aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-02-26 20:16:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-02-26 20:16:20 -0500
commit2b8c70b2174402ca3dec13310ce56597233392d7 (patch)
tree0aed464521a2a671cbb7b4302b55fe72abc95d3d /drivers
parent29e1fa3565a7951cc415c634eb2b78dbdbee151d (diff)
parent3621263a4d9679726b7bc1e2546c1c03941a59b4 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (362 commits) V4L-DVB: cx88-dvb: remove extra attribution for core V4L/DVB: v4l: soc_camera: fix bound checking of mbus_fmt[] index V4L/DVB: Add support for SMT7020 to cx88 V4L/DVB: radio-si470x: Use UTF-8 encoding on a comment V4L/DVB: MAINTAINERS: Telegent tlg2300 section fix V4L/DVB: gspca_stv06xx: Add support for camera button V4L/DVB: gspca_ov519: add support for the button on ov511 based cams V4L/DVB: gspca_ov519: Add support for the button on ov518 based cams V4L/DVB: gspca_ov519: add support for the button on ov519 based cams V4L/DVB: gspca_main: Fix a compile error when CONFIG_INPUT is not set V4L/DVB: gspca_main: some input error handling fixes V4L/DVB: gspca_main: Allow use of input device creation code for non int. inputs V4L/DVB: gspca_pac7302: much improved exposure control V4L/DVB: gspca_sonixb: Make sonixb driver handle pas106 and pas202 cameras V4L/DVB: gspca_sonixb: pas106: fixup bright ctrl and add gain and exposure ctrls V4L/DVB: Documentation: gspca.txt: update known mr97310a cams V4L/DVB: gspca_mr97310a: add support for the Sakar 1638x CyberPix V4L/DVB: gscpa_sonixb: limit ov7630 max framerate at 640x480 V4L/DVB: gspca_sonixb: pas202: fixup brightness ctrl and add gain and exposure ctrls V4L/DVB: gscpa_sonixb: Differentiate between sensors with a coarse and fine expo ctrl ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/IR/Makefile2
-rw-r--r--drivers/media/IR/ir-functions.c2
-rw-r--r--drivers/media/IR/ir-keymaps.c99
-rw-r--r--drivers/media/IR/ir-keytable.c61
-rw-r--r--drivers/media/IR/ir-sysfs.c211
-rw-r--r--drivers/media/common/saa7146_fops.c11
-rw-r--r--drivers/media/common/tuners/tuner-types.c21
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c79
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile3
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c21
-rw-r--r--drivers/media/dvb/bt8xx/dst.c12
-rw-r--r--drivers/media/dvb/dm1105/Kconfig1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c505
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c12
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c351
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h1
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.c1151
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.h14
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c3
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c197
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c160
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h9
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c1
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c95
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c141
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.h2
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c2
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c19
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c514
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c1
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c2
-rw-r--r--drivers/media/dvb/firewire/firedtv.h6
-rw-r--r--drivers/media/dvb/frontends/af9013.h1
-rw-r--r--drivers/media/dvb/frontends/atbm8830.c16
-rw-r--r--drivers/media/dvb/frontends/dib0090.c2
-rw-r--r--drivers/media/dvb/frontends/dib8000.c2
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c2
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c3
-rw-r--r--drivers/media/dvb/frontends/si21xx.c38
-rw-r--r--drivers/media/dvb/frontends/stv0900.h2
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c109
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h11
-rw-r--r--drivers/media/dvb/frontends/stv0900_reg.h6
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c54
-rw-r--r--drivers/media/dvb/frontends/stv090x.c486
-rw-r--r--drivers/media/dvb/frontends/stv090x.h13
-rw-r--r--drivers/media/dvb/frontends/stv090x_priv.h17
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c188
-rw-r--r--drivers/media/dvb/frontends/stv6110x.h1
-rw-r--r--drivers/media/dvb/frontends/stv6110x_priv.h1
-rw-r--r--drivers/media/dvb/frontends/tda665x.c2
-rw-r--r--drivers/media/dvb/frontends/tda8261.c2
-rw-r--r--drivers/media/dvb/frontends/zl10036.c2
-rw-r--r--drivers/media/dvb/frontends/zl10039.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_hif.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_input.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_pci.c5
-rw-r--r--drivers/media/dvb/ngene/Kconfig9
-rw-r--r--drivers/media/dvb/ngene/Makefile11
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c2024
-rw-r--r--drivers/media/dvb/ngene/ngene.h859
-rw-r--r--drivers/media/dvb/siano/sms-cards.c1
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c7
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h77
-rw-r--r--drivers/media/dvb/siano/smsdvb.c318
-rw-r--r--drivers/media/dvb/siano/smsir.c6
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c14
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c2
-rw-r--r--drivers/media/dvb/ttpci/budget.c4
-rw-r--r--drivers/media/radio/Kconfig23
-rw-r--r--drivers/media/radio/Makefile2
-rw-r--r--drivers/media/radio/radio-timb.c244
-rw-r--r--drivers/media/radio/saa7706h.c451
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c2
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c8
-rw-r--r--drivers/media/video/Kconfig36
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/bt819.c10
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c9
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c4
-rw-r--r--drivers/media/video/cafe_ccic.c6
-rw-r--r--drivers/media/video/cpia.c3
-rw-r--r--drivers/media/video/cx18/Kconfig11
-rw-r--r--drivers/media/video/cx18/Makefile2
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c293
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.c175
-rw-r--r--drivers/media/video/cx18/cx18-alsa-mixer.h23
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c354
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.h27
-rw-r--r--drivers/media/video/cx18/cx18-alsa.h75
-rw-r--r--drivers/media/video/cx18/cx18-cards.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c70
-rw-r--r--drivers/media/video/cx18/cx18-driver.h50
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c22
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c205
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h3
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c135
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c45
-rw-r--r--drivers/media/video/cx18/cx18-queue.c3
-rw-r--r--drivers/media/video/cx18/cx18-streams.c72
-rw-r--r--drivers/media/video/cx18/cx18-streams.h10
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h3
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c8
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c4
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c32
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c17
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c13
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c54
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c10
-rw-r--r--drivers/media/video/cx88/cx88-cards.c23
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c214
-rw-r--r--drivers/media/video/cx88/cx88-input.c4
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c3
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/dabusb.c2
-rw-r--r--drivers/media/video/davinci/Makefile1
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c410
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c361
-rw-r--r--drivers/media/video/davinci/isif.c1172
-rw-r--r--drivers/media/video/davinci/isif_regs.h269
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c131
-rw-r--r--drivers/media/video/davinci/vpss.c289
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c80
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c19
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c113
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h4
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c17
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c58
-rw-r--r--drivers/media/video/em28xx/em28xx.h6
-rw-r--r--drivers/media/video/et61x251/Kconfig6
-rw-r--r--drivers/media/video/gspca/Kconfig46
-rw-r--r--drivers/media/video/gspca/Makefile8
-rw-r--r--drivers/media/video/gspca/benq.c322
-rw-r--r--drivers/media/video/gspca/coarse_expo_autogain.h116
-rw-r--r--drivers/media/video/gspca/conex.c4
-rw-r--r--drivers/media/video/gspca/cpia1.c2022
-rw-r--r--drivers/media/video/gspca/etoms.c4
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c10
-rw-r--r--drivers/media/video/gspca/gspca.c259
-rw-r--r--drivers/media/video/gspca/gspca.h30
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c2
-rw-r--r--drivers/media/video/gspca/mars.c2
-rw-r--r--drivers/media/video/gspca/mr97310a.c226
-rw-r--r--drivers/media/video/gspca/ov519.c151
-rw-r--r--drivers/media/video/gspca/ov534.c1253
-rw-r--r--drivers/media/video/gspca/ov534_9.c1477
-rw-r--r--drivers/media/video/gspca/pac207.c25
-rw-r--r--drivers/media/video/gspca/pac7302.c411
-rw-r--r--drivers/media/video/gspca/pac7311.c251
-rw-r--r--drivers/media/video/gspca/pac_common.h9
-rw-r--r--drivers/media/video/gspca/sn9c2028.c757
-rw-r--r--drivers/media/video/gspca/sn9c2028.h51
-rw-r--r--drivers/media/video/gspca/sn9c20x.c33
-rw-r--r--drivers/media/video/gspca/sonixb.c451
-rw-r--r--drivers/media/video/gspca/sonixj.c341
-rw-r--r--drivers/media/video/gspca/spca500.c4
-rw-r--r--drivers/media/video/gspca/spca501.c2
-rw-r--r--drivers/media/video/gspca/spca505.c2
-rw-r--r--drivers/media/video/gspca/spca506.c4
-rw-r--r--drivers/media/video/gspca/spca508.c2
-rw-r--r--drivers/media/video/gspca/spca561.c4
-rw-r--r--drivers/media/video/gspca/sq905c.c45
-rw-r--r--drivers/media/video/gspca/stk014.c2
-rw-r--r--drivers/media/video/gspca/stv0680.c16
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c32
-rw-r--r--drivers/media/video/gspca/sunplus.c186
-rw-r--r--drivers/media/video/gspca/t613.c51
-rw-r--r--drivers/media/video/gspca/tv8532.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c694
-rw-r--r--drivers/media/video/gspca/zc3xx.c679
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c5
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c5
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h1
-rw-r--r--drivers/media/video/hexium_gemini.c9
-rw-r--r--drivers/media/video/hexium_orion.c4
-rw-r--r--drivers/media/video/ir-kbd-i2c.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c48
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h3
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c1
-rw-r--r--drivers/media/video/mt9v022.c17
-rw-r--r--drivers/media/video/mxb.c10
-rw-r--r--drivers/media/video/ov772x.c22
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c53
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h1
-rw-r--r--drivers/media/video/pxa_camera.c10
-rw-r--r--drivers/media/video/rj54n1cb0c.c12
-rw-r--r--drivers/media/video/saa7115.c27
-rw-r--r--drivers/media/video/saa7127.c47
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c52
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c7
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c18
-rw-r--r--drivers/media/video/sn9c102/Kconfig5
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h6
-rw-r--r--drivers/media/video/soc_camera.c36
-rw-r--r--drivers/media/video/soc_mediabus.c48
-rw-r--r--drivers/media/video/tlg2300/Kconfig16
-rw-r--r--drivers/media/video/tlg2300/Makefile9
-rw-r--r--drivers/media/video/tlg2300/pd-alsa.c332
-rw-r--r--drivers/media/video/tlg2300/pd-common.h282
-rw-r--r--drivers/media/video/tlg2300/pd-dvb.c593
-rw-r--r--drivers/media/video/tlg2300/pd-main.c539
-rw-r--r--drivers/media/video/tlg2300/pd-radio.c420
-rw-r--r--drivers/media/video/tlg2300/pd-video.c1667
-rw-r--r--drivers/media/video/tlg2300/vendorcmds.h243
-rw-r--r--drivers/media/video/tuner-core.c1
-rw-r--r--drivers/media/video/tveeprom.c5
-rw-r--r--drivers/media/video/tvp7002.c1187
-rw-r--r--drivers/media/video/tvp7002_reg.h150
-rw-r--r--drivers/media/video/tw9910.c8
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c242
-rw-r--r--drivers/media/video/uvc/uvc_driver.c74
-rw-r--r--drivers/media/video/uvc/uvc_queue.c1
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c4
-rw-r--r--drivers/media/video/uvc/uvc_video.c10
-rw-r--r--drivers/media/video/uvc/uvcvideo.h19
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c5
-rw-r--r--drivers/media/video/videobuf-dma-sg.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/vivi.c2
-rw-r--r--drivers/media/video/zc0301/Kconfig6
-rw-r--r--drivers/media/video/zoran/zoran_device.c6
-rw-r--r--drivers/media/video/zoran/zoran_driver.c4
-rw-r--r--drivers/media/video/zr364xx.c37
-rw-r--r--drivers/mfd/Kconfig10
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/timberdale.c727
-rw-r--r--drivers/mfd/timberdale.h130
-rw-r--r--drivers/staging/go7007/s2250-board.c2
257 files changed, 26403 insertions, 4585 deletions
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index df5ddb4bbbf7..171890e7a41d 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -1,5 +1,5 @@
1ir-common-objs := ir-functions.o ir-keymaps.o 1ir-common-objs := ir-functions.o ir-keymaps.o
2ir-core-objs := ir-keytable.o 2ir-core-objs := ir-keytable.o ir-sysfs.o
3 3
4obj-$(CONFIG_IR_CORE) += ir-core.o 4obj-$(CONFIG_IR_CORE) += ir-core.o
5obj-$(CONFIG_VIDEO_IR) += ir-common.o 5obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
index 776a136616d6..ab06919ad5fc 100644
--- a/drivers/media/IR/ir-functions.c
+++ b/drivers/media/IR/ir-functions.c
@@ -52,7 +52,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
52/* -------------------------------------------------------------------------- */ 52/* -------------------------------------------------------------------------- */
53 53
54int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 54int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
55 int ir_type) 55 const u64 ir_type)
56{ 56{
57 ir->ir_type = ir_type; 57 ir->ir_type = ir_type;
58 58
diff --git a/drivers/media/IR/ir-keymaps.c b/drivers/media/IR/ir-keymaps.c
index 9bbe6b1e9871..0efdefe75f32 100644
--- a/drivers/media/IR/ir-keymaps.c
+++ b/drivers/media/IR/ir-keymaps.c
@@ -3393,3 +3393,102 @@ struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
3393}; 3393};
3394EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table); 3394EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
3395 3395
3396
3397/* Leadtek Winfast TV USB II Deluxe remote
3398 Magnus Alm <magnus.alm@gmail.com>
3399 */
3400static struct ir_scancode ir_codes_winfast_usbii_deluxe[] = {
3401 { 0x62, KEY_0},
3402 { 0x75, KEY_1},
3403 { 0x76, KEY_2},
3404 { 0x77, KEY_3},
3405 { 0x79, KEY_4},
3406 { 0x7a, KEY_5},
3407 { 0x7b, KEY_6},
3408 { 0x7d, KEY_7},
3409 { 0x7e, KEY_8},
3410 { 0x7f, KEY_9},
3411
3412 { 0x38, KEY_CAMERA}, /* SNAPSHOT */
3413 { 0x37, KEY_RECORD}, /* RECORD */
3414 { 0x35, KEY_TIME}, /* TIMESHIFT */
3415
3416 { 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */
3417 { 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3418 { 0x64, KEY_MUTE}, /* MUTE */
3419
3420 { 0x21, KEY_CHANNEL}, /* SURF */
3421 { 0x7c, KEY_CHANNELUP}, /* CHANNELUP */
3422 { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3423 { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
3424
3425 { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
3426
3427 { 0x70, KEY_POWER2}, /* TV ON/OFF */
3428
3429 { 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */
3430 { 0x3a, KEY_NEW}, /* PIP */
3431 { 0x73, KEY_ZOOM}, /* FULLSECREEN */
3432
3433 { 0x66, KEY_INFO}, /* OSD (DISPLAY) */
3434
3435 { 0x31, KEY_DOT}, /* '.' */
3436 { 0x63, KEY_ENTER}, /* ENTER */
3437
3438};
3439struct ir_scancode_table ir_codes_winfast_usbii_deluxe_table = {
3440 .scan = ir_codes_winfast_usbii_deluxe,
3441 .size = ARRAY_SIZE(ir_codes_winfast_usbii_deluxe),
3442};
3443EXPORT_SYMBOL_GPL(ir_codes_winfast_usbii_deluxe_table);
3444
3445/* Kworld 315U
3446 */
3447static struct ir_scancode ir_codes_kworld_315u[] = {
3448 { 0x6143, KEY_POWER },
3449 { 0x6101, KEY_TUNER }, /* source */
3450 { 0x610b, KEY_ZOOM },
3451 { 0x6103, KEY_POWER2 }, /* shutdown */
3452
3453 { 0x6104, KEY_1 },
3454 { 0x6108, KEY_2 },
3455 { 0x6102, KEY_3 },
3456 { 0x6109, KEY_CHANNELUP },
3457
3458 { 0x610f, KEY_4 },
3459 { 0x6105, KEY_5 },
3460 { 0x6106, KEY_6 },
3461 { 0x6107, KEY_CHANNELDOWN },
3462
3463 { 0x610c, KEY_7 },
3464 { 0x610d, KEY_8 },
3465 { 0x610a, KEY_9 },
3466 { 0x610e, KEY_VOLUMEUP },
3467
3468 { 0x6110, KEY_LAST },
3469 { 0x6111, KEY_0 },
3470 { 0x6112, KEY_ENTER },
3471 { 0x6113, KEY_VOLUMEDOWN },
3472
3473 { 0x6114, KEY_RECORD },
3474 { 0x6115, KEY_STOP },
3475 { 0x6116, KEY_PLAY },
3476 { 0x6117, KEY_MUTE },
3477
3478 { 0x6118, KEY_UP },
3479 { 0x6119, KEY_DOWN },
3480 { 0x611a, KEY_LEFT },
3481 { 0x611b, KEY_RIGHT },
3482
3483 { 0x611c, KEY_RED },
3484 { 0x611d, KEY_GREEN },
3485 { 0x611e, KEY_YELLOW },
3486 { 0x611f, KEY_BLUE },
3487};
3488
3489struct ir_scancode_table ir_codes_kworld_315u_table = {
3490 .scan = ir_codes_kworld_315u,
3491 .size = ARRAY_SIZE(ir_codes_kworld_315u),
3492 .ir_type = IR_TYPE_NEC,
3493};
3494EXPORT_SYMBOL_GPL(ir_codes_kworld_315u_table);
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index b521ed9d6e2e..0903f539bf68 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -65,7 +65,7 @@ exit:
65 * In order to reduce the quantity of table resizes, it has a minimum 65 * In order to reduce the quantity of table resizes, it has a minimum
66 * table size of IR_TAB_MIN_SIZE. 66 * table size of IR_TAB_MIN_SIZE.
67 */ 67 */
68int ir_roundup_tablesize(int n_elems) 68static int ir_roundup_tablesize(int n_elems)
69{ 69{
70 size_t size; 70 size_t size;
71 71
@@ -81,7 +81,6 @@ int ir_roundup_tablesize(int n_elems)
81 81
82 return n_elems; 82 return n_elems;
83} 83}
84EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
85 84
86/** 85/**
87 * ir_copy_table() - copies a keytable, discarding the unused entries 86 * ir_copy_table() - copies a keytable, discarding the unused entries
@@ -89,9 +88,11 @@ EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
89 * @origin: origin table 88 * @origin: origin table
90 * 89 *
91 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED 90 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
91 * Also copies table size and table protocol.
92 * NOTE: It shouldn't copy the lock field
92 */ 93 */
93 94
94int ir_copy_table(struct ir_scancode_table *destin, 95static int ir_copy_table(struct ir_scancode_table *destin,
95 const struct ir_scancode_table *origin) 96 const struct ir_scancode_table *origin)
96{ 97{
97 int i, j = 0; 98 int i, j = 0;
@@ -105,12 +106,12 @@ int ir_copy_table(struct ir_scancode_table *destin,
105 j++; 106 j++;
106 } 107 }
107 destin->size = j; 108 destin->size = j;
109 destin->ir_type = origin->ir_type;
108 110
109 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); 111 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
110 112
111 return 0; 113 return 0;
112} 114}
113EXPORT_SYMBOL_GPL(ir_copy_table);
114 115
115/** 116/**
116 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table 117 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
@@ -184,18 +185,14 @@ static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
184 int newsize = rc_tab->size - 1; 185 int newsize = rc_tab->size - 1;
185 int resize = ir_is_resize_needed(rc_tab, newsize); 186 int resize = ir_is_resize_needed(rc_tab, newsize);
186 struct ir_scancode *oldkeymap = rc_tab->scan; 187 struct ir_scancode *oldkeymap = rc_tab->scan;
187 struct ir_scancode *newkeymap; 188 struct ir_scancode *newkeymap = NULL;
188 189
189 if (resize) { 190 if (resize)
190 newkeymap = kzalloc(ir_roundup_tablesize(newsize) * 191 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
191 sizeof(*newkeymap), GFP_ATOMIC); 192 sizeof(*newkeymap), GFP_ATOMIC);
192 193
193 /* There's no memory for resize. Keep the old table */ 194 /* There's no memory for resize. Keep the old table */
194 if (!newkeymap) 195 if (!resize || !newkeymap) {
195 resize = 0;
196 }
197
198 if (!resize) {
199 newkeymap = oldkeymap; 196 newkeymap = oldkeymap;
200 197
201 /* We'll modify the live table. Lock it */ 198 /* We'll modify the live table. Lock it */
@@ -399,12 +396,14 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
399 * @input_dev: the struct input_dev descriptor of the device 396 * @input_dev: the struct input_dev descriptor of the device
400 * @rc_tab: the struct ir_scancode_table table of scancode/keymap 397 * @rc_tab: the struct ir_scancode_table table of scancode/keymap
401 * 398 *
402 * This routine is used to initialize the input infrastructure to work with 399 * This routine is used to initialize the input infrastructure
403 * an IR. 400 * to work with an IR.
404 * It should be called before registering the IR device. 401 * It will register the input/evdev interface for the device and
402 * register the syfs code for IR class
405 */ 403 */
406int ir_input_register(struct input_dev *input_dev, 404int ir_input_register(struct input_dev *input_dev,
407 struct ir_scancode_table *rc_tab) 405 const struct ir_scancode_table *rc_tab,
406 const struct ir_dev_props *props)
408{ 407{
409 struct ir_input_dev *ir_dev; 408 struct ir_input_dev *ir_dev;
410 struct ir_scancode *keymap = rc_tab->scan; 409 struct ir_scancode *keymap = rc_tab->scan;
@@ -417,19 +416,22 @@ int ir_input_register(struct input_dev *input_dev,
417 if (!ir_dev) 416 if (!ir_dev)
418 return -ENOMEM; 417 return -ENOMEM;
419 418
420 spin_lock_init(&rc_tab->lock); 419 spin_lock_init(&ir_dev->rc_tab.lock);
421 420
422 ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size); 421 ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
423 ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size * 422 ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
424 sizeof(struct ir_scancode), GFP_KERNEL); 423 sizeof(struct ir_scancode), GFP_KERNEL);
425 if (!ir_dev->rc_tab.scan) 424 if (!ir_dev->rc_tab.scan) {
425 kfree(ir_dev);
426 return -ENOMEM; 426 return -ENOMEM;
427 }
427 428
428 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", 429 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
429 ir_dev->rc_tab.size, 430 ir_dev->rc_tab.size,
430 ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan)); 431 ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
431 432
432 ir_copy_table(&ir_dev->rc_tab, rc_tab); 433 ir_copy_table(&ir_dev->rc_tab, rc_tab);
434 ir_dev->props = props;
433 435
434 /* set the bits for the keys */ 436 /* set the bits for the keys */
435 IR_dprintk(1, "key map size: %d\n", rc_tab->size); 437 IR_dprintk(1, "key map size: %d\n", rc_tab->size);
@@ -447,16 +449,31 @@ int ir_input_register(struct input_dev *input_dev,
447 input_set_drvdata(input_dev, ir_dev); 449 input_set_drvdata(input_dev, ir_dev);
448 450
449 rc = input_register_device(input_dev); 451 rc = input_register_device(input_dev);
452 if (rc < 0)
453 goto err;
454
455 rc = ir_register_class(input_dev);
450 if (rc < 0) { 456 if (rc < 0) {
451 kfree(rc_tab->scan); 457 input_unregister_device(input_dev);
452 kfree(ir_dev); 458 goto err;
453 input_set_drvdata(input_dev, NULL);
454 } 459 }
455 460
461 return 0;
462
463err:
464 kfree(rc_tab->scan);
465 kfree(ir_dev);
466 input_set_drvdata(input_dev, NULL);
456 return rc; 467 return rc;
457} 468}
458EXPORT_SYMBOL_GPL(ir_input_register); 469EXPORT_SYMBOL_GPL(ir_input_register);
459 470
471/**
472 * ir_input_unregister() - unregisters IR and frees resources
473 * @input_dev: the struct input_dev descriptor of the device
474
475 * This routine is used to free memory and de-register interfaces.
476 */
460void ir_input_unregister(struct input_dev *dev) 477void ir_input_unregister(struct input_dev *dev)
461{ 478{
462 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 479 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -472,6 +489,8 @@ void ir_input_unregister(struct input_dev *dev)
472 kfree(rc_tab->scan); 489 kfree(rc_tab->scan);
473 rc_tab->scan = NULL; 490 rc_tab->scan = NULL;
474 491
492 ir_unregister_class(dev);
493
475 kfree(ir_dev); 494 kfree(ir_dev);
476 input_unregister_device(dev); 495 input_unregister_device(dev);
477} 496}
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
new file mode 100644
index 000000000000..bf5fbcd84238
--- /dev/null
+++ b/drivers/media/IR/ir-sysfs.c
@@ -0,0 +1,211 @@
1/* ir-register.c - handle IR scancode->keycode tables
2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/input.h>
16#include <linux/device.h>
17#include <media/ir-core.h>
18
19#define IRRCV_NUM_DEVICES 256
20
21/* bit array to represent IR sysfs device number */
22static unsigned long ir_core_dev_number;
23
24/* class for /sys/class/irrcv */
25static struct class *ir_input_class;
26
27/**
28 * show_protocol() - shows the current IR protocol
29 * @d: the device descriptor
30 * @mattr: the device attribute struct (unused)
31 * @buf: a pointer to the output buffer
32 *
33 * This routine is a callback routine for input read the IR protocol type.
34 * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol.
35 * It returns the protocol name, as understood by the driver.
36 */
37static ssize_t show_protocol(struct device *d,
38 struct device_attribute *mattr, char *buf)
39{
40 char *s;
41 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
42 u64 ir_type = ir_dev->rc_tab.ir_type;
43
44 IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
45
46 /* FIXME: doesn't support multiple protocols at the same time */
47 if (ir_type == IR_TYPE_UNKNOWN)
48 s = "Unknown";
49 else if (ir_type == IR_TYPE_RC5)
50 s = "RC-5";
51 else if (ir_type == IR_TYPE_PD)
52 s = "Pulse/distance";
53 else if (ir_type == IR_TYPE_NEC)
54 s = "NEC";
55 else
56 s = "Other";
57
58 return sprintf(buf, "%s\n", s);
59}
60
61/**
62 * store_protocol() - shows the current IR protocol
63 * @d: the device descriptor
64 * @mattr: the device attribute struct (unused)
65 * @buf: a pointer to the input buffer
66 * @len: length of the input buffer
67 *
68 * This routine is a callback routine for changing the IR protocol type.
69 * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol.
70 * It changes the IR the protocol name, if the IR type is recognized
71 * by the driver.
72 * If an unknown protocol name is used, returns -EINVAL.
73 */
74static ssize_t store_protocol(struct device *d,
75 struct device_attribute *mattr,
76 const char *data,
77 size_t len)
78{
79 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
80 u64 ir_type = IR_TYPE_UNKNOWN;
81 int rc = -EINVAL;
82 unsigned long flags;
83 char *buf;
84
85 buf = strsep((char **) &data, "\n");
86
87 if (!strcasecmp(buf, "rc-5"))
88 ir_type = IR_TYPE_RC5;
89 else if (!strcasecmp(buf, "pd"))
90 ir_type = IR_TYPE_PD;
91 else if (!strcasecmp(buf, "nec"))
92 ir_type = IR_TYPE_NEC;
93
94 if (ir_type == IR_TYPE_UNKNOWN) {
95 IR_dprintk(1, "Error setting protocol to %lld\n",
96 (long long)ir_type);
97 return -EINVAL;
98 }
99
100 if (ir_dev->props && ir_dev->props->change_protocol)
101 rc = ir_dev->props->change_protocol(ir_dev->props->priv,
102 ir_type);
103
104 if (rc < 0) {
105 IR_dprintk(1, "Error setting protocol to %lld\n",
106 (long long)ir_type);
107 return -EINVAL;
108 }
109
110 spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
111 ir_dev->rc_tab.ir_type = ir_type;
112 spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
113
114 IR_dprintk(1, "Current protocol is %lld\n",
115 (long long)ir_type);
116
117 return len;
118}
119
120/*
121 * Static device attribute struct with the sysfs attributes for IR's
122 */
123static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR,
124 show_protocol, store_protocol);
125
126static struct attribute *ir_dev_attrs[] = {
127 &dev_attr_current_protocol.attr,
128 NULL,
129};
130
131/**
132 * ir_register_class() - creates the sysfs for /sys/class/irrcv/irrcv?
133 * @input_dev: the struct input_dev descriptor of the device
134 *
135 * This routine is used to register the syfs code for IR class
136 */
137int ir_register_class(struct input_dev *input_dev)
138{
139 int rc;
140 struct kobject *kobj;
141
142 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
143 int devno = find_first_zero_bit(&ir_core_dev_number,
144 IRRCV_NUM_DEVICES);
145
146 if (unlikely(devno < 0))
147 return devno;
148
149 ir_dev->attr.attrs = ir_dev_attrs;
150 ir_dev->class_dev = device_create(ir_input_class, NULL,
151 input_dev->dev.devt, ir_dev,
152 "irrcv%d", devno);
153 kobj = &ir_dev->class_dev->kobj;
154
155 printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj));
156 rc = sysfs_create_group(kobj, &ir_dev->attr);
157 if (unlikely(rc < 0)) {
158 device_destroy(ir_input_class, input_dev->dev.devt);
159 return -ENOMEM;
160 }
161
162 ir_dev->devno = devno;
163 set_bit(devno, &ir_core_dev_number);
164
165 return 0;
166};
167
168/**
169 * ir_unregister_class() - removes the sysfs for sysfs for
170 * /sys/class/irrcv/irrcv?
171 * @input_dev: the struct input_dev descriptor of the device
172 *
173 * This routine is used to unregister the syfs code for IR class
174 */
175void ir_unregister_class(struct input_dev *input_dev)
176{
177 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
178 struct kobject *kobj;
179
180 clear_bit(ir_dev->devno, &ir_core_dev_number);
181
182 kobj = &ir_dev->class_dev->kobj;
183
184 sysfs_remove_group(kobj, &ir_dev->attr);
185 device_destroy(ir_input_class, input_dev->dev.devt);
186
187 kfree(ir_dev->attr.name);
188}
189
190/*
191 * Init/exit code for the module. Basically, creates/removes /sys/class/irrcv
192 */
193
194static int __init ir_core_init(void)
195{
196 ir_input_class = class_create(THIS_MODULE, "irrcv");
197 if (IS_ERR(ir_input_class)) {
198 printk(KERN_ERR "ir_core: unable to register irrcv class\n");
199 return PTR_ERR(ir_input_class);
200 }
201
202 return 0;
203}
204
205static void __exit ir_core_exit(void)
206{
207 class_destroy(ir_input_class);
208}
209
210module_init(ir_core_init);
211module_exit(ir_core_exit);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 7364b9642d00..fd8e1f45be36 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -423,14 +423,15 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
423 } 423 }
424} 424}
425 425
426int saa7146_vv_devinit(struct saa7146_dev *dev)
427{
428 return v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
429}
430EXPORT_SYMBOL_GPL(saa7146_vv_devinit);
431
426int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) 432int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
427{ 433{
428 struct saa7146_vv *vv; 434 struct saa7146_vv *vv;
429 int err;
430
431 err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
432 if (err)
433 return err;
434 435
435 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); 436 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
436 if (vv == NULL) { 437 if (vv == NULL) {
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 2b876f3988c1..d9aaaca620c9 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1337,6 +1337,22 @@ static struct tuner_params tuner_philips_cu1216l_params[] = {
1337 }, 1337 },
1338}; 1338};
1339 1339
1340/* ---------------------- TUNER_SONY_BTF_PXN01Z ------------------------ */
1341
1342static struct tuner_range tuner_sony_btf_pxn01z_ranges[] = {
1343 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
1344 { 16 * 367.25 /*MHz*/, 0x8e, 0x02, },
1345 { 16 * 999.99 , 0x8e, 0x04, },
1346};
1347
1348static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
1349 {
1350 .type = TUNER_PARAM_TYPE_NTSC,
1351 .ranges = tuner_sony_btf_pxn01z_ranges,
1352 .count = ARRAY_SIZE(tuner_sony_btf_pxn01z_ranges),
1353 },
1354};
1355
1340/* --------------------------------------------------------------------- */ 1356/* --------------------------------------------------------------------- */
1341 1357
1342struct tunertype tuners[] = { 1358struct tunertype tuners[] = {
@@ -1805,6 +1821,11 @@ struct tunertype tuners[] = {
1805 .name = "NXP TDA18271", 1821 .name = "NXP TDA18271",
1806 /* see tda18271-fe.c for details */ 1822 /* see tda18271-fe.c for details */
1807 }, 1823 },
1824 [TUNER_SONY_BTF_PXN01Z] = {
1825 .name = "Sony BTF-Pxn01Z",
1826 .params = tuner_sony_btf_pxn01z_params,
1827 .count = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
1828 },
1808}; 1829};
1809EXPORT_SYMBOL(tuners); 1830EXPORT_SYMBOL(tuners);
1810 1831
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index f270e605da83..be51c294b375 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -917,30 +917,68 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
917 * that xc2028 will be in a safe state. 917 * that xc2028 will be in a safe state.
918 * Maybe this might also be needed for DTV. 918 * Maybe this might also be needed for DTV.
919 */ 919 */
920 if (new_mode == T_ANALOG_TV) 920 if (new_mode == T_ANALOG_TV) {
921 rc = send_seq(priv, {0x00, 0x00}); 921 rc = send_seq(priv, {0x00, 0x00});
922 922
923 /* 923 /* Analog modes require offset = 0 */
924 * Digital modes require an offset to adjust to the 924 } else {
925 * proper frequency. 925 /*
926 * Analog modes require offset = 0 926 * Digital modes require an offset to adjust to the
927 */ 927 * proper frequency. The offset depends on what
928 if (new_mode == T_DIGITAL_TV) { 928 * firmware version is used.
929 /* Sets the offset according with firmware */ 929 */
930
931 /*
932 * Adjust to the center frequency. This is calculated by the
933 * formula: offset = 1.25MHz - BW/2
934 * For DTV 7/8, the firmware uses BW = 8000, so it needs a
935 * further adjustment to get the frequency center on VHF
936 */
930 if (priv->cur_fw.type & DTV6) 937 if (priv->cur_fw.type & DTV6)
931 offset = 1750000; 938 offset = 1750000;
932 else if (priv->cur_fw.type & DTV7) 939 else if (priv->cur_fw.type & DTV7)
933 offset = 2250000; 940 offset = 2250000;
934 else /* DTV8 or DTV78 */ 941 else /* DTV8 or DTV78 */
935 offset = 2750000; 942 offset = 2750000;
943 if ((priv->cur_fw.type & DTV78) && freq < 470000000)
944 offset -= 500000;
936 945
937 /* 946 /*
938 * We must adjust the offset by 500kHz when 947 * xc3028 additional "magic"
939 * tuning a 7MHz VHF channel with DTV78 firmware 948 * Depending on the firmware version, it needs some adjustments
940 * (used in Australia, Italy and Germany) 949 * to properly centralize the frequency. This seems to be
950 * needed to compensate the SCODE table adjustments made by
951 * newer firmwares
941 */ 952 */
942 if ((priv->cur_fw.type & DTV78) && freq < 470000000) 953
943 offset -= 500000; 954#if 1
955 /*
956 * The proper adjustment would be to do it at s-code table.
957 * However, this didn't work, as reported by
958 * Robert Lowery <rglowery@exemail.com.au>
959 */
960
961 if (priv->cur_fw.type & DTV7)
962 offset += 500000;
963
964#else
965 /*
966 * Still need tests for XC3028L (firmware 3.2 or upper)
967 * So, for now, let's just comment the per-firmware
968 * version of this change. Reports with xc3028l working
969 * with and without the lines bellow are welcome
970 */
971
972 if (priv->firm_version < 0x0302) {
973 if (priv->cur_fw.type & DTV7)
974 offset += 500000;
975 } else {
976 if (priv->cur_fw.type & DTV7)
977 offset -= 300000;
978 else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
979 offset += 200000;
980 }
981#endif
944 } 982 }
945 983
946 div = (freq - offset + DIV / 2) / DIV; 984 div = (freq - offset + DIV / 2) / DIV;
@@ -1097,17 +1135,24 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1097 1135
1098 /* All S-code tables need a 200kHz shift */ 1136 /* All S-code tables need a 200kHz shift */
1099 if (priv->ctrl.demod) { 1137 if (priv->ctrl.demod) {
1100 demod = priv->ctrl.demod + 200; 1138 demod = priv->ctrl.demod;
1139
1140 /*
1141 * Newer firmwares require a 200 kHz offset only for ATSC
1142 */
1143 if (type == ATSC || priv->firm_version < 0x0302)
1144 demod += 200;
1101 /* 1145 /*
1102 * The DTV7 S-code table needs a 700 kHz shift. 1146 * The DTV7 S-code table needs a 700 kHz shift.
1103 * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
1104 * 1147 *
1105 * DTV7 is only used in Australia. Germany or Italy may also 1148 * DTV7 is only used in Australia. Germany or Italy may also
1106 * use this firmware after initialization, but a tune to a UHF 1149 * use this firmware after initialization, but a tune to a UHF
1107 * channel should then cause DTV78 to be used. 1150 * channel should then cause DTV78 to be used.
1151 *
1152 * Unfortunately, on real-field tests, the s-code offset
1153 * didn't work as expected, as reported by
1154 * Robert Lowery <rglowery@exemail.com.au>
1108 */ 1155 */
1109 if (type & DTV7)
1110 demod += 500;
1111 } 1156 }
1112 1157
1113 return generic_set_freq(fe, p->frequency, 1158 return generic_set_freq(fe, p->frequency,
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index cf8f65f309da..161ccfd471cb 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -76,6 +76,10 @@ comment "Supported Mantis Adapters"
76 depends on DVB_CORE && PCI && I2C 76 depends on DVB_CORE && PCI && I2C
77 source "drivers/media/dvb/mantis/Kconfig" 77 source "drivers/media/dvb/mantis/Kconfig"
78 78
79comment "Supported nGene Adapters"
80 depends on DVB_CORE && PCI && I2C
81 source "drivers/media/dvb/ngene/Kconfig"
82
79comment "Supported DVB Frontends" 83comment "Supported DVB Frontends"
80 depends on DVB_CORE 84 depends on DVB_CORE
81source "drivers/media/dvb/frontends/Kconfig" 85source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index c12922c3659b..a1a08758a6f2 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -14,6 +14,7 @@ obj-y := dvb-core/ \
14 siano/ \ 14 siano/ \
15 dm1105/ \ 15 dm1105/ \
16 pt1/ \ 16 pt1/ \
17 mantis/ 17 mantis/ \
18 ngene/
18 19
19obj-$(CONFIG_DVB_FIREDTV) += firewire/ 20obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index a24c125331f0..99d62094f908 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -576,43 +576,30 @@ static struct pci_driver bt878_pci_driver = {
576 .remove = __devexit_p(bt878_remove), 576 .remove = __devexit_p(bt878_remove),
577}; 577};
578 578
579static int bt878_pci_driver_registered;
580
581/*******************************/ 579/*******************************/
582/* Module management functions */ 580/* Module management functions */
583/*******************************/ 581/*******************************/
584 582
585static int bt878_init_module(void) 583static int __init bt878_init_module(void)
586{ 584{
587 bt878_num = 0; 585 bt878_num = 0;
588 bt878_pci_driver_registered = 0;
589 586
590 printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", 587 printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
591 (BT878_VERSION_CODE >> 16) & 0xff, 588 (BT878_VERSION_CODE >> 16) & 0xff,
592 (BT878_VERSION_CODE >> 8) & 0xff, 589 (BT878_VERSION_CODE >> 8) & 0xff,
593 BT878_VERSION_CODE & 0xff); 590 BT878_VERSION_CODE & 0xff);
594/* 591
595 bt878_check_chipset();
596*/
597 /* later we register inside of bt878_find_audio_dma()
598 * because we may want to ignore certain cards */
599 bt878_pci_driver_registered = 1;
600 return pci_register_driver(&bt878_pci_driver); 592 return pci_register_driver(&bt878_pci_driver);
601} 593}
602 594
603static void bt878_cleanup_module(void) 595static void __exit bt878_cleanup_module(void)
604{ 596{
605 if (bt878_pci_driver_registered) { 597 pci_unregister_driver(&bt878_pci_driver);
606 bt878_pci_driver_registered = 0;
607 pci_unregister_driver(&bt878_pci_driver);
608 }
609 return;
610} 598}
611 599
612module_init(bt878_init_module); 600module_init(bt878_init_module);
613module_exit(bt878_cleanup_module); 601module_exit(bt878_cleanup_module);
614 602
615//MODULE_AUTHOR("XXX");
616MODULE_LICENSE("GPL"); 603MODULE_LICENSE("GPL");
617 604
618/* 605/*
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 91353a6faf1d..8b0cde38984d 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1352,8 +1352,7 @@ static int dst_get_tuna(struct dst_state *state)
1352 return retval; 1352 return retval;
1353 } 1353 }
1354 if ((state->type_flags & DST_TYPE_HAS_VLF) && 1354 if ((state->type_flags & DST_TYPE_HAS_VLF) &&
1355 !(state->dst_type == DST_TYPE_IS_CABLE) && 1355 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1356 !(state->dst_type == DST_TYPE_IS_ATSC)) {
1357 1356
1358 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1357 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1359 dprintk(verbose, DST_INFO, 1, "checksum failure ? "); 1358 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
@@ -1820,8 +1819,13 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
1820 .frequency_max = 858000000, 1819 .frequency_max = 858000000,
1821 .symbol_rate_min = 1000000, 1820 .symbol_rate_min = 1000000,
1822 .symbol_rate_max = 45000000, 1821 .symbol_rate_max = 45000000,
1823 /* . symbol_rate_tolerance = ???,*/ 1822 .caps = FE_CAN_FEC_AUTO |
1824 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO 1823 FE_CAN_QAM_AUTO |
1824 FE_CAN_QAM_16 |
1825 FE_CAN_QAM_32 |
1826 FE_CAN_QAM_64 |
1827 FE_CAN_QAM_128 |
1828 FE_CAN_QAM_256
1825 }, 1829 },
1826 1830
1827 .release = dst_release, 1831 .release = dst_release,
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
index de3eeb0a8d6e..695239227cb7 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -8,6 +8,7 @@ config DVB_DM1105
8 select DVB_STB6000 if !DVB_FE_CUSTOMISE 8 select DVB_STB6000 if !DVB_FE_CUSTOMISE
9 select DVB_CX24116 if !DVB_FE_CUSTOMISE 9 select DVB_CX24116 if !DVB_FE_CUSTOMISE
10 select DVB_SI21XX if !DVB_FE_CUSTOMISE 10 select DVB_SI21XX if !DVB_FE_CUSTOMISE
11 select DVB_DS3000 if !DVB_FE_CUSTOMISE
11 select VIDEO_IR 12 select VIDEO_IR
12 help 13 help
13 Support for cards based on the SDMC DM1105 PCI chip like 14 Support for cards based on the SDMC DM1105 PCI chip like
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index f0f483ac8b89..383cca378b8c 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -43,6 +43,7 @@
43#include "si21xx.h" 43#include "si21xx.h"
44#include "cx24116.h" 44#include "cx24116.h"
45#include "z0194a.h" 45#include "z0194a.h"
46#include "ds3000.h"
46 47
47#define UNSET (-1U) 48#define UNSET (-1U)
48 49
@@ -269,7 +270,7 @@ struct infrared {
269 u32 ir_command; 270 u32 ir_command;
270}; 271};
271 272
272struct dm1105dvb { 273struct dm1105_dev {
273 /* pci */ 274 /* pci */
274 struct pci_dev *pdev; 275 struct pci_dev *pdev;
275 u8 __iomem *io_mem; 276 u8 __iomem *io_mem;
@@ -308,31 +309,47 @@ struct dm1105dvb {
308 spinlock_t lock; 309 spinlock_t lock;
309}; 310};
310 311
311#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) 312#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))
313
314#define dm_readb(reg) inb(dm_io_mem(reg))
315#define dm_writeb(reg, value) outb((value), (dm_io_mem(reg)))
316
317#define dm_readw(reg) inw(dm_io_mem(reg))
318#define dm_writew(reg, value) outw((value), (dm_io_mem(reg)))
319
320#define dm_readl(reg) inl(dm_io_mem(reg))
321#define dm_writel(reg, value) outl((value), (dm_io_mem(reg)))
322
323#define dm_andorl(reg, mask, value) \
324 outl((inl(dm_io_mem(reg)) & ~(mask)) |\
325 ((value) & (mask)), (dm_io_mem(reg)))
326
327#define dm_setl(reg, bit) dm_andorl((reg), (bit), (bit))
328#define dm_clearl(reg, bit) dm_andorl((reg), (bit), 0)
312 329
313static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, 330static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
314 struct i2c_msg *msgs, int num) 331 struct i2c_msg *msgs, int num)
315{ 332{
316 struct dm1105dvb *dm1105dvb ; 333 struct dm1105_dev *dev ;
317 334
318 int addr, rc, i, j, k, len, byte, data; 335 int addr, rc, i, j, k, len, byte, data;
319 u8 status; 336 u8 status;
320 337
321 dm1105dvb = i2c_adap->algo_data; 338 dev = i2c_adap->algo_data;
322 for (i = 0; i < num; i++) { 339 for (i = 0; i < num; i++) {
323 outb(0x00, dm_io_mem(DM1105_I2CCTR)); 340 dm_writeb(DM1105_I2CCTR, 0x00);
324 if (msgs[i].flags & I2C_M_RD) { 341 if (msgs[i].flags & I2C_M_RD) {
325 /* read bytes */ 342 /* read bytes */
326 addr = msgs[i].addr << 1; 343 addr = msgs[i].addr << 1;
327 addr |= 1; 344 addr |= 1;
328 outb(addr, dm_io_mem(DM1105_I2CDAT)); 345 dm_writeb(DM1105_I2CDAT, addr);
329 for (byte = 0; byte < msgs[i].len; byte++) 346 for (byte = 0; byte < msgs[i].len; byte++)
330 outb(0, dm_io_mem(DM1105_I2CDAT + byte + 1)); 347 dm_writeb(DM1105_I2CDAT + byte + 1, 0);
331 348
332 outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); 349 dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
333 for (j = 0; j < 55; j++) { 350 for (j = 0; j < 55; j++) {
334 mdelay(10); 351 mdelay(10);
335 status = inb(dm_io_mem(DM1105_I2CSTS)); 352 status = dm_readb(DM1105_I2CSTS);
336 if ((status & 0xc0) == 0x40) 353 if ((status & 0xc0) == 0x40)
337 break; 354 break;
338 } 355 }
@@ -340,56 +357,54 @@ static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
340 return -1; 357 return -1;
341 358
342 for (byte = 0; byte < msgs[i].len; byte++) { 359 for (byte = 0; byte < msgs[i].len; byte++) {
343 rc = inb(dm_io_mem(DM1105_I2CDAT + byte + 1)); 360 rc = dm_readb(DM1105_I2CDAT + byte + 1);
344 if (rc < 0) 361 if (rc < 0)
345 goto err; 362 goto err;
346 msgs[i].buf[byte] = rc; 363 msgs[i].buf[byte] = rc;
347 } 364 }
348 } else { 365 } else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {
349 if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) { 366 /* prepaired for cx24116 firmware */
350 /* prepaired for cx24116 firmware */ 367 /* Write in small blocks */
351 /* Write in small blocks */ 368 len = msgs[i].len - 1;
352 len = msgs[i].len - 1; 369 k = 1;
353 k = 1; 370 do {
354 do { 371 dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
355 outb(msgs[i].addr << 1, dm_io_mem(DM1105_I2CDAT)); 372 dm_writeb(DM1105_I2CDAT + 1, 0xf7);
356 outb(0xf7, dm_io_mem(DM1105_I2CDAT + 1)); 373 for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {
357 for (byte = 0; byte < (len > 48 ? 48 : len); byte++) { 374 data = msgs[i].buf[k + byte];
358 data = msgs[i].buf[k+byte]; 375 dm_writeb(DM1105_I2CDAT + byte + 2, data);
359 outb(data, dm_io_mem(DM1105_I2CDAT + byte + 2));
360 }
361 outb(0x82 + (len > 48 ? 48 : len), dm_io_mem(DM1105_I2CCTR));
362 for (j = 0; j < 25; j++) {
363 mdelay(10);
364 status = inb(dm_io_mem(DM1105_I2CSTS));
365 if ((status & 0xc0) == 0x40)
366 break;
367 }
368
369 if (j >= 25)
370 return -1;
371
372 k += 48;
373 len -= 48;
374 } while (len > 0);
375 } else {
376 /* write bytes */
377 outb(msgs[i].addr<<1, dm_io_mem(DM1105_I2CDAT));
378 for (byte = 0; byte < msgs[i].len; byte++) {
379 data = msgs[i].buf[byte];
380 outb(data, dm_io_mem(DM1105_I2CDAT + byte + 1));
381 } 376 }
382 outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); 377 dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len));
383 for (j = 0; j < 25; j++) { 378 for (j = 0; j < 25; j++) {
384 mdelay(10); 379 mdelay(10);
385 status = inb(dm_io_mem(DM1105_I2CSTS)); 380 status = dm_readb(DM1105_I2CSTS);
386 if ((status & 0xc0) == 0x40) 381 if ((status & 0xc0) == 0x40)
387 break; 382 break;
388 } 383 }
389 384
390 if (j >= 25) 385 if (j >= 25)
391 return -1; 386 return -1;
387
388 k += 48;
389 len -= 48;
390 } while (len > 0);
391 } else {
392 /* write bytes */
393 dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);
394 for (byte = 0; byte < msgs[i].len; byte++) {
395 data = msgs[i].buf[byte];
396 dm_writeb(DM1105_I2CDAT + byte + 1, data);
392 } 397 }
398 dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);
399 for (j = 0; j < 25; j++) {
400 mdelay(10);
401 status = dm_readb(DM1105_I2CSTS);
402 if ((status & 0xc0) == 0x40)
403 break;
404 }
405
406 if (j >= 25)
407 return -1;
393 } 408 }
394 } 409 }
395 return num; 410 return num;
@@ -407,22 +422,22 @@ static struct i2c_algorithm dm1105_algo = {
407 .functionality = functionality, 422 .functionality = functionality,
408}; 423};
409 424
410static inline struct dm1105dvb *feed_to_dm1105dvb(struct dvb_demux_feed *feed) 425static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed)
411{ 426{
412 return container_of(feed->demux, struct dm1105dvb, demux); 427 return container_of(feed->demux, struct dm1105_dev, demux);
413} 428}
414 429
415static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) 430static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe)
416{ 431{
417 return container_of(fe->dvb, struct dm1105dvb, dvb_adapter); 432 return container_of(fe->dvb, struct dm1105_dev, dvb_adapter);
418} 433}
419 434
420static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 435static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
421{ 436{
422 struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); 437 struct dm1105_dev *dev = frontend_to_dm1105_dev(fe);
423 u32 lnb_mask, lnb_13v, lnb_18v, lnb_off; 438 u32 lnb_mask, lnb_13v, lnb_18v, lnb_off;
424 439
425 switch (dm1105dvb->boardnr) { 440 switch (dev->boardnr) {
426 case DM1105_BOARD_AXESS_DM05: 441 case DM1105_BOARD_AXESS_DM05:
427 lnb_mask = DM05_LNB_MASK; 442 lnb_mask = DM05_LNB_MASK;
428 lnb_off = DM05_LNB_OFF; 443 lnb_off = DM05_LNB_OFF;
@@ -438,62 +453,67 @@ static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volta
438 lnb_18v = DM1105_LNB_18V; 453 lnb_18v = DM1105_LNB_18V;
439 } 454 }
440 455
441 outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); 456 dm_writel(DM1105_GPIOCTR, lnb_mask);
442 if (voltage == SEC_VOLTAGE_18) 457 if (voltage == SEC_VOLTAGE_18)
443 outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); 458 dm_writel(DM1105_GPIOVAL, lnb_18v);
444 else if (voltage == SEC_VOLTAGE_13) 459 else if (voltage == SEC_VOLTAGE_13)
445 outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); 460 dm_writel(DM1105_GPIOVAL, lnb_13v);
446 else 461 else
447 outl(lnb_off, dm_io_mem(DM1105_GPIOVAL)); 462 dm_writel(DM1105_GPIOVAL, lnb_off);
448 463
449 return 0; 464 return 0;
450} 465}
451 466
452static void dm1105dvb_set_dma_addr(struct dm1105dvb *dm1105dvb) 467static void dm1105_set_dma_addr(struct dm1105_dev *dev)
453{ 468{
454 outl(cpu_to_le32(dm1105dvb->dma_addr), dm_io_mem(DM1105_STADR)); 469 dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr));
455} 470}
456 471
457static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb) 472static int __devinit dm1105_dma_map(struct dm1105_dev *dev)
458{ 473{
459 dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr); 474 dev->ts_buf = pci_alloc_consistent(dev->pdev,
475 6 * DM1105_DMA_BYTES,
476 &dev->dma_addr);
460 477
461 return !dm1105dvb->ts_buf; 478 return !dev->ts_buf;
462} 479}
463 480
464static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb) 481static void dm1105_dma_unmap(struct dm1105_dev *dev)
465{ 482{
466 pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr); 483 pci_free_consistent(dev->pdev,
484 6 * DM1105_DMA_BYTES,
485 dev->ts_buf,
486 dev->dma_addr);
467} 487}
468 488
469static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb) 489static void dm1105_enable_irqs(struct dm1105_dev *dev)
470{ 490{
471 outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK)); 491 dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK);
472 outb(1, dm_io_mem(DM1105_CR)); 492 dm_writeb(DM1105_CR, 1);
473} 493}
474 494
475static void dm1105dvb_disable_irqs(struct dm1105dvb *dm1105dvb) 495static void dm1105_disable_irqs(struct dm1105_dev *dev)
476{ 496{
477 outb(INTMAK_IRM, dm_io_mem(DM1105_INTMAK)); 497 dm_writeb(DM1105_INTMAK, INTMAK_IRM);
478 outb(0, dm_io_mem(DM1105_CR)); 498 dm_writeb(DM1105_CR, 0);
479} 499}
480 500
481static int dm1105dvb_start_feed(struct dvb_demux_feed *f) 501static int dm1105_start_feed(struct dvb_demux_feed *f)
482{ 502{
483 struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); 503 struct dm1105_dev *dev = feed_to_dm1105_dev(f);
484 504
485 if (dm1105dvb->full_ts_users++ == 0) 505 if (dev->full_ts_users++ == 0)
486 dm1105dvb_enable_irqs(dm1105dvb); 506 dm1105_enable_irqs(dev);
487 507
488 return 0; 508 return 0;
489} 509}
490 510
491static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) 511static int dm1105_stop_feed(struct dvb_demux_feed *f)
492{ 512{
493 struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); 513 struct dm1105_dev *dev = feed_to_dm1105_dev(f);
494 514
495 if (--dm1105dvb->full_ts_users == 0) 515 if (--dev->full_ts_users == 0)
496 dm1105dvb_disable_irqs(dm1105dvb); 516 dm1105_disable_irqs(dev);
497 517
498 return 0; 518 return 0;
499} 519}
@@ -517,68 +537,64 @@ static void dm1105_emit_key(struct work_struct *work)
517/* work handler */ 537/* work handler */
518static void dm1105_dmx_buffer(struct work_struct *work) 538static void dm1105_dmx_buffer(struct work_struct *work)
519{ 539{
520 struct dm1105dvb *dm1105dvb = 540 struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work);
521 container_of(work, struct dm1105dvb, work);
522 unsigned int nbpackets; 541 unsigned int nbpackets;
523 u32 oldwrp = dm1105dvb->wrp; 542 u32 oldwrp = dev->wrp;
524 u32 nextwrp = dm1105dvb->nextwrp; 543 u32 nextwrp = dev->nextwrp;
525 544
526 if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && 545 if (!((dev->ts_buf[oldwrp] == 0x47) &&
527 (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && 546 (dev->ts_buf[oldwrp + 188] == 0x47) &&
528 (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { 547 (dev->ts_buf[oldwrp + 188 * 2] == 0x47))) {
529 dm1105dvb->PacketErrorCount++; 548 dev->PacketErrorCount++;
530 /* bad packet found */ 549 /* bad packet found */
531 if ((dm1105dvb->PacketErrorCount >= 2) && 550 if ((dev->PacketErrorCount >= 2) &&
532 (dm1105dvb->dmarst == 0)) { 551 (dev->dmarst == 0)) {
533 outb(1, dm_io_mem(DM1105_RST)); 552 dm_writeb(DM1105_RST, 1);
534 dm1105dvb->wrp = 0; 553 dev->wrp = 0;
535 dm1105dvb->PacketErrorCount = 0; 554 dev->PacketErrorCount = 0;
536 dm1105dvb->dmarst = 0; 555 dev->dmarst = 0;
537 return; 556 return;
538 } 557 }
539 } 558 }
540 559
541 if (nextwrp < oldwrp) { 560 if (nextwrp < oldwrp) {
542 memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, 561 memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp);
543 dm1105dvb->ts_buf, nextwrp); 562 nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188;
544 nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188;
545 } else 563 } else
546 nbpackets = (nextwrp - oldwrp) / 188; 564 nbpackets = (nextwrp - oldwrp) / 188;
547 565
548 dm1105dvb->wrp = nextwrp; 566 dev->wrp = nextwrp;
549 dvb_dmx_swfilter_packets(&dm1105dvb->demux, 567 dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets);
550 &dm1105dvb->ts_buf[oldwrp], nbpackets);
551} 568}
552 569
553static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) 570static irqreturn_t dm1105_irq(int irq, void *dev_id)
554{ 571{
555 struct dm1105dvb *dm1105dvb = dev_id; 572 struct dm1105_dev *dev = dev_id;
556 573
557 /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ 574 /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
558 unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS)); 575 unsigned int intsts = dm_readb(DM1105_INTSTS);
559 outb(intsts, dm_io_mem(DM1105_INTSTS)); 576 dm_writeb(DM1105_INTSTS, intsts);
560 577
561 switch (intsts) { 578 switch (intsts) {
562 case INTSTS_TSIRQ: 579 case INTSTS_TSIRQ:
563 case (INTSTS_TSIRQ | INTSTS_IR): 580 case (INTSTS_TSIRQ | INTSTS_IR):
564 dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - 581 dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR);
565 inl(dm_io_mem(DM1105_STADR)); 582 queue_work(dev->wq, &dev->work);
566 queue_work(dm1105dvb->wq, &dm1105dvb->work);
567 break; 583 break;
568 case INTSTS_IR: 584 case INTSTS_IR:
569 dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); 585 dev->ir.ir_command = dm_readl(DM1105_IRCODE);
570 schedule_work(&dm1105dvb->ir.work); 586 schedule_work(&dev->ir.work);
571 break; 587 break;
572 } 588 }
573 589
574 return IRQ_HANDLED; 590 return IRQ_HANDLED;
575} 591}
576 592
577int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) 593int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
578{ 594{
579 struct input_dev *input_dev; 595 struct input_dev *input_dev;
580 struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table; 596 struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table;
581 int ir_type = IR_TYPE_OTHER; 597 u64 ir_type = IR_TYPE_OTHER;
582 int err = -ENOMEM; 598 int err = -ENOMEM;
583 599
584 input_dev = input_allocate_device(); 600 input_dev = input_allocate_device();
@@ -611,51 +627,51 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
611 627
612 INIT_WORK(&dm1105->ir.work, dm1105_emit_key); 628 INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
613 629
614 err = ir_input_register(input_dev, ir_codes); 630 err = ir_input_register(input_dev, ir_codes, NULL);
615 631
616 return err; 632 return err;
617} 633}
618 634
619void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) 635void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
620{ 636{
621 ir_input_unregister(dm1105->ir.input_dev); 637 ir_input_unregister(dm1105->ir.input_dev);
622} 638}
623 639
624static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) 640static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
625{ 641{
626 dm1105dvb_disable_irqs(dm1105dvb); 642 dm1105_disable_irqs(dev);
627 643
628 outb(0, dm_io_mem(DM1105_HOST_CTR)); 644 dm_writeb(DM1105_HOST_CTR, 0);
629 645
630 /*DATALEN 188,*/ 646 /*DATALEN 188,*/
631 outb(188, dm_io_mem(DM1105_DTALENTH)); 647 dm_writeb(DM1105_DTALENTH, 188);
632 /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/ 648 /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/
633 outw(0xc10a, dm_io_mem(DM1105_TSCTR)); 649 dm_writew(DM1105_TSCTR, 0xc10a);
634 650
635 /* map DMA and set address */ 651 /* map DMA and set address */
636 dm1105dvb_dma_map(dm1105dvb); 652 dm1105_dma_map(dev);
637 dm1105dvb_set_dma_addr(dm1105dvb); 653 dm1105_set_dma_addr(dev);
638 /* big buffer */ 654 /* big buffer */
639 outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN)); 655 dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES);
640 outb(47, dm_io_mem(DM1105_INTCNT)); 656 dm_writeb(DM1105_INTCNT, 47);
641 657
642 /* IR NEC mode enable */ 658 /* IR NEC mode enable */
643 outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR)); 659 dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK));
644 outb(0, dm_io_mem(DM1105_IRMODE)); 660 dm_writeb(DM1105_IRMODE, 0);
645 outw(0, dm_io_mem(DM1105_SYSTEMCODE)); 661 dm_writew(DM1105_SYSTEMCODE, 0);
646 662
647 return 0; 663 return 0;
648} 664}
649 665
650static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) 666static void dm1105_hw_exit(struct dm1105_dev *dev)
651{ 667{
652 dm1105dvb_disable_irqs(dm1105dvb); 668 dm1105_disable_irqs(dev);
653 669
654 /* IR disable */ 670 /* IR disable */
655 outb(0, dm_io_mem(DM1105_IRCTR)); 671 dm_writeb(DM1105_IRCTR, 0);
656 outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK)); 672 dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK);
657 673
658 dm1105dvb_dma_unmap(dm1105dvb); 674 dm1105_dma_unmap(dev);
659} 675}
660 676
661static struct stv0299_config sharp_z0194a_config = { 677static struct stv0299_config sharp_z0194a_config = {
@@ -685,70 +701,79 @@ static struct cx24116_config serit_sp2633_config = {
685 .demod_address = 0x55, 701 .demod_address = 0x55,
686}; 702};
687 703
688static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) 704static struct ds3000_config dvbworld_ds3000_config = {
705 .demod_address = 0x68,
706};
707
708static int __devinit frontend_init(struct dm1105_dev *dev)
689{ 709{
690 int ret; 710 int ret;
691 711
692 switch (dm1105dvb->boardnr) { 712 switch (dev->boardnr) {
693 case DM1105_BOARD_DVBWORLD_2004: 713 case DM1105_BOARD_DVBWORLD_2004:
694 dm1105dvb->fe = dvb_attach( 714 dev->fe = dvb_attach(
695 cx24116_attach, &serit_sp2633_config, 715 cx24116_attach, &serit_sp2633_config,
696 &dm1105dvb->i2c_adap); 716 &dev->i2c_adap);
697 if (dm1105dvb->fe) 717 if (dev->fe) {
698 dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; 718 dev->fe->ops.set_voltage = dm1105_set_voltage;
719 break;
720 }
721
722 dev->fe = dvb_attach(
723 ds3000_attach, &dvbworld_ds3000_config,
724 &dev->i2c_adap);
725 if (dev->fe)
726 dev->fe->ops.set_voltage = dm1105_set_voltage;
699 727
700 break; 728 break;
701 case DM1105_BOARD_DVBWORLD_2002: 729 case DM1105_BOARD_DVBWORLD_2002:
702 case DM1105_BOARD_AXESS_DM05: 730 case DM1105_BOARD_AXESS_DM05:
703 default: 731 default:
704 dm1105dvb->fe = dvb_attach( 732 dev->fe = dvb_attach(
705 stv0299_attach, &sharp_z0194a_config, 733 stv0299_attach, &sharp_z0194a_config,
706 &dm1105dvb->i2c_adap); 734 &dev->i2c_adap);
707 if (dm1105dvb->fe) { 735 if (dev->fe) {
708 dm1105dvb->fe->ops.set_voltage = 736 dev->fe->ops.set_voltage = dm1105_set_voltage;
709 dm1105dvb_set_voltage; 737 dvb_attach(dvb_pll_attach, dev->fe, 0x60,
710 dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, 738 &dev->i2c_adap, DVB_PLL_OPERA1);
711 &dm1105dvb->i2c_adap, DVB_PLL_OPERA1);
712 break; 739 break;
713 } 740 }
714 741
715 dm1105dvb->fe = dvb_attach( 742 dev->fe = dvb_attach(
716 stv0288_attach, &earda_config, 743 stv0288_attach, &earda_config,
717 &dm1105dvb->i2c_adap); 744 &dev->i2c_adap);
718 if (dm1105dvb->fe) { 745 if (dev->fe) {
719 dm1105dvb->fe->ops.set_voltage = 746 dev->fe->ops.set_voltage = dm1105_set_voltage;
720 dm1105dvb_set_voltage; 747 dvb_attach(stb6000_attach, dev->fe, 0x61,
721 dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, 748 &dev->i2c_adap);
722 &dm1105dvb->i2c_adap);
723 break; 749 break;
724 } 750 }
725 751
726 dm1105dvb->fe = dvb_attach( 752 dev->fe = dvb_attach(
727 si21xx_attach, &serit_config, 753 si21xx_attach, &serit_config,
728 &dm1105dvb->i2c_adap); 754 &dev->i2c_adap);
729 if (dm1105dvb->fe) 755 if (dev->fe)
730 dm1105dvb->fe->ops.set_voltage = 756 dev->fe->ops.set_voltage = dm1105_set_voltage;
731 dm1105dvb_set_voltage;
732 757
733 } 758 }
734 759
735 if (!dm1105dvb->fe) { 760 if (!dev->fe) {
736 dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n"); 761 dev_err(&dev->pdev->dev, "could not attach frontend\n");
737 return -ENODEV; 762 return -ENODEV;
738 } 763 }
739 764
740 ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe); 765 ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe);
741 if (ret < 0) { 766 if (ret < 0) {
742 if (dm1105dvb->fe->ops.release) 767 if (dev->fe->ops.release)
743 dm1105dvb->fe->ops.release(dm1105dvb->fe); 768 dev->fe->ops.release(dev->fe);
744 dm1105dvb->fe = NULL; 769 dev->fe = NULL;
745 return ret; 770 return ret;
746 } 771 }
747 772
748 return 0; 773 return 0;
749} 774}
750 775
751static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) 776static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac)
752{ 777{
753 static u8 command[1] = { 0x28 }; 778 static u8 command[1] = { 0x28 };
754 779
@@ -766,47 +791,47 @@ static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac)
766 }, 791 },
767 }; 792 };
768 793
769 dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); 794 dm1105_i2c_xfer(&dev->i2c_adap, msg , 2);
770 dev_info(&dm1105dvb->pdev->dev, "MAC %pM\n", mac); 795 dev_info(&dev->pdev->dev, "MAC %pM\n", mac);
771} 796}
772 797
773static int __devinit dm1105_probe(struct pci_dev *pdev, 798static int __devinit dm1105_probe(struct pci_dev *pdev,
774 const struct pci_device_id *ent) 799 const struct pci_device_id *ent)
775{ 800{
776 struct dm1105dvb *dm1105dvb; 801 struct dm1105_dev *dev;
777 struct dvb_adapter *dvb_adapter; 802 struct dvb_adapter *dvb_adapter;
778 struct dvb_demux *dvbdemux; 803 struct dvb_demux *dvbdemux;
779 struct dmx_demux *dmx; 804 struct dmx_demux *dmx;
780 int ret = -ENOMEM; 805 int ret = -ENOMEM;
781 int i; 806 int i;
782 807
783 dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); 808 dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL);
784 if (!dm1105dvb) 809 if (!dev)
785 return -ENOMEM; 810 return -ENOMEM;
786 811
787 /* board config */ 812 /* board config */
788 dm1105dvb->nr = dm1105_devcount; 813 dev->nr = dm1105_devcount;
789 dm1105dvb->boardnr = UNSET; 814 dev->boardnr = UNSET;
790 if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards)) 815 if (card[dev->nr] < ARRAY_SIZE(dm1105_boards))
791 dm1105dvb->boardnr = card[dm1105dvb->nr]; 816 dev->boardnr = card[dev->nr];
792 for (i = 0; UNSET == dm1105dvb->boardnr && 817 for (i = 0; UNSET == dev->boardnr &&
793 i < ARRAY_SIZE(dm1105_subids); i++) 818 i < ARRAY_SIZE(dm1105_subids); i++)
794 if (pdev->subsystem_vendor == 819 if (pdev->subsystem_vendor ==
795 dm1105_subids[i].subvendor && 820 dm1105_subids[i].subvendor &&
796 pdev->subsystem_device == 821 pdev->subsystem_device ==
797 dm1105_subids[i].subdevice) 822 dm1105_subids[i].subdevice)
798 dm1105dvb->boardnr = dm1105_subids[i].card; 823 dev->boardnr = dm1105_subids[i].card;
799 824
800 if (UNSET == dm1105dvb->boardnr) { 825 if (UNSET == dev->boardnr) {
801 dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN; 826 dev->boardnr = DM1105_BOARD_UNKNOWN;
802 dm1105_card_list(pdev); 827 dm1105_card_list(pdev);
803 } 828 }
804 829
805 dm1105_devcount++; 830 dm1105_devcount++;
806 dm1105dvb->pdev = pdev; 831 dev->pdev = pdev;
807 dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; 832 dev->buffer_size = 5 * DM1105_DMA_BYTES;
808 dm1105dvb->PacketErrorCount = 0; 833 dev->PacketErrorCount = 0;
809 dm1105dvb->dmarst = 0; 834 dev->dmarst = 0;
810 835
811 ret = pci_enable_device(pdev); 836 ret = pci_enable_device(pdev);
812 if (ret < 0) 837 if (ret < 0)
@@ -822,47 +847,47 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
822 if (ret < 0) 847 if (ret < 0)
823 goto err_pci_disable_device; 848 goto err_pci_disable_device;
824 849
825 dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); 850 dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
826 if (!dm1105dvb->io_mem) { 851 if (!dev->io_mem) {
827 ret = -EIO; 852 ret = -EIO;
828 goto err_pci_release_regions; 853 goto err_pci_release_regions;
829 } 854 }
830 855
831 spin_lock_init(&dm1105dvb->lock); 856 spin_lock_init(&dev->lock);
832 pci_set_drvdata(pdev, dm1105dvb); 857 pci_set_drvdata(pdev, dev);
833 858
834 ret = dm1105dvb_hw_init(dm1105dvb); 859 ret = dm1105_hw_init(dev);
835 if (ret < 0) 860 if (ret < 0)
836 goto err_pci_iounmap; 861 goto err_pci_iounmap;
837 862
838 /* i2c */ 863 /* i2c */
839 i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); 864 i2c_set_adapdata(&dev->i2c_adap, dev);
840 strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME); 865 strcpy(dev->i2c_adap.name, DRIVER_NAME);
841 dm1105dvb->i2c_adap.owner = THIS_MODULE; 866 dev->i2c_adap.owner = THIS_MODULE;
842 dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; 867 dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
843 dm1105dvb->i2c_adap.dev.parent = &pdev->dev; 868 dev->i2c_adap.dev.parent = &pdev->dev;
844 dm1105dvb->i2c_adap.algo = &dm1105_algo; 869 dev->i2c_adap.algo = &dm1105_algo;
845 dm1105dvb->i2c_adap.algo_data = dm1105dvb; 870 dev->i2c_adap.algo_data = dev;
846 ret = i2c_add_adapter(&dm1105dvb->i2c_adap); 871 ret = i2c_add_adapter(&dev->i2c_adap);
847 872
848 if (ret < 0) 873 if (ret < 0)
849 goto err_dm1105dvb_hw_exit; 874 goto err_dm1105_hw_exit;
850 875
851 /* dvb */ 876 /* dvb */
852 ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME, 877 ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME,
853 THIS_MODULE, &pdev->dev, adapter_nr); 878 THIS_MODULE, &pdev->dev, adapter_nr);
854 if (ret < 0) 879 if (ret < 0)
855 goto err_i2c_del_adapter; 880 goto err_i2c_del_adapter;
856 881
857 dvb_adapter = &dm1105dvb->dvb_adapter; 882 dvb_adapter = &dev->dvb_adapter;
858 883
859 dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac); 884 dm1105_read_mac(dev, dvb_adapter->proposed_mac);
860 885
861 dvbdemux = &dm1105dvb->demux; 886 dvbdemux = &dev->demux;
862 dvbdemux->filternum = 256; 887 dvbdemux->filternum = 256;
863 dvbdemux->feednum = 256; 888 dvbdemux->feednum = 256;
864 dvbdemux->start_feed = dm1105dvb_start_feed; 889 dvbdemux->start_feed = dm1105_start_feed;
865 dvbdemux->stop_feed = dm1105dvb_stop_feed; 890 dvbdemux->stop_feed = dm1105_stop_feed;
866 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | 891 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
867 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); 892 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
868 ret = dvb_dmx_init(dvbdemux); 893 ret = dvb_dmx_init(dvbdemux);
@@ -870,113 +895,113 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
870 goto err_dvb_unregister_adapter; 895 goto err_dvb_unregister_adapter;
871 896
872 dmx = &dvbdemux->dmx; 897 dmx = &dvbdemux->dmx;
873 dm1105dvb->dmxdev.filternum = 256; 898 dev->dmxdev.filternum = 256;
874 dm1105dvb->dmxdev.demux = dmx; 899 dev->dmxdev.demux = dmx;
875 dm1105dvb->dmxdev.capabilities = 0; 900 dev->dmxdev.capabilities = 0;
876 901
877 ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter); 902 ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter);
878 if (ret < 0) 903 if (ret < 0)
879 goto err_dvb_dmx_release; 904 goto err_dvb_dmx_release;
880 905
881 dm1105dvb->hw_frontend.source = DMX_FRONTEND_0; 906 dev->hw_frontend.source = DMX_FRONTEND_0;
882 907
883 ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend); 908 ret = dmx->add_frontend(dmx, &dev->hw_frontend);
884 if (ret < 0) 909 if (ret < 0)
885 goto err_dvb_dmxdev_release; 910 goto err_dvb_dmxdev_release;
886 911
887 dm1105dvb->mem_frontend.source = DMX_MEMORY_FE; 912 dev->mem_frontend.source = DMX_MEMORY_FE;
888 913
889 ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend); 914 ret = dmx->add_frontend(dmx, &dev->mem_frontend);
890 if (ret < 0) 915 if (ret < 0)
891 goto err_remove_hw_frontend; 916 goto err_remove_hw_frontend;
892 917
893 ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend); 918 ret = dmx->connect_frontend(dmx, &dev->hw_frontend);
894 if (ret < 0) 919 if (ret < 0)
895 goto err_remove_mem_frontend; 920 goto err_remove_mem_frontend;
896 921
897 ret = frontend_init(dm1105dvb); 922 ret = frontend_init(dev);
898 if (ret < 0) 923 if (ret < 0)
899 goto err_disconnect_frontend; 924 goto err_disconnect_frontend;
900 925
901 dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); 926 dvb_net_init(dvb_adapter, &dev->dvbnet, dmx);
902 dm1105_ir_init(dm1105dvb); 927 dm1105_ir_init(dev);
903 928
904 INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); 929 INIT_WORK(&dev->work, dm1105_dmx_buffer);
905 sprintf(dm1105dvb->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num); 930 sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
906 dm1105dvb->wq = create_singlethread_workqueue(dm1105dvb->wqn); 931 dev->wq = create_singlethread_workqueue(dev->wqn);
907 if (!dm1105dvb->wq) 932 if (!dev->wq)
908 goto err_dvb_net; 933 goto err_dvb_net;
909 934
910 ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, 935 ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED,
911 DRIVER_NAME, dm1105dvb); 936 DRIVER_NAME, dev);
912 if (ret < 0) 937 if (ret < 0)
913 goto err_workqueue; 938 goto err_workqueue;
914 939
915 return 0; 940 return 0;
916 941
917err_workqueue: 942err_workqueue:
918 destroy_workqueue(dm1105dvb->wq); 943 destroy_workqueue(dev->wq);
919err_dvb_net: 944err_dvb_net:
920 dvb_net_release(&dm1105dvb->dvbnet); 945 dvb_net_release(&dev->dvbnet);
921err_disconnect_frontend: 946err_disconnect_frontend:
922 dmx->disconnect_frontend(dmx); 947 dmx->disconnect_frontend(dmx);
923err_remove_mem_frontend: 948err_remove_mem_frontend:
924 dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); 949 dmx->remove_frontend(dmx, &dev->mem_frontend);
925err_remove_hw_frontend: 950err_remove_hw_frontend:
926 dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); 951 dmx->remove_frontend(dmx, &dev->hw_frontend);
927err_dvb_dmxdev_release: 952err_dvb_dmxdev_release:
928 dvb_dmxdev_release(&dm1105dvb->dmxdev); 953 dvb_dmxdev_release(&dev->dmxdev);
929err_dvb_dmx_release: 954err_dvb_dmx_release:
930 dvb_dmx_release(dvbdemux); 955 dvb_dmx_release(dvbdemux);
931err_dvb_unregister_adapter: 956err_dvb_unregister_adapter:
932 dvb_unregister_adapter(dvb_adapter); 957 dvb_unregister_adapter(dvb_adapter);
933err_i2c_del_adapter: 958err_i2c_del_adapter:
934 i2c_del_adapter(&dm1105dvb->i2c_adap); 959 i2c_del_adapter(&dev->i2c_adap);
935err_dm1105dvb_hw_exit: 960err_dm1105_hw_exit:
936 dm1105dvb_hw_exit(dm1105dvb); 961 dm1105_hw_exit(dev);
937err_pci_iounmap: 962err_pci_iounmap:
938 pci_iounmap(pdev, dm1105dvb->io_mem); 963 pci_iounmap(pdev, dev->io_mem);
939err_pci_release_regions: 964err_pci_release_regions:
940 pci_release_regions(pdev); 965 pci_release_regions(pdev);
941err_pci_disable_device: 966err_pci_disable_device:
942 pci_disable_device(pdev); 967 pci_disable_device(pdev);
943err_kfree: 968err_kfree:
944 pci_set_drvdata(pdev, NULL); 969 pci_set_drvdata(pdev, NULL);
945 kfree(dm1105dvb); 970 kfree(dev);
946 return ret; 971 return ret;
947} 972}
948 973
949static void __devexit dm1105_remove(struct pci_dev *pdev) 974static void __devexit dm1105_remove(struct pci_dev *pdev)
950{ 975{
951 struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev); 976 struct dm1105_dev *dev = pci_get_drvdata(pdev);
952 struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter; 977 struct dvb_adapter *dvb_adapter = &dev->dvb_adapter;
953 struct dvb_demux *dvbdemux = &dm1105dvb->demux; 978 struct dvb_demux *dvbdemux = &dev->demux;
954 struct dmx_demux *dmx = &dvbdemux->dmx; 979 struct dmx_demux *dmx = &dvbdemux->dmx;
955 980
956 dm1105_ir_exit(dm1105dvb); 981 dm1105_ir_exit(dev);
957 dmx->close(dmx); 982 dmx->close(dmx);
958 dvb_net_release(&dm1105dvb->dvbnet); 983 dvb_net_release(&dev->dvbnet);
959 if (dm1105dvb->fe) 984 if (dev->fe)
960 dvb_unregister_frontend(dm1105dvb->fe); 985 dvb_unregister_frontend(dev->fe);
961 986
962 dmx->disconnect_frontend(dmx); 987 dmx->disconnect_frontend(dmx);
963 dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); 988 dmx->remove_frontend(dmx, &dev->mem_frontend);
964 dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); 989 dmx->remove_frontend(dmx, &dev->hw_frontend);
965 dvb_dmxdev_release(&dm1105dvb->dmxdev); 990 dvb_dmxdev_release(&dev->dmxdev);
966 dvb_dmx_release(dvbdemux); 991 dvb_dmx_release(dvbdemux);
967 dvb_unregister_adapter(dvb_adapter); 992 dvb_unregister_adapter(dvb_adapter);
968 if (&dm1105dvb->i2c_adap) 993 if (&dev->i2c_adap)
969 i2c_del_adapter(&dm1105dvb->i2c_adap); 994 i2c_del_adapter(&dev->i2c_adap);
970 995
971 dm1105dvb_hw_exit(dm1105dvb); 996 dm1105_hw_exit(dev);
972 synchronize_irq(pdev->irq); 997 synchronize_irq(pdev->irq);
973 free_irq(pdev->irq, dm1105dvb); 998 free_irq(pdev->irq, dev);
974 pci_iounmap(pdev, dm1105dvb->io_mem); 999 pci_iounmap(pdev, dev->io_mem);
975 pci_release_regions(pdev); 1000 pci_release_regions(pdev);
976 pci_disable_device(pdev); 1001 pci_disable_device(pdev);
977 pci_set_drvdata(pdev, NULL); 1002 pci_set_drvdata(pdev, NULL);
978 dm1105_devcount--; 1003 dm1105_devcount--;
979 kfree(dm1105dvb); 1004 kfree(dev);
980} 1005}
981 1006
982static struct pci_device_id dm1105_id_table[] __devinitdata = { 1007static struct pci_device_id dm1105_id_table[] __devinitdata = {
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 07461222a7f5..55ea260572bf 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1199,8 +1199,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1199{ 1199{
1200 int r = 0; 1200 int r = 0;
1201 1201
1202 dtv_property_dump(tvp);
1203
1204 /* Allow the frontend to validate incoming properties */ 1202 /* Allow the frontend to validate incoming properties */
1205 if (fe->ops.get_property) 1203 if (fe->ops.get_property)
1206 r = fe->ops.get_property(fe, tvp); 1204 r = fe->ops.get_property(fe, tvp);
@@ -1323,6 +1321,8 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1323 r = -1; 1321 r = -1;
1324 } 1322 }
1325 1323
1324 dtv_property_dump(tvp);
1325
1326 return r; 1326 return r;
1327} 1327}
1328 1328
@@ -1488,7 +1488,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1488 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1488 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1489 int err = -EOPNOTSUPP; 1489 int err = -EOPNOTSUPP;
1490 1490
1491 dprintk ("%s\n", __func__); 1491 dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
1492 1492
1493 if (fepriv->exit) 1493 if (fepriv->exit)
1494 return -ENODEV; 1494 return -ENODEV;
@@ -1536,8 +1536,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1536 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) 1536 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1537 return -EINVAL; 1537 return -EINVAL;
1538 1538
1539 tvp = (struct dtv_property *) kmalloc(tvps->num * 1539 tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
1540 sizeof(struct dtv_property), GFP_KERNEL);
1541 if (!tvp) { 1540 if (!tvp) {
1542 err = -ENOMEM; 1541 err = -ENOMEM;
1543 goto out; 1542 goto out;
@@ -1569,8 +1568,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1569 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) 1568 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1570 return -EINVAL; 1569 return -EINVAL;
1571 1570
1572 tvp = (struct dtv_property *) kmalloc(tvps->num * 1571 tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
1573 sizeof(struct dtv_property), GFP_KERNEL);
1574 if (!tvp) { 1572 if (!tvp) {
1575 err = -ENOMEM; 1573 err = -ENOMEM;
1576 goto out; 1574 goto out;
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 584bbd194dc8..a5712cd7c65f 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -89,6 +89,7 @@ void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
89 rbuf->pread = rbuf->pwrite; 89 rbuf->pread = rbuf->pwrite;
90 rbuf->error = 0; 90 rbuf->error = 0;
91} 91}
92EXPORT_SYMBOL(dvb_ringbuffer_flush);
92 93
93void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) 94void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
94{ 95{
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 465295b1d14b..e5f91f16ffa4 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -336,3 +336,11 @@ config DVB_USB_EC168
336 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 336 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
337 help 337 help
338 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. 338 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
339
340config DVB_USB_AZ6027
341 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
342 depends on DVB_USB
343 select DVB_STB0899 if !DVB_FE_CUSTOMISE
344 select DVB_STB6100 if !DVB_FE_CUSTOMISE
345 help
346 Say Y here to support the AZ6027 device
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 72c92cb69a22..1a192453b0e7 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -85,6 +85,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
85dvb-usb-ec168-objs = ec168.o 85dvb-usb-ec168-objs = ec168.o
86obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o 86obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
87 87
88dvb-usb-az6027-objs = az6027.o
89obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
90
88EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 91EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
89# due to tuner-xc3028 92# due to tuner-xc3028
90EXTRA_CFLAGS += -Idrivers/media/common/tuners 93EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 8b60a601fb82..d7975383d31b 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -21,6 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/hash.h>
25
24#include "af9015.h" 26#include "af9015.h"
25#include "af9013.h" 27#include "af9013.h"
26#include "mt2060.h" 28#include "mt2060.h"
@@ -553,26 +555,45 @@ exit:
553 return ret; 555 return ret;
554} 556}
555 557
556/* dump eeprom */ 558/* hash (and dump) eeprom */
557static int af9015_eeprom_dump(struct dvb_usb_device *d) 559static int af9015_eeprom_hash(struct usb_device *udev)
558{ 560{
559 u8 reg, val; 561 static const unsigned int eeprom_size = 256;
562 unsigned int reg;
563 int ret;
564 u8 val, *eeprom;
565 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
560 566
561 for (reg = 0; ; reg++) { 567 eeprom = kmalloc(eeprom_size, GFP_KERNEL);
562 if (reg % 16 == 0) { 568 if (eeprom == NULL)
563 if (reg) 569 return -ENOMEM;
564 deb_info(KERN_CONT "\n"); 570
565 deb_info(KERN_DEBUG "%02x:", reg); 571 for (reg = 0; reg < eeprom_size; reg++) {
566 } 572 req.addr = reg;
567 if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0) 573 ret = af9015_rw_udev(udev, &req);
568 deb_info(KERN_CONT " %02x", val); 574 if (ret)
569 else 575 goto free;
570 deb_info(KERN_CONT " --"); 576 eeprom[reg] = val;
571 if (reg == 0xff)
572 break;
573 } 577 }
574 deb_info(KERN_CONT "\n"); 578
575 return 0; 579 if (dvb_usb_af9015_debug & 0x01)
580 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
581 eeprom_size);
582
583 BUG_ON(eeprom_size % 4);
584
585 af9015_config.eeprom_sum = 0;
586 for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
587 af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
588 af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
589 }
590
591 deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
592
593 ret = 0;
594free:
595 kfree(eeprom);
596 return ret;
576} 597}
577 598
578static int af9015_download_ir_table(struct dvb_usb_device *d) 599static int af9015_download_ir_table(struct dvb_usb_device *d)
@@ -711,12 +732,132 @@ error:
711 return ret; 732 return ret;
712} 733}
713 734
735struct af9015_setup {
736 unsigned int id;
737 struct dvb_usb_rc_key *rc_key_map;
738 unsigned int rc_key_map_size;
739 u8 *ir_table;
740 unsigned int ir_table_size;
741};
742
743static const struct af9015_setup *af9015_setup_match(unsigned int id,
744 const struct af9015_setup *table)
745{
746 for (; table->rc_key_map; table++)
747 if (table->id == id)
748 return table;
749 return NULL;
750}
751
752static const struct af9015_setup af9015_setup_modparam[] = {
753 { AF9015_REMOTE_A_LINK_DTU_M,
754 af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link),
755 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
756 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
757 af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi),
758 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
759 { AF9015_REMOTE_MYGICTV_U718,
760 af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv),
761 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
762 { AF9015_REMOTE_DIGITTRADE_DVB_T,
763 af9015_rc_keys_digittrade, ARRAY_SIZE(af9015_rc_keys_digittrade),
764 af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) },
765 { AF9015_REMOTE_AVERMEDIA_KS,
766 af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia),
767 af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) },
768 { }
769};
770
771/* don't add new entries here anymore, use hashes instead */
772static const struct af9015_setup af9015_setup_usbids[] = {
773 { USB_VID_LEADTEK,
774 af9015_rc_keys_leadtek, ARRAY_SIZE(af9015_rc_keys_leadtek),
775 af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) },
776 { USB_VID_VISIONPLUS,
777 af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan),
778 af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) },
779 { USB_VID_KWORLD_2, /* TODO: use correct rc keys */
780 af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan),
781 af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) },
782 { USB_VID_AVERMEDIA,
783 af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia),
784 af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) },
785 { USB_VID_MSI_2,
786 af9015_rc_keys_msi_digivox_iii, ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii),
787 af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) },
788 { }
789};
790
791static const struct af9015_setup af9015_setup_hashes[] = {
792 { 0xb8feb708,
793 af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi),
794 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
795 { 0xa3703d00,
796 af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link),
797 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
798 { 0x9b7dc64e,
799 af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv),
800 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
801 { }
802};
803
804static void af9015_set_remote_config(struct usb_device *udev,
805 struct dvb_usb_device_properties *props)
806{
807 const struct af9015_setup *table = NULL;
808
809 if (dvb_usb_af9015_remote) {
810 /* load remote defined as module param */
811 table = af9015_setup_match(dvb_usb_af9015_remote,
812 af9015_setup_modparam);
813 } else {
814 u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
815
816 table = af9015_setup_match(af9015_config.eeprom_sum,
817 af9015_setup_hashes);
818
819 if (!table && vendor == USB_VID_AFATECH) {
820 /* Check USB manufacturer and product strings and try
821 to determine correct remote in case of chip vendor
822 reference IDs are used.
823 DO NOT ADD ANYTHING NEW HERE. Use hashes instead.
824 */
825 char manufacturer[10];
826 memset(manufacturer, 0, sizeof(manufacturer));
827 usb_string(udev, udev->descriptor.iManufacturer,
828 manufacturer, sizeof(manufacturer));
829 if (!strcmp("MSI", manufacturer)) {
830 /* iManufacturer 1 MSI
831 iProduct 2 MSI K-VOX */
832 table = af9015_setup_match(
833 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
834 af9015_setup_modparam);
835 } else if (udev->descriptor.idProduct ==
836 cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
837 table = &(const struct af9015_setup){ 0,
838 af9015_rc_keys_trekstor,
839 ARRAY_SIZE(af9015_rc_keys_trekstor),
840 af9015_ir_table_trekstor,
841 ARRAY_SIZE(af9015_ir_table_trekstor)
842 };
843 }
844 } else if (!table)
845 table = af9015_setup_match(vendor, af9015_setup_usbids);
846 }
847
848 if (table) {
849 props->rc_key_map = table->rc_key_map;
850 props->rc_key_map_size = table->rc_key_map_size;
851 af9015_config.ir_table = table->ir_table;
852 af9015_config.ir_table_size = table->ir_table_size;
853 }
854}
855
714static int af9015_read_config(struct usb_device *udev) 856static int af9015_read_config(struct usb_device *udev)
715{ 857{
716 int ret; 858 int ret;
717 u8 val, i, offset = 0; 859 u8 val, i, offset = 0;
718 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; 860 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
719 char manufacturer[10];
720 861
721 /* IR remote controller */ 862 /* IR remote controller */
722 req.addr = AF9015_EEPROM_IR_MODE; 863 req.addr = AF9015_EEPROM_IR_MODE;
@@ -728,158 +869,18 @@ static int af9015_read_config(struct usb_device *udev)
728 } 869 }
729 if (ret) 870 if (ret)
730 goto error; 871 goto error;
872
873 ret = af9015_eeprom_hash(udev);
874 if (ret)
875 goto error;
876
731 deb_info("%s: IR mode:%d\n", __func__, val); 877 deb_info("%s: IR mode:%d\n", __func__, val);
732 for (i = 0; i < af9015_properties_count; i++) { 878 for (i = 0; i < af9015_properties_count; i++) {
733 if (val == AF9015_IR_MODE_DISABLED) { 879 if (val == AF9015_IR_MODE_DISABLED) {
734 af9015_properties[i].rc_key_map = NULL; 880 af9015_properties[i].rc_key_map = NULL;
735 af9015_properties[i].rc_key_map_size = 0; 881 af9015_properties[i].rc_key_map_size = 0;
736 } else if (dvb_usb_af9015_remote) { 882 } else
737 /* load remote defined as module param */ 883 af9015_set_remote_config(udev, &af9015_properties[i]);
738 switch (dvb_usb_af9015_remote) {
739 case AF9015_REMOTE_A_LINK_DTU_M:
740 af9015_properties[i].rc_key_map =
741 af9015_rc_keys_a_link;
742 af9015_properties[i].rc_key_map_size =
743 ARRAY_SIZE(af9015_rc_keys_a_link);
744 af9015_config.ir_table = af9015_ir_table_a_link;
745 af9015_config.ir_table_size =
746 ARRAY_SIZE(af9015_ir_table_a_link);
747 break;
748 case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3:
749 af9015_properties[i].rc_key_map =
750 af9015_rc_keys_msi;
751 af9015_properties[i].rc_key_map_size =
752 ARRAY_SIZE(af9015_rc_keys_msi);
753 af9015_config.ir_table = af9015_ir_table_msi;
754 af9015_config.ir_table_size =
755 ARRAY_SIZE(af9015_ir_table_msi);
756 break;
757 case AF9015_REMOTE_MYGICTV_U718:
758 af9015_properties[i].rc_key_map =
759 af9015_rc_keys_mygictv;
760 af9015_properties[i].rc_key_map_size =
761 ARRAY_SIZE(af9015_rc_keys_mygictv);
762 af9015_config.ir_table =
763 af9015_ir_table_mygictv;
764 af9015_config.ir_table_size =
765 ARRAY_SIZE(af9015_ir_table_mygictv);
766 break;
767 case AF9015_REMOTE_DIGITTRADE_DVB_T:
768 af9015_properties[i].rc_key_map =
769 af9015_rc_keys_digittrade;
770 af9015_properties[i].rc_key_map_size =
771 ARRAY_SIZE(af9015_rc_keys_digittrade);
772 af9015_config.ir_table =
773 af9015_ir_table_digittrade;
774 af9015_config.ir_table_size =
775 ARRAY_SIZE(af9015_ir_table_digittrade);
776 break;
777 case AF9015_REMOTE_AVERMEDIA_KS:
778 af9015_properties[i].rc_key_map =
779 af9015_rc_keys_avermedia;
780 af9015_properties[i].rc_key_map_size =
781 ARRAY_SIZE(af9015_rc_keys_avermedia);
782 af9015_config.ir_table =
783 af9015_ir_table_avermedia_ks;
784 af9015_config.ir_table_size =
785 ARRAY_SIZE(af9015_ir_table_avermedia_ks);
786 break;
787 }
788 } else {
789 switch (le16_to_cpu(udev->descriptor.idVendor)) {
790 case USB_VID_LEADTEK:
791 af9015_properties[i].rc_key_map =
792 af9015_rc_keys_leadtek;
793 af9015_properties[i].rc_key_map_size =
794 ARRAY_SIZE(af9015_rc_keys_leadtek);
795 af9015_config.ir_table =
796 af9015_ir_table_leadtek;
797 af9015_config.ir_table_size =
798 ARRAY_SIZE(af9015_ir_table_leadtek);
799 break;
800 case USB_VID_VISIONPLUS:
801 af9015_properties[i].rc_key_map =
802 af9015_rc_keys_twinhan;
803 af9015_properties[i].rc_key_map_size =
804 ARRAY_SIZE(af9015_rc_keys_twinhan);
805 af9015_config.ir_table =
806 af9015_ir_table_twinhan;
807 af9015_config.ir_table_size =
808 ARRAY_SIZE(af9015_ir_table_twinhan);
809 break;
810 case USB_VID_KWORLD_2:
811 /* TODO: use correct rc keys */
812 af9015_properties[i].rc_key_map =
813 af9015_rc_keys_twinhan;
814 af9015_properties[i].rc_key_map_size =
815 ARRAY_SIZE(af9015_rc_keys_twinhan);
816 af9015_config.ir_table = af9015_ir_table_kworld;
817 af9015_config.ir_table_size =
818 ARRAY_SIZE(af9015_ir_table_kworld);
819 break;
820 /* Check USB manufacturer and product strings and try
821 to determine correct remote in case of chip vendor
822 reference IDs are used. */
823 case USB_VID_AFATECH:
824 memset(manufacturer, 0, sizeof(manufacturer));
825 usb_string(udev, udev->descriptor.iManufacturer,
826 manufacturer, sizeof(manufacturer));
827 if (!strcmp("Geniatech", manufacturer)) {
828 /* iManufacturer 1 Geniatech
829 iProduct 2 AF9015 */
830 af9015_properties[i].rc_key_map =
831 af9015_rc_keys_mygictv;
832 af9015_properties[i].rc_key_map_size =
833 ARRAY_SIZE(af9015_rc_keys_mygictv);
834 af9015_config.ir_table =
835 af9015_ir_table_mygictv;
836 af9015_config.ir_table_size =
837 ARRAY_SIZE(af9015_ir_table_mygictv);
838 } else if (!strcmp("MSI", manufacturer)) {
839 /* iManufacturer 1 MSI
840 iProduct 2 MSI K-VOX */
841 af9015_properties[i].rc_key_map =
842 af9015_rc_keys_msi;
843 af9015_properties[i].rc_key_map_size =
844 ARRAY_SIZE(af9015_rc_keys_msi);
845 af9015_config.ir_table =
846 af9015_ir_table_msi;
847 af9015_config.ir_table_size =
848 ARRAY_SIZE(af9015_ir_table_msi);
849 } else if (udev->descriptor.idProduct ==
850 cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
851 af9015_properties[i].rc_key_map =
852 af9015_rc_keys_trekstor;
853 af9015_properties[i].rc_key_map_size =
854 ARRAY_SIZE(af9015_rc_keys_trekstor);
855 af9015_config.ir_table =
856 af9015_ir_table_trekstor;
857 af9015_config.ir_table_size =
858 ARRAY_SIZE(af9015_ir_table_trekstor);
859 }
860 break;
861 case USB_VID_AVERMEDIA:
862 af9015_properties[i].rc_key_map =
863 af9015_rc_keys_avermedia;
864 af9015_properties[i].rc_key_map_size =
865 ARRAY_SIZE(af9015_rc_keys_avermedia);
866 af9015_config.ir_table =
867 af9015_ir_table_avermedia;
868 af9015_config.ir_table_size =
869 ARRAY_SIZE(af9015_ir_table_avermedia);
870 break;
871 case USB_VID_MSI_2:
872 af9015_properties[i].rc_key_map =
873 af9015_rc_keys_msi_digivox_iii;
874 af9015_properties[i].rc_key_map_size =
875 ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii);
876 af9015_config.ir_table =
877 af9015_ir_table_msi_digivox_iii;
878 af9015_config.ir_table_size =
879 ARRAY_SIZE(af9015_ir_table_msi_digivox_iii);
880 break;
881 }
882 }
883 } 884 }
884 885
885 /* TS mode - one or two receivers */ 886 /* TS mode - one or two receivers */
@@ -1001,6 +1002,9 @@ static int af9015_read_config(struct usb_device *udev)
1001 af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; 1002 af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
1002 af9015_af9013_config[i].rf_spec_inv = 1; 1003 af9015_af9013_config[i].rf_spec_inv = 1;
1003 break; 1004 break;
1005 case AF9013_TUNER_TDA18218:
1006 warn("tuner NXP TDA18218 not supported yet");
1007 return -ENODEV;
1004 default: 1008 default:
1005 warn("tuner id:%d not supported, please report!", val); 1009 warn("tuner id:%d not supported, please report!", val);
1006 return -ENODEV; 1010 return -ENODEV;
@@ -1125,11 +1129,6 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1125 1129
1126 deb_info("%s: init I2C\n", __func__); 1130 deb_info("%s: init I2C\n", __func__);
1127 ret = af9015_i2c_init(adap->dev); 1131 ret = af9015_i2c_init(adap->dev);
1128
1129 /* dump eeprom (debug) */
1130 ret = af9015_eeprom_dump(adap->dev);
1131 if (ret)
1132 return ret;
1133 } else { 1132 } else {
1134 /* select I2C adapter */ 1133 /* select I2C adapter */
1135 i2c_adap = &state->i2c_adap; 1134 i2c_adap = &state->i2c_adap;
@@ -1295,6 +1294,8 @@ static struct usb_device_id af9015_usb_table[] = {
1295/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, 1294/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
1296 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, 1295 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
1297 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, 1296 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
1297 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
1298 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
1298 {0}, 1299 {0},
1299}; 1300};
1300MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1301MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1381,7 +1382,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1381 }, 1382 },
1382 { 1383 {
1383 .name = "DigitalNow TinyTwin DVB-T Receiver", 1384 .name = "DigitalNow TinyTwin DVB-T Receiver",
1384 .cold_ids = {&af9015_usb_table[5], NULL}, 1385 .cold_ids = {&af9015_usb_table[5],
1386 &af9015_usb_table[28], NULL},
1385 .warm_ids = {NULL}, 1387 .warm_ids = {NULL},
1386 }, 1388 },
1387 { 1389 {
@@ -1566,7 +1568,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1566 1568
1567 .i2c_algo = &af9015_i2c_algo, 1569 .i2c_algo = &af9015_i2c_algo,
1568 1570
1569 .num_device_descs = 6, /* max 9 */ 1571 .num_device_descs = 7, /* max 9 */
1570 .devices = { 1572 .devices = {
1571 { 1573 {
1572 .name = "AverMedia AVerTV Volar GPS 805 (A805)", 1574 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1600,6 +1602,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1600 .cold_ids = {&af9015_usb_table[27], NULL}, 1602 .cold_ids = {&af9015_usb_table[27], NULL},
1601 .warm_ids = {NULL}, 1603 .warm_ids = {NULL},
1602 }, 1604 },
1605 {
1606 .name = "Leadtek WinFast DTV2000DS",
1607 .cold_ids = {&af9015_usb_table[29], NULL},
1608 .warm_ids = {NULL},
1609 },
1603 } 1610 }
1604 }, 1611 },
1605}; 1612};
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 931c8515830d..ef36b1831490 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -107,6 +107,7 @@ struct af9015_config {
107 u16 mt2060_if1[2]; 107 u16 mt2060_if1[2];
108 u16 firmware_size; 108 u16 firmware_size;
109 u16 firmware_checksum; 109 u16 firmware_checksum;
110 u32 eeprom_sum;
110 u8 *ir_table; 111 u8 *ir_table;
111 u16 ir_table_size; 112 u16 ir_table_size;
112}; 113};
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c
new file mode 100644
index 000000000000..d7290b2c0913
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/az6027.c
@@ -0,0 +1,1151 @@
1/* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)
2 * receiver.
3 *
4 * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "az6027.h"
13
14#include "stb0899_drv.h"
15#include "stb0899_reg.h"
16#include "stb0899_cfg.h"
17
18#include "stb6100.h"
19#include "stb6100_cfg.h"
20#include "dvb_ca_en50221.h"
21
22int dvb_usb_az6027_debug;
23module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
24MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27
28struct az6027_device_state {
29 struct dvb_ca_en50221 ca;
30 struct mutex ca_mutex;
31 u8 power_state;
32};
33
34static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
35
36 /* 0x0000000b, SYSREG */
37 { STB0899_DEV_ID , 0x30 },
38 { STB0899_DISCNTRL1 , 0x32 },
39 { STB0899_DISCNTRL2 , 0x80 },
40 { STB0899_DISRX_ST0 , 0x04 },
41 { STB0899_DISRX_ST1 , 0x00 },
42 { STB0899_DISPARITY , 0x00 },
43 { STB0899_DISFIFO , 0x00 },
44 { STB0899_DISSTATUS , 0x20 },
45 { STB0899_DISF22 , 0x99 },
46 { STB0899_DISF22RX , 0xa8 },
47 /* SYSREG ? */
48 { STB0899_ACRPRESC , 0x11 },
49 { STB0899_ACRDIV1 , 0x0a },
50 { STB0899_ACRDIV2 , 0x05 },
51 { STB0899_DACR1 , 0x00 },
52 { STB0899_DACR2 , 0x00 },
53 { STB0899_OUTCFG , 0x00 },
54 { STB0899_MODECFG , 0x00 },
55 { STB0899_IRQSTATUS_3 , 0xfe },
56 { STB0899_IRQSTATUS_2 , 0x03 },
57 { STB0899_IRQSTATUS_1 , 0x7c },
58 { STB0899_IRQSTATUS_0 , 0xf4 },
59 { STB0899_IRQMSK_3 , 0xf3 },
60 { STB0899_IRQMSK_2 , 0xfc },
61 { STB0899_IRQMSK_1 , 0xff },
62 { STB0899_IRQMSK_0 , 0xff },
63 { STB0899_IRQCFG , 0x00 },
64 { STB0899_I2CCFG , 0x88 },
65 { STB0899_I2CRPT , 0x58 },
66 { STB0899_IOPVALUE5 , 0x00 },
67 { STB0899_IOPVALUE4 , 0x33 },
68 { STB0899_IOPVALUE3 , 0x6d },
69 { STB0899_IOPVALUE2 , 0x90 },
70 { STB0899_IOPVALUE1 , 0x60 },
71 { STB0899_IOPVALUE0 , 0x00 },
72 { STB0899_GPIO00CFG , 0x82 },
73 { STB0899_GPIO01CFG , 0x82 },
74 { STB0899_GPIO02CFG , 0x82 },
75 { STB0899_GPIO03CFG , 0x82 },
76 { STB0899_GPIO04CFG , 0x82 },
77 { STB0899_GPIO05CFG , 0x82 },
78 { STB0899_GPIO06CFG , 0x82 },
79 { STB0899_GPIO07CFG , 0x82 },
80 { STB0899_GPIO08CFG , 0x82 },
81 { STB0899_GPIO09CFG , 0x82 },
82 { STB0899_GPIO10CFG , 0x82 },
83 { STB0899_GPIO11CFG , 0x82 },
84 { STB0899_GPIO12CFG , 0x82 },
85 { STB0899_GPIO13CFG , 0x82 },
86 { STB0899_GPIO14CFG , 0x82 },
87 { STB0899_GPIO15CFG , 0x82 },
88 { STB0899_GPIO16CFG , 0x82 },
89 { STB0899_GPIO17CFG , 0x82 },
90 { STB0899_GPIO18CFG , 0x82 },
91 { STB0899_GPIO19CFG , 0x82 },
92 { STB0899_GPIO20CFG , 0x82 },
93 { STB0899_SDATCFG , 0xb8 },
94 { STB0899_SCLTCFG , 0xba },
95 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
96 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
97 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
98 { STB0899_DIRCLKCFG , 0x82 },
99 { STB0899_CLKOUT27CFG , 0x7e },
100 { STB0899_STDBYCFG , 0x82 },
101 { STB0899_CS0CFG , 0x82 },
102 { STB0899_CS1CFG , 0x82 },
103 { STB0899_DISEQCOCFG , 0x20 },
104 { STB0899_GPIO32CFG , 0x82 },
105 { STB0899_GPIO33CFG , 0x82 },
106 { STB0899_GPIO34CFG , 0x82 },
107 { STB0899_GPIO35CFG , 0x82 },
108 { STB0899_GPIO36CFG , 0x82 },
109 { STB0899_GPIO37CFG , 0x82 },
110 { STB0899_GPIO38CFG , 0x82 },
111 { STB0899_GPIO39CFG , 0x82 },
112 { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
113 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
114 { STB0899_FILTCTRL , 0x00 },
115 { STB0899_SYSCTRL , 0x01 },
116 { STB0899_STOPCLK1 , 0x20 },
117 { STB0899_STOPCLK2 , 0x00 },
118 { STB0899_INTBUFSTATUS , 0x00 },
119 { STB0899_INTBUFCTRL , 0x0a },
120 { 0xffff , 0xff },
121};
122
123static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
124 { STB0899_DEMOD , 0x00 },
125 { STB0899_RCOMPC , 0xc9 },
126 { STB0899_AGC1CN , 0x01 },
127 { STB0899_AGC1REF , 0x10 },
128 { STB0899_RTC , 0x23 },
129 { STB0899_TMGCFG , 0x4e },
130 { STB0899_AGC2REF , 0x34 },
131 { STB0899_TLSR , 0x84 },
132 { STB0899_CFD , 0xf7 },
133 { STB0899_ACLC , 0x87 },
134 { STB0899_BCLC , 0x94 },
135 { STB0899_EQON , 0x41 },
136 { STB0899_LDT , 0xf1 },
137 { STB0899_LDT2 , 0xe3 },
138 { STB0899_EQUALREF , 0xb4 },
139 { STB0899_TMGRAMP , 0x10 },
140 { STB0899_TMGTHD , 0x30 },
141 { STB0899_IDCCOMP , 0xfd },
142 { STB0899_QDCCOMP , 0xff },
143 { STB0899_POWERI , 0x0c },
144 { STB0899_POWERQ , 0x0f },
145 { STB0899_RCOMP , 0x6c },
146 { STB0899_AGCIQIN , 0x80 },
147 { STB0899_AGC2I1 , 0x06 },
148 { STB0899_AGC2I2 , 0x00 },
149 { STB0899_TLIR , 0x30 },
150 { STB0899_RTF , 0x7f },
151 { STB0899_DSTATUS , 0x00 },
152 { STB0899_LDI , 0xbc },
153 { STB0899_CFRM , 0xea },
154 { STB0899_CFRL , 0x31 },
155 { STB0899_NIRM , 0x2b },
156 { STB0899_NIRL , 0x80 },
157 { STB0899_ISYMB , 0x1d },
158 { STB0899_QSYMB , 0xa6 },
159 { STB0899_SFRH , 0x2f },
160 { STB0899_SFRM , 0x68 },
161 { STB0899_SFRL , 0x40 },
162 { STB0899_SFRUPH , 0x2f },
163 { STB0899_SFRUPM , 0x68 },
164 { STB0899_SFRUPL , 0x40 },
165 { STB0899_EQUAI1 , 0x02 },
166 { STB0899_EQUAQ1 , 0xff },
167 { STB0899_EQUAI2 , 0x04 },
168 { STB0899_EQUAQ2 , 0x05 },
169 { STB0899_EQUAI3 , 0x02 },
170 { STB0899_EQUAQ3 , 0xfd },
171 { STB0899_EQUAI4 , 0x03 },
172 { STB0899_EQUAQ4 , 0x07 },
173 { STB0899_EQUAI5 , 0x08 },
174 { STB0899_EQUAQ5 , 0xf5 },
175 { STB0899_DSTATUS2 , 0x00 },
176 { STB0899_VSTATUS , 0x00 },
177 { STB0899_VERROR , 0x86 },
178 { STB0899_IQSWAP , 0x2a },
179 { STB0899_ECNT1M , 0x00 },
180 { STB0899_ECNT1L , 0x00 },
181 { STB0899_ECNT2M , 0x00 },
182 { STB0899_ECNT2L , 0x00 },
183 { STB0899_ECNT3M , 0x0a },
184 { STB0899_ECNT3L , 0xad },
185 { STB0899_FECAUTO1 , 0x06 },
186 { STB0899_FECM , 0x01 },
187 { STB0899_VTH12 , 0xb0 },
188 { STB0899_VTH23 , 0x7a },
189 { STB0899_VTH34 , 0x58 },
190 { STB0899_VTH56 , 0x38 },
191 { STB0899_VTH67 , 0x34 },
192 { STB0899_VTH78 , 0x24 },
193 { STB0899_PRVIT , 0xff },
194 { STB0899_VITSYNC , 0x19 },
195 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
196 { STB0899_TSULC , 0x42 },
197 { STB0899_RSLLC , 0x41 },
198 { STB0899_TSLPL , 0x12 },
199 { STB0899_TSCFGH , 0x0c },
200 { STB0899_TSCFGM , 0x00 },
201 { STB0899_TSCFGL , 0x00 },
202 { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
203 { STB0899_RSSYNCDEL , 0x00 },
204 { STB0899_TSINHDELH , 0x02 },
205 { STB0899_TSINHDELM , 0x00 },
206 { STB0899_TSINHDELL , 0x00 },
207 { STB0899_TSLLSTKM , 0x1b },
208 { STB0899_TSLLSTKL , 0xb3 },
209 { STB0899_TSULSTKM , 0x00 },
210 { STB0899_TSULSTKL , 0x00 },
211 { STB0899_PCKLENUL , 0xbc },
212 { STB0899_PCKLENLL , 0xcc },
213 { STB0899_RSPCKLEN , 0xbd },
214 { STB0899_TSSTATUS , 0x90 },
215 { STB0899_ERRCTRL1 , 0xb6 },
216 { STB0899_ERRCTRL2 , 0x95 },
217 { STB0899_ERRCTRL3 , 0x8d },
218 { STB0899_DMONMSK1 , 0x27 },
219 { STB0899_DMONMSK0 , 0x03 },
220 { STB0899_DEMAPVIT , 0x5c },
221 { STB0899_PLPARM , 0x19 },
222 { STB0899_PDELCTRL , 0x48 },
223 { STB0899_PDELCTRL2 , 0x00 },
224 { STB0899_BBHCTRL1 , 0x00 },
225 { STB0899_BBHCTRL2 , 0x00 },
226 { STB0899_HYSTTHRESH , 0x77 },
227 { STB0899_MATCSTM , 0x00 },
228 { STB0899_MATCSTL , 0x00 },
229 { STB0899_UPLCSTM , 0x00 },
230 { STB0899_UPLCSTL , 0x00 },
231 { STB0899_DFLCSTM , 0x00 },
232 { STB0899_DFLCSTL , 0x00 },
233 { STB0899_SYNCCST , 0x00 },
234 { STB0899_SYNCDCSTM , 0x00 },
235 { STB0899_SYNCDCSTL , 0x00 },
236 { STB0899_ISI_ENTRY , 0x00 },
237 { STB0899_ISI_BIT_EN , 0x00 },
238 { STB0899_MATSTRM , 0xf0 },
239 { STB0899_MATSTRL , 0x02 },
240 { STB0899_UPLSTRM , 0x45 },
241 { STB0899_UPLSTRL , 0x60 },
242 { STB0899_DFLSTRM , 0xe3 },
243 { STB0899_DFLSTRL , 0x00 },
244 { STB0899_SYNCSTR , 0x47 },
245 { STB0899_SYNCDSTRM , 0x05 },
246 { STB0899_SYNCDSTRL , 0x18 },
247 { STB0899_CFGPDELSTATUS1 , 0x19 },
248 { STB0899_CFGPDELSTATUS2 , 0x2b },
249 { STB0899_BBFERRORM , 0x00 },
250 { STB0899_BBFERRORL , 0x01 },
251 { STB0899_UPKTERRORM , 0x00 },
252 { STB0899_UPKTERRORL , 0x00 },
253 { 0xffff , 0xff },
254};
255
256
257
258struct stb0899_config az6027_stb0899_config = {
259 .init_dev = az6027_stb0899_s1_init_1,
260 .init_s2_demod = stb0899_s2_init_2,
261 .init_s1_demod = az6027_stb0899_s1_init_3,
262 .init_s2_fec = stb0899_s2_init_4,
263 .init_tst = stb0899_s1_init_5,
264
265 .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
266
267 .xtal_freq = 27000000,
268 .inversion = IQ_SWAP_ON, /* 1 */
269
270 .lo_clk = 76500000,
271 .hi_clk = 99000000,
272
273 .esno_ave = STB0899_DVBS2_ESNO_AVE,
274 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
275 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
276 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
277 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
278 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
279 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
280 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
281 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
282
283 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
284 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
285 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
286 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
287
288 .tuner_get_frequency = stb6100_get_frequency,
289 .tuner_set_frequency = stb6100_set_frequency,
290 .tuner_set_bandwidth = stb6100_set_bandwidth,
291 .tuner_get_bandwidth = stb6100_get_bandwidth,
292 .tuner_set_rfsiggain = NULL,
293};
294
295struct stb6100_config az6027_stb6100_config = {
296 .tuner_address = 0xc0,
297 .refclock = 27000000,
298};
299
300
301/* check for mutex FIXME */
302int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
303{
304 int ret = -1;
305 if (mutex_lock_interruptible(&d->usb_mutex))
306 return -EAGAIN;
307
308 ret = usb_control_msg(d->udev,
309 usb_rcvctrlpipe(d->udev, 0),
310 req,
311 USB_TYPE_VENDOR | USB_DIR_IN,
312 value,
313 index,
314 b,
315 blen,
316 2000);
317
318 if (ret < 0) {
319 warn("usb in operation failed. (%d)", ret);
320 ret = -EIO;
321 } else
322 ret = 0;
323
324 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
325 debug_dump(b, blen, deb_xfer);
326
327 mutex_unlock(&d->usb_mutex);
328 return ret;
329}
330
331static int az6027_usb_out_op(struct dvb_usb_device *d,
332 u8 req,
333 u16 value,
334 u16 index,
335 u8 *b,
336 int blen)
337{
338 int ret;
339
340 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
341 debug_dump(b, blen, deb_xfer);
342
343 if (mutex_lock_interruptible(&d->usb_mutex))
344 return -EAGAIN;
345
346 ret = usb_control_msg(d->udev,
347 usb_sndctrlpipe(d->udev, 0),
348 req,
349 USB_TYPE_VENDOR | USB_DIR_OUT,
350 value,
351 index,
352 b,
353 blen,
354 2000);
355
356 if (ret != blen) {
357 warn("usb out operation failed. (%d)", ret);
358 mutex_unlock(&d->usb_mutex);
359 return -EIO;
360 } else{
361 mutex_unlock(&d->usb_mutex);
362 return 0;
363 }
364}
365
366static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
367{
368 int ret;
369 u8 req;
370 u16 value;
371 u16 index;
372 int blen;
373
374 deb_info("%s %d", __func__, onoff);
375
376 req = 0xBC;
377 value = onoff;
378 index = 0;
379 blen = 0;
380
381 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
382 if (ret != 0)
383 warn("usb out operation failed. (%d)", ret);
384
385 return ret;
386}
387
388/* keys for the enclosed remote control */
389static struct dvb_usb_rc_key az6027_rc_keys[] = {
390 { 0x01, KEY_1 },
391 { 0x02, KEY_2 },
392};
393
394/* remote control stuff (does not work with my box) */
395static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
396{
397 return 0;
398}
399
400/*
401int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
402{
403 u8 v = onoff;
404 return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
405}
406*/
407
408static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
409 int slot,
410 int address)
411{
412 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
413 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
414
415 int ret;
416 u8 req;
417 u16 value;
418 u16 index;
419 int blen;
420 u8 b[12];
421
422 if (slot != 0)
423 return -EINVAL;
424
425 mutex_lock(&state->ca_mutex);
426
427 req = 0xC1;
428 value = address;
429 index = 0;
430 blen = 1;
431
432 ret = az6027_usb_in_op(d, req, value, index, b, blen);
433 if (ret < 0) {
434 warn("usb in operation failed. (%d)", ret);
435 ret = -EINVAL;
436 } else {
437 ret = b[0];
438 }
439
440 mutex_unlock(&state->ca_mutex);
441 return ret;
442}
443
444static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
445 int slot,
446 int address,
447 u8 value)
448{
449 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
450 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
451
452 int ret;
453 u8 req;
454 u16 value1;
455 u16 index;
456 int blen;
457
458 deb_info("%s %d", __func__, slot);
459 if (slot != 0)
460 return -EINVAL;
461
462 mutex_lock(&state->ca_mutex);
463 req = 0xC2;
464 value1 = address;
465 index = value;
466 blen = 0;
467
468 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
469 if (ret != 0)
470 warn("usb out operation failed. (%d)", ret);
471
472 mutex_unlock(&state->ca_mutex);
473 return ret;
474}
475
476static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
477 int slot,
478 u8 address)
479{
480 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
481 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
482
483 int ret;
484 u8 req;
485 u16 value;
486 u16 index;
487 int blen;
488 u8 b[12];
489
490 if (slot != 0)
491 return -EINVAL;
492
493 mutex_lock(&state->ca_mutex);
494
495 req = 0xC3;
496 value = address;
497 index = 0;
498 blen = 2;
499
500 ret = az6027_usb_in_op(d, req, value, index, b, blen);
501 if (ret < 0) {
502 warn("usb in operation failed. (%d)", ret);
503 ret = -EINVAL;
504 } else {
505 if (b[0] == 0)
506 warn("Read CI IO error");
507
508 ret = b[1];
509 deb_info("read cam data = %x from 0x%x", b[1], value);
510 }
511
512 mutex_unlock(&state->ca_mutex);
513 return ret;
514}
515
516static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
517 int slot,
518 u8 address,
519 u8 value)
520{
521 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
522 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
523
524 int ret;
525 u8 req;
526 u16 value1;
527 u16 index;
528 int blen;
529
530 if (slot != 0)
531 return -EINVAL;
532
533 mutex_lock(&state->ca_mutex);
534 req = 0xC4;
535 value1 = address;
536 index = value;
537 blen = 0;
538
539 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
540 if (ret != 0) {
541 warn("usb out operation failed. (%d)", ret);
542 goto failed;
543 }
544
545failed:
546 mutex_unlock(&state->ca_mutex);
547 return ret;
548}
549
550static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
551{
552 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
553
554 int ret;
555 u8 req;
556 u16 value;
557 u16 index;
558 int blen;
559 u8 b[12];
560
561 req = 0xC8;
562 value = 0;
563 index = 0;
564 blen = 1;
565
566 ret = az6027_usb_in_op(d, req, value, index, b, blen);
567 if (ret < 0) {
568 warn("usb in operation failed. (%d)", ret);
569 ret = -EIO;
570 } else{
571 ret = b[0];
572 }
573 return ret;
574}
575
576static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
577{
578 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
579 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
580
581 int ret, i;
582 u8 req;
583 u16 value;
584 u16 index;
585 int blen;
586
587 mutex_lock(&state->ca_mutex);
588
589 req = 0xC6;
590 value = 1;
591 index = 0;
592 blen = 0;
593
594 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
595 if (ret != 0) {
596 warn("usb out operation failed. (%d)", ret);
597 goto failed;
598 }
599
600 msleep(500);
601 req = 0xC6;
602 value = 0;
603 index = 0;
604 blen = 0;
605
606 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
607 if (ret != 0) {
608 warn("usb out operation failed. (%d)", ret);
609 goto failed;
610 }
611
612 for (i = 0; i < 15; i++) {
613 msleep(100);
614
615 if (CI_CamReady(ca, slot)) {
616 deb_info("CAM Ready");
617 break;
618 }
619 }
620 msleep(5000);
621
622failed:
623 mutex_unlock(&state->ca_mutex);
624 return ret;
625}
626
627static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
628{
629 return 0;
630}
631
632static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
633{
634 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
635 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
636
637 int ret;
638 u8 req;
639 u16 value;
640 u16 index;
641 int blen;
642
643 deb_info("%s", __func__);
644 mutex_lock(&state->ca_mutex);
645 req = 0xC7;
646 value = 1;
647 index = 0;
648 blen = 0;
649
650 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
651 if (ret != 0) {
652 warn("usb out operation failed. (%d)", ret);
653 goto failed;
654 }
655
656failed:
657 mutex_unlock(&state->ca_mutex);
658 return ret;
659}
660
661static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
662{
663 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
664 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
665 int ret;
666 u8 req;
667 u16 value;
668 u16 index;
669 int blen;
670 u8 b[12];
671
672 mutex_lock(&state->ca_mutex);
673
674 req = 0xC5;
675 value = 0;
676 index = 0;
677 blen = 1;
678
679 ret = az6027_usb_in_op(d, req, value, index, b, blen);
680 if (ret < 0) {
681 warn("usb in operation failed. (%d)", ret);
682 ret = -EIO;
683 } else
684 ret = 0;
685
686 if (b[0] == 0) {
687 ret = 0;
688
689 } else if (b[0] == 1) {
690 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
691 DVB_CA_EN50221_POLL_CAM_READY;
692 }
693
694 mutex_unlock(&state->ca_mutex);
695 return ret;
696}
697
698
699static void az6027_ci_uninit(struct dvb_usb_device *d)
700{
701 struct az6027_device_state *state;
702
703 deb_info("%s", __func__);
704
705 if (NULL == d)
706 return;
707
708 state = (struct az6027_device_state *)d->priv;
709 if (NULL == state)
710 return;
711
712 if (NULL == state->ca.data)
713 return;
714
715 dvb_ca_en50221_release(&state->ca);
716
717 memset(&state->ca, 0, sizeof(state->ca));
718}
719
720
721static int az6027_ci_init(struct dvb_usb_adapter *a)
722{
723 struct dvb_usb_device *d = a->dev;
724 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
725 int ret;
726
727 deb_info("%s", __func__);
728
729 mutex_init(&state->ca_mutex);
730
731 state->ca.owner = THIS_MODULE;
732 state->ca.read_attribute_mem = az6027_ci_read_attribute_mem;
733 state->ca.write_attribute_mem = az6027_ci_write_attribute_mem;
734 state->ca.read_cam_control = az6027_ci_read_cam_control;
735 state->ca.write_cam_control = az6027_ci_write_cam_control;
736 state->ca.slot_reset = az6027_ci_slot_reset;
737 state->ca.slot_shutdown = az6027_ci_slot_shutdown;
738 state->ca.slot_ts_enable = az6027_ci_slot_ts_enable;
739 state->ca.poll_slot_status = az6027_ci_poll_slot_status;
740 state->ca.data = d;
741
742 ret = dvb_ca_en50221_init(&a->dvb_adap,
743 &state->ca,
744 0, /* flags */
745 1);/* n_slots */
746 if (ret != 0) {
747 err("Cannot initialize CI: Error %d.", ret);
748 memset(&state->ca, 0, sizeof(state->ca));
749 return ret;
750 }
751
752 deb_info("CI initialized.");
753
754 return 0;
755}
756
757/*
758static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
759{
760 az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
761 return 0;
762}
763*/
764
765static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
766{
767
768 u8 buf;
769 int ret;
770 struct dvb_usb_adapter *adap = fe->dvb->priv;
771
772 struct i2c_msg i2c_msg = {
773 .addr = 0x99,
774 .flags = 0,
775 .buf = &buf,
776 .len = 1
777 };
778
779 /*
780 * 2 --18v
781 * 1 --13v
782 * 0 --off
783 */
784 switch (voltage) {
785 case SEC_VOLTAGE_13:
786 buf = 1;
787 ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
788 break;
789
790 case SEC_VOLTAGE_18:
791 buf = 2;
792 ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
793 break;
794
795 case SEC_VOLTAGE_OFF:
796 buf = 0;
797 ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
798 break;
799
800 default:
801 return -EINVAL;
802 }
803 return 0;
804}
805
806
807static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
808{
809 int ret;
810 u8 req;
811 u16 value;
812 u16 index;
813 int blen;
814
815 req = 0xBC;
816 value = 1; /* power on */
817 index = 3;
818 blen = 0;
819
820 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
821 if (ret != 0)
822 return -EIO;
823
824 return 0;
825}
826static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
827{
828 int ret;
829 u8 req;
830 u16 value;
831 u16 index;
832 int blen;
833
834 /* reset demodulator */
835 req = 0xC0;
836 value = 1; /* high */
837 index = 3;
838 blen = 0;
839
840 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
841 if (ret != 0)
842 return -EIO;
843
844 req = 0xC0;
845 value = 0; /* low */
846 index = 3;
847 blen = 0;
848 msleep_interruptible(200);
849
850 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
851 if (ret != 0)
852 return -EIO;
853
854 msleep_interruptible(200);
855
856 req = 0xC0;
857 value = 1; /*high */
858 index = 3;
859 blen = 0;
860
861 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
862 if (ret != 0)
863 return -EIO;
864
865 msleep_interruptible(200);
866 return 0;
867}
868
869static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
870{
871 int ret;
872 u8 req;
873 u16 value;
874 u16 index;
875 int blen;
876
877 /* TS passthrough */
878 req = 0xC7;
879 value = onoff;
880 index = 0;
881 blen = 0;
882
883 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
884 if (ret != 0)
885 return -EIO;
886
887 return 0;
888}
889
890static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
891{
892
893 az6027_frontend_poweron(adap);
894 az6027_frontend_reset(adap);
895
896 deb_info("adap = %p, dev = %p\n", adap, adap->dev);
897 adap->fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
898
899 if (adap->fe) {
900 deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
901 if (stb6100_attach(adap->fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
902 deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
903 adap->fe->ops.set_voltage = az6027_set_voltage;
904 az6027_ci_init(adap);
905 } else {
906 adap->fe = NULL;
907 }
908 } else
909 warn("no front-end attached\n");
910
911 az6027_frontend_tsbypass(adap, 0);
912
913 return 0;
914}
915
916static struct dvb_usb_device_properties az6027_properties;
917
918static void az6027_usb_disconnect(struct usb_interface *intf)
919{
920 struct dvb_usb_device *d = usb_get_intfdata(intf);
921 az6027_ci_uninit(d);
922 dvb_usb_device_exit(intf);
923}
924
925
926static int az6027_usb_probe(struct usb_interface *intf,
927 const struct usb_device_id *id)
928{
929 return dvb_usb_device_init(intf,
930 &az6027_properties,
931 THIS_MODULE,
932 NULL,
933 adapter_nr);
934}
935
936/* I2C */
937static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
938{
939 struct dvb_usb_device *d = i2c_get_adapdata(adap);
940 int i = 0, j = 0, len = 0;
941 int ret;
942 u16 index;
943 u16 value;
944 int length;
945 u8 req;
946 u8 data[256];
947
948 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
949 return -EAGAIN;
950
951 if (num > 2)
952 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
953
954 for (i = 0; i < num; i++) {
955
956 if (msg[i].addr == 0x99) {
957 req = 0xBE;
958 index = 0;
959 value = msg[i].buf[0] & 0x00ff;
960 length = 1;
961 az6027_usb_out_op(d, req, value, index, data, length);
962 }
963
964 if (msg[i].addr == 0xd0) {
965 /* write/read request */
966 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
967 req = 0xB9;
968 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
969 value = msg[i].addr + (msg[i].len << 8);
970 length = msg[i + 1].len + 6;
971 ret = az6027_usb_in_op(d, req, value, index, data, length);
972 len = msg[i + 1].len;
973 for (j = 0; j < len; j++)
974 msg[i + 1].buf[j] = data[j + 5];
975
976 i++;
977 } else {
978
979 if (msg[i].addr == 0xd0) {
980 /* demod 16bit addr */
981 req = 0xBD;
982 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
983 value = msg[i].addr + (2 << 8);
984 length = msg[i].len - 2;
985 len = msg[i].len - 2;
986 for (j = 0; j < len; j++)
987 data[j] = msg[i].buf[j + 2];
988
989 }
990 az6027_usb_out_op(d, req, value, index, data, length);
991 }
992 }
993
994 if (msg[i].addr == 0xc0) {
995 if (msg[i].flags & I2C_M_RD) {
996
997 req = 0xB9;
998 index = 0x0;
999 value = msg[i].addr;
1000 length = msg[i].len + 6;
1001 ret = az6027_usb_in_op(d, req, value, index, data, length);
1002 len = msg[i].len;
1003 for (j = 0; j < len; j++)
1004 msg[i].buf[j] = data[j + 5];
1005
1006 } else {
1007
1008 req = 0xBD;
1009 index = msg[i].buf[0] & 0x00FF;
1010 value = msg[i].addr + (1 << 8);
1011 length = msg[i].len - 1;
1012 len = msg[i].len - 1;
1013
1014 for (j = 0; j < len; j++)
1015 data[j] = msg[i].buf[j + 1];
1016
1017 az6027_usb_out_op(d, req, value, index, data, length);
1018 }
1019 }
1020 }
1021 mutex_unlock(&d->i2c_mutex);
1022
1023 return i;
1024}
1025
1026
1027static u32 az6027_i2c_func(struct i2c_adapter *adapter)
1028{
1029 return I2C_FUNC_I2C;
1030}
1031
1032static struct i2c_algorithm az6027_i2c_algo = {
1033 .master_xfer = az6027_i2c_xfer,
1034 .functionality = az6027_i2c_func,
1035};
1036
1037int az6027_identify_state(struct usb_device *udev,
1038 struct dvb_usb_device_properties *props,
1039 struct dvb_usb_device_description **desc,
1040 int *cold)
1041{
1042 u8 b[16];
1043 s16 ret = usb_control_msg(udev,
1044 usb_rcvctrlpipe(udev, 0),
1045 0xb7,
1046 USB_TYPE_VENDOR | USB_DIR_IN,
1047 6,
1048 0,
1049 b,
1050 6,
1051 USB_CTRL_GET_TIMEOUT);
1052
1053 *cold = ret <= 0;
1054
1055 deb_info("cold: %d\n", *cold);
1056 return 0;
1057}
1058
1059
1060static struct usb_device_id az6027_usb_table[] = {
1061 { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
1062 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI) },
1063 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI) },
1064 { },
1065};
1066
1067MODULE_DEVICE_TABLE(usb, az6027_usb_table);
1068
1069static struct dvb_usb_device_properties az6027_properties = {
1070 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1071 .usb_ctrl = CYPRESS_FX2,
1072 .firmware = "dvb-usb-az6027-03.fw",
1073 .no_reconnect = 1,
1074
1075 .size_of_priv = sizeof(struct az6027_device_state),
1076 .identify_state = az6027_identify_state,
1077 .num_adapters = 1,
1078 .adapter = {
1079 {
1080 .streaming_ctrl = az6027_streaming_ctrl,
1081 .frontend_attach = az6027_frontend_attach,
1082
1083 /* parameter for the MPEG2-data transfer */
1084 .stream = {
1085 .type = USB_BULK,
1086 .count = 10,
1087 .endpoint = 0x02,
1088 .u = {
1089 .bulk = {
1090 .buffersize = 4096,
1091 }
1092 }
1093 },
1094 }
1095 },
1096/*
1097 .power_ctrl = az6027_power_ctrl,
1098 .read_mac_address = az6027_read_mac_addr,
1099 */
1100 .rc_key_map = az6027_rc_keys,
1101 .rc_key_map_size = ARRAY_SIZE(az6027_rc_keys),
1102 .rc_interval = 400,
1103 .rc_query = az6027_rc_query,
1104 .i2c_algo = &az6027_i2c_algo,
1105
1106 .num_device_descs = 1,
1107 .devices = {
1108 {
1109 .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
1110 .cold_ids = { &az6027_usb_table[0], NULL },
1111 .warm_ids = { NULL },
1112 },
1113 { NULL },
1114 }
1115};
1116
1117/* usb specific object needed to register this driver with the usb subsystem */
1118static struct usb_driver az6027_usb_driver = {
1119 .name = "dvb_usb_az6027",
1120 .probe = az6027_usb_probe,
1121 .disconnect = az6027_usb_disconnect,
1122 .id_table = az6027_usb_table,
1123};
1124
1125/* module stuff */
1126static int __init az6027_usb_module_init(void)
1127{
1128 int result;
1129
1130 result = usb_register(&az6027_usb_driver);
1131 if (result) {
1132 err("usb_register failed. (%d)", result);
1133 return result;
1134 }
1135
1136 return 0;
1137}
1138
1139static void __exit az6027_usb_module_exit(void)
1140{
1141 /* deregister this driver from the USB subsystem */
1142 usb_deregister(&az6027_usb_driver);
1143}
1144
1145module_init(az6027_usb_module_init);
1146module_exit(az6027_usb_module_exit);
1147
1148MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
1149MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
1150MODULE_VERSION("1.0");
1151MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/az6027.h b/drivers/media/dvb/dvb-usb/az6027.h
new file mode 100644
index 000000000000..f3afe17f3f3d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/az6027.h
@@ -0,0 +1,14 @@
1#ifndef _DVB_USB_VP6027_H_
2#define _DVB_USB_VP6027_H_
3
4#define DVB_USB_LOG_PREFIX "az6027"
5#include "dvb-usb.h"
6
7
8extern int dvb_usb_az6027_debug;
9#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
10#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
11#define deb_rc(args...) dprintk(dvb_usb_az6027_debug, 0x04, args)
12#define deb_fe(args...) dprintk(dvb_usb_az6027_debug, 0x08, args)
13
14#endif
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 05fb28e9c69e..a7b8405c291e 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -1184,6 +1184,9 @@ static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1184 .osc_clk_freq = 30400, /* in kHz */ 1184 .osc_clk_freq = 30400, /* in kHz */
1185 .if_freq = 0, /* zero IF */ 1185 .if_freq = 0, /* zero IF */
1186 .zif_swap_iq = 1, 1186 .zif_swap_iq = 1,
1187 .agc_min = 0x2E,
1188 .agc_max = 0x90,
1189 .agc_hold_loop = 0,
1187}; 1190};
1188 1191
1189static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) 1192static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 495a90577c5f..83fc24a6c31a 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -42,7 +42,6 @@ struct dib0700_state {
42 u16 mt2060_if1[2]; 42 u16 mt2060_if1[2];
43 u8 rc_toggle; 43 u8 rc_toggle;
44 u8 rc_counter; 44 u8 rc_counter;
45 u8 rc_func_version;
46 u8 is_dib7000pc; 45 u8 is_dib7000pc;
47 u8 fw_use_new_i2c_api; 46 u8 fw_use_new_i2c_api;
48 u8 disable_streaming_master_mode; 47 u8 disable_streaming_master_mode;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 0d3c9a9a33be..4f961d2d1817 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -471,14 +471,209 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
471 return dib0700_ctrl_wr(adap->dev, b, 4); 471 return dib0700_ctrl_wr(adap->dev, b, 4);
472} 472}
473 473
474/* Number of keypresses to ignore before start repeating */
475#define RC_REPEAT_DELAY_V1_20 10
476
477/* This is the structure of the RC response packet starting in firmware 1.20 */
478struct dib0700_rc_response {
479 u8 report_id;
480 u8 data_state;
481 u16 system;
482 u8 data;
483 u8 not_data;
484};
485#define RC_MSG_SIZE_V1_20 6
486
487static void dib0700_rc_urb_completion(struct urb *purb)
488{
489 struct dvb_usb_device *d = purb->context;
490 struct dvb_usb_rc_key *keymap;
491 struct dib0700_state *st;
492 struct dib0700_rc_response poll_reply;
493 u8 *buf;
494 int found = 0;
495 u32 event;
496 int state;
497 int i;
498
499 deb_info("%s()\n", __func__);
500 if (d == NULL)
501 return;
502
503 if (d->rc_input_dev == NULL) {
504 /* This will occur if disable_rc_polling=1 */
505 usb_free_urb(purb);
506 return;
507 }
508
509 keymap = d->props.rc_key_map;
510 st = d->priv;
511 buf = (u8 *)purb->transfer_buffer;
512
513 if (purb->status < 0) {
514 deb_info("discontinuing polling\n");
515 usb_free_urb(purb);
516 return;
517 }
518
519 if (purb->actual_length != RC_MSG_SIZE_V1_20) {
520 deb_info("malformed rc msg size=%d\n", purb->actual_length);
521 goto resubmit;
522 }
523
524 /* Set initial results in case we exit the function early */
525 event = 0;
526 state = REMOTE_NO_KEY_PRESSED;
527
528 deb_data("IR raw %02X %02X %02X %02X %02X %02X (len %d)\n", buf[0],
529 buf[1], buf[2], buf[3], buf[4], buf[5], purb->actual_length);
530
531 switch (dvb_usb_dib0700_ir_proto) {
532 case 0:
533 /* NEC Protocol */
534 poll_reply.report_id = 0;
535 poll_reply.data_state = 1;
536 poll_reply.system = buf[2];
537 poll_reply.data = buf[4];
538 poll_reply.not_data = buf[5];
539
540 /* NEC protocol sends repeat code as 0 0 0 FF */
541 if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
542 && (poll_reply.not_data == 0xff)) {
543 poll_reply.data_state = 2;
544 break;
545 }
546 break;
547 default:
548 /* RC5 Protocol */
549 poll_reply.report_id = buf[0];
550 poll_reply.data_state = buf[1];
551 poll_reply.system = (buf[2] << 8) | buf[3];
552 poll_reply.data = buf[4];
553 poll_reply.not_data = buf[5];
554 break;
555 }
556
557 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
558 /* Key failed integrity check */
559 err("key failed integrity check: %04x %02x %02x",
560 poll_reply.system,
561 poll_reply.data, poll_reply.not_data);
562 goto resubmit;
563 }
564
565 deb_data("rid=%02x ds=%02x sm=%04x d=%02x nd=%02x\n",
566 poll_reply.report_id, poll_reply.data_state,
567 poll_reply.system, poll_reply.data, poll_reply.not_data);
568
569 /* Find the key in the map */
570 for (i = 0; i < d->props.rc_key_map_size; i++) {
571 if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
572 rc5_data(&keymap[i]) == poll_reply.data) {
573 event = keymap[i].event;
574 found = 1;
575 break;
576 }
577 }
578
579 if (found == 0) {
580 err("Unknown remote controller key: %04x %02x %02x",
581 poll_reply.system, poll_reply.data, poll_reply.not_data);
582 d->last_event = 0;
583 goto resubmit;
584 }
585
586 if (poll_reply.data_state == 1) {
587 /* New key hit */
588 st->rc_counter = 0;
589 event = keymap[i].event;
590 state = REMOTE_KEY_PRESSED;
591 d->last_event = keymap[i].event;
592 } else if (poll_reply.data_state == 2) {
593 /* Key repeated */
594 st->rc_counter++;
595
596 /* prevents unwanted double hits */
597 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
598 event = d->last_event;
599 state = REMOTE_KEY_PRESSED;
600 st->rc_counter = RC_REPEAT_DELAY_V1_20;
601 }
602 } else {
603 err("Unknown data state [%d]", poll_reply.data_state);
604 }
605
606 switch (state) {
607 case REMOTE_NO_KEY_PRESSED:
608 break;
609 case REMOTE_KEY_PRESSED:
610 deb_info("key pressed\n");
611 d->last_event = event;
612 case REMOTE_KEY_REPEAT:
613 deb_info("key repeated\n");
614 input_event(d->rc_input_dev, EV_KEY, event, 1);
615 input_sync(d->rc_input_dev);
616 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
617 input_sync(d->rc_input_dev);
618 break;
619 default:
620 break;
621 }
622
623resubmit:
624 /* Clean the buffer before we requeue */
625 memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
626
627 /* Requeue URB */
628 usb_submit_urb(purb, GFP_ATOMIC);
629}
630
474int dib0700_rc_setup(struct dvb_usb_device *d) 631int dib0700_rc_setup(struct dvb_usb_device *d)
475{ 632{
633 struct dib0700_state *st = d->priv;
476 u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; 634 u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
477 int i = dib0700_ctrl_wr(d, rc_setup, 3); 635 struct urb *purb;
636 int ret;
637 int i;
638
639 if (d->props.rc_key_map == NULL)
640 return 0;
641
642 /* Set the IR mode */
643 i = dib0700_ctrl_wr(d, rc_setup, 3);
478 if (i<0) { 644 if (i<0) {
479 err("ir protocol setup failed"); 645 err("ir protocol setup failed");
480 return -1; 646 return -1;
481 } 647 }
648
649 if (st->fw_version < 0x10200)
650 return 0;
651
652 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
653 purb = usb_alloc_urb(0, GFP_KERNEL);
654 if (purb == NULL) {
655 err("rc usb alloc urb failed\n");
656 return -1;
657 }
658
659 purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
660 if (purb->transfer_buffer == NULL) {
661 err("rc kzalloc failed\n");
662 usb_free_urb(purb);
663 return -1;
664 }
665
666 purb->status = -EINPROGRESS;
667 usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
668 purb->transfer_buffer, RC_MSG_SIZE_V1_20,
669 dib0700_rc_urb_completion, d);
670
671 ret = usb_submit_urb(purb, GFP_ATOMIC);
672 if (ret != 0) {
673 err("rc submit urb failed\n");
674 return -1;
675 }
676
482 return 0; 677 return 0;
483} 678}
484 679
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 44972d01bbd0..34eab05afc6c 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -472,20 +472,25 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
472 472
473/* Number of keypresses to ignore before start repeating */ 473/* Number of keypresses to ignore before start repeating */
474#define RC_REPEAT_DELAY 6 474#define RC_REPEAT_DELAY 6
475#define RC_REPEAT_DELAY_V1_20 10
476 475
477 476static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
478
479/* Used by firmware versions < 1.20 (deprecated) */
480static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
481 int *state)
482{ 477{
483 u8 key[4]; 478 u8 key[4];
484 int i; 479 int i;
485 struct dvb_usb_rc_key *keymap = d->props.rc_key_map; 480 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
486 struct dib0700_state *st = d->priv; 481 struct dib0700_state *st = d->priv;
482
487 *event = 0; 483 *event = 0;
488 *state = REMOTE_NO_KEY_PRESSED; 484 *state = REMOTE_NO_KEY_PRESSED;
485
486 if (st->fw_version >= 0x10200) {
487 /* For 1.20 firmware , We need to keep the RC polling
488 callback so we can reuse the input device setup in
489 dvb-usb-remote.c. However, the actual work is being done
490 in the bulk URB completion handler. */
491 return 0;
492 }
493
489 i=dib0700_ctrl_rd(d,rc_request,2,key,4); 494 i=dib0700_ctrl_rd(d,rc_request,2,key,4);
490 if (i<=0) { 495 if (i<=0) {
491 err("RC Query Failed"); 496 err("RC Query Failed");
@@ -557,149 +562,6 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
557 return 0; 562 return 0;
558} 563}
559 564
560/* This is the structure of the RC response packet starting in firmware 1.20 */
561struct dib0700_rc_response {
562 u8 report_id;
563 u8 data_state;
564 u16 system;
565 u8 data;
566 u8 not_data;
567};
568
569/* This supports the new IR response format for firmware v1.20 */
570static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
571 int *state)
572{
573 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
574 struct dib0700_state *st = d->priv;
575 struct dib0700_rc_response poll_reply;
576 u8 buf[6];
577 int i;
578 int status;
579 int actlen;
580 int found = 0;
581
582 /* Set initial results in case we exit the function early */
583 *event = 0;
584 *state = REMOTE_NO_KEY_PRESSED;
585
586 /* Firmware v1.20 provides RC data via bulk endpoint 1 */
587 status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
588 sizeof(buf), &actlen, 50);
589 if (status < 0) {
590 /* No data available (meaning no key press) */
591 return 0;
592 }
593
594
595 switch (dvb_usb_dib0700_ir_proto) {
596 case 0:
597 poll_reply.report_id = 0;
598 poll_reply.data_state = 1;
599 poll_reply.system = buf[2];
600 poll_reply.data = buf[4];
601 poll_reply.not_data = buf[5];
602
603 /* NEC protocol sends repeat code as 0 0 0 FF */
604 if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00)
605 && (poll_reply.not_data == 0xff)) {
606 poll_reply.data_state = 2;
607 break;
608 }
609 break;
610 default:
611 if (actlen != sizeof(buf)) {
612 /* We didn't get back the 6 byte message we expected */
613 err("Unexpected RC response size [%d]", actlen);
614 return -1;
615 }
616
617 poll_reply.report_id = buf[0];
618 poll_reply.data_state = buf[1];
619 poll_reply.system = (buf[2] << 8) | buf[3];
620 poll_reply.data = buf[4];
621 poll_reply.not_data = buf[5];
622
623 break;
624 }
625
626 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
627 /* Key failed integrity check */
628 err("key failed integrity check: %04x %02x %02x",
629 poll_reply.system,
630 poll_reply.data, poll_reply.not_data);
631 return -1;
632 }
633
634
635 /* Find the key in the map */
636 for (i = 0; i < d->props.rc_key_map_size; i++) {
637 if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
638 rc5_data(&keymap[i]) == poll_reply.data) {
639 *event = keymap[i].event;
640 found = 1;
641 break;
642 }
643 }
644
645 if (found == 0) {
646 err("Unknown remote controller key: %04x %02x %02x",
647 poll_reply.system,
648 poll_reply.data, poll_reply.not_data);
649 d->last_event = 0;
650 return 0;
651 }
652
653 if (poll_reply.data_state == 1) {
654 /* New key hit */
655 st->rc_counter = 0;
656 *event = keymap[i].event;
657 *state = REMOTE_KEY_PRESSED;
658 d->last_event = keymap[i].event;
659 } else if (poll_reply.data_state == 2) {
660 /* Key repeated */
661 st->rc_counter++;
662
663 /* prevents unwanted double hits */
664 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
665 *event = d->last_event;
666 *state = REMOTE_KEY_PRESSED;
667 st->rc_counter = RC_REPEAT_DELAY_V1_20;
668 }
669 } else {
670 err("Unknown data state [%d]", poll_reply.data_state);
671 }
672
673 return 0;
674}
675
676static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
677{
678 struct dib0700_state *st = d->priv;
679
680 /* Because some people may have improperly named firmware files,
681 let's figure out whether to use the new firmware call or the legacy
682 call based on the firmware version embedded in the file */
683 if (st->rc_func_version == 0) {
684 u32 hwver, romver, ramver, fwtype;
685 int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
686 &fwtype);
687 if (ret < 0) {
688 err("Could not determine version info");
689 return -1;
690 }
691 if (ramver < 0x10200)
692 st->rc_func_version = 1;
693 else
694 st->rc_func_version = 2;
695 }
696
697 if (st->rc_func_version == 2)
698 return dib0700_rc_query_v1_20(d, event, state);
699 else
700 return dib0700_rc_query_legacy(d, event, state);
701}
702
703static struct dvb_usb_rc_key dib0700_rc_keys[] = { 565static struct dvb_usb_rc_key dib0700_rc_keys[] = {
704 /* Key codes for the tiny Pinnacle remote*/ 566 /* Key codes for the tiny Pinnacle remote*/
705 { 0x0700, KEY_MUTE }, 567 { 0x0700, KEY_MUTE },
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index bc3581d58ced..ae8b57acfe05 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -64,6 +64,8 @@
64#define USB_VID_HUMAX_COEX 0x10b9 64#define USB_VID_HUMAX_COEX 0x10b9
65#define USB_VID_774 0x7a69 65#define USB_VID_774 0x7a69
66#define USB_VID_EVOLUTEPC 0x1e59 66#define USB_VID_EVOLUTEPC 0x1e59
67#define USB_VID_AZUREWAVE 0x13d3
68#define USB_VID_TECHNISAT 0x14f7
67 69
68/* Product IDs */ 70/* Product IDs */
69#define USB_PID_ADSTECH_USB2_COLD 0xa333 71#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -138,6 +140,7 @@
138#define USB_PID_TWINHAN_VP7021_COLD 0x3207 140#define USB_PID_TWINHAN_VP7021_COLD 0x3207
139#define USB_PID_TWINHAN_VP7021_WARM 0x3208 141#define USB_PID_TWINHAN_VP7021_WARM 0x3208
140#define USB_PID_TINYTWIN 0x3226 142#define USB_PID_TINYTWIN 0x3226
143#define USB_PID_TINYTWIN_2 0xe402
141#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 144#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
142#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 145#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
143#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 146#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
@@ -209,6 +212,7 @@
209#define USB_PID_PINNACLE_PCTV71E 0x022b 212#define USB_PID_PINNACLE_PCTV71E 0x022b
210#define USB_PID_PINNACLE_PCTV72E 0x0236 213#define USB_PID_PINNACLE_PCTV72E 0x0236
211#define USB_PID_PINNACLE_PCTV73E 0x0237 214#define USB_PID_PINNACLE_PCTV73E 0x0237
215#define USB_PID_PINNACLE_PCTV310E 0x3211
212#define USB_PID_PINNACLE_PCTV801E 0x023a 216#define USB_PID_PINNACLE_PCTV801E 0x023a
213#define USB_PID_PINNACLE_PCTV801E_SE 0x023b 217#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
214#define USB_PID_PINNACLE_PCTV73A 0x0243 218#define USB_PID_PINNACLE_PCTV73A 0x0243
@@ -248,6 +252,7 @@
248#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361 252#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361
249#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 253#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6
250#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 254#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
255#define USB_PID_WINFAST_DTV2000DS 0x6a04
251#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 256#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
252#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 257#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
253#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 258#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
@@ -290,5 +295,7 @@
290#define USB_PID_FRIIO_WHITE 0x0001 295#define USB_PID_FRIIO_WHITE 0x0001
291#define USB_PID_TVWAY_PLUS 0x0002 296#define USB_PID_TVWAY_PLUS 0x0002
292#define USB_PID_SVEON_STV20 0xe39d 297#define USB_PID_SVEON_STV20 0xe39d
293 298#define USB_PID_AZUREWAVE_AZ6027 0x3275
299#define USB_PID_TERRATEC_DVBS2CI 0x3275
300#define USB_PID_TECHNISAT_USB2_HDCI 0x0002
294#endif 301#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index e331db8c77b2..5d91f70d2d2d 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -243,7 +243,7 @@ int dvb_usb_device_init(struct usb_interface *intf,
243 d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); 243 d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
244 if (d == NULL) { 244 if (d == NULL) {
245 err("no memory for 'struct dvb_usb_device'"); 245 err("no memory for 'struct dvb_usb_device'");
246 return ret; 246 return -ENOMEM;
247 } 247 }
248 248
249 d->udev = udev; 249 d->udev = udev;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 6b5ded9e7d5d..a03ef7efec9a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -107,6 +107,7 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
107 case REMOTE_KEY_REPEAT: 107 case REMOTE_KEY_REPEAT:
108 deb_rc("key repeated\n"); 108 deb_rc("key repeated\n");
109 input_event(d->rc_input_dev, EV_KEY, event, 1); 109 input_event(d->rc_input_dev, EV_KEY, event, 1);
110 input_sync(d->rc_input_dev);
110 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); 111 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
111 input_sync(d->rc_input_dev); 112 input_sync(d->rc_input_dev);
112 break; 113 break;
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 64132c0cf80d..accc65509b07 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,6 +1,7 @@
1/* DVB USB framework compliant Linux driver for the 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3* TeVii S600, S630, S650 Cards 3* TeVii S600, S630, S650,
4* Prof 1100, 7500 Cards
4* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) 5* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
5* 6*
6* This program is free software; you can redistribute it and/or modify it 7* This program is free software; you can redistribute it and/or modify it
@@ -469,11 +470,13 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
469 int num) 470 int num)
470{ 471{
471 struct dvb_usb_device *d = i2c_get_adapdata(adap); 472 struct dvb_usb_device *d = i2c_get_adapdata(adap);
473 struct usb_device *udev;
472 int ret = 0; 474 int ret = 0;
473 int len, i, j; 475 int len, i, j;
474 476
475 if (!d) 477 if (!d)
476 return -ENODEV; 478 return -ENODEV;
479 udev = d->udev;
477 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 480 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
478 return -EAGAIN; 481 return -EAGAIN;
479 482
@@ -488,8 +491,13 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
488 } 491 }
489 case (DW2102_VOLTAGE_CTRL): { 492 case (DW2102_VOLTAGE_CTRL): {
490 u8 obuf[2]; 493 u8 obuf[2];
494
495 obuf[0] = 1;
496 obuf[1] = msg[j].buf[1];/* off-on */
497 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
498 obuf, 2, DW210X_WRITE_MSG);
491 obuf[0] = 3; 499 obuf[0] = 3;
492 obuf[1] = msg[j].buf[0]; 500 obuf[1] = msg[j].buf[0];/* 13v-18v */
493 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, 501 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
494 obuf, 2, DW210X_WRITE_MSG); 502 obuf, 2, DW210X_WRITE_MSG);
495 break; 503 break;
@@ -527,6 +535,17 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
527 i += 16; 535 i += 16;
528 len -= 16; 536 len -= 16;
529 } while (len > 0); 537 } while (len > 0);
538 } else if ((udev->descriptor.idProduct == 0x7500)
539 && (j < (num - 1))) {
540 /* write register addr before read */
541 u8 obuf[msg[j].len + 2];
542 obuf[0] = msg[j + 1].len;
543 obuf[1] = (msg[j].addr << 1);
544 memcpy(obuf + 2, msg[j].buf, msg[j].len);
545 ret = dw210x_op_rw(d->udev, 0x92, 0, 0,
546 obuf, msg[j].len + 2,
547 DW210X_WRITE_MSG);
548 break;
530 } else { 549 } else {
531 /* write registers */ 550 /* write registers */
532 u8 obuf[msg[j].len + 2]; 551 u8 obuf[msg[j].len + 2];
@@ -651,18 +670,25 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
651 670
652static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 671static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
653{ 672{
654 static u8 command_13v[1] = {0x00}; 673 static u8 command_13v[] = {0x00, 0x01};
655 static u8 command_18v[1] = {0x01}; 674 static u8 command_18v[] = {0x01, 0x01};
656 struct i2c_msg msg[] = { 675 static u8 command_off[] = {0x00, 0x00};
657 {.addr = DW2102_VOLTAGE_CTRL, .flags = 0, 676 struct i2c_msg msg = {
658 .buf = command_13v, .len = 1}, 677 .addr = DW2102_VOLTAGE_CTRL,
678 .flags = 0,
679 .buf = command_off,
680 .len = 2,
659 }; 681 };
660 682
661 struct dvb_usb_adapter *udev_adap = 683 struct dvb_usb_adapter *udev_adap =
662 (struct dvb_usb_adapter *)(fe->dvb->priv); 684 (struct dvb_usb_adapter *)(fe->dvb->priv);
663 if (voltage == SEC_VOLTAGE_18) 685 if (voltage == SEC_VOLTAGE_18)
664 msg[0].buf = command_18v; 686 msg.buf = command_18v;
665 i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); 687 else if (voltage == SEC_VOLTAGE_13)
688 msg.buf = command_13v;
689
690 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
691
666 return 0; 692 return 0;
667} 693}
668 694
@@ -735,6 +761,18 @@ static struct stv6110_config dw2104_stv6110_config = {
735 .clk_div = 1, 761 .clk_div = 1,
736}; 762};
737 763
764static struct stv0900_config prof_7500_stv0900_config = {
765 .demod_address = 0x6a,
766 .demod_mode = 0,
767 .xtal = 27000000,
768 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
769 .diseqc_mode = 2,/* 2/3 PWM */
770 .tun1_maddress = 0,/* 0x60 */
771 .tun1_adc = 0,/* 2 Vpp */
772 .path1_mode = 3,
773 .tun1_type = 3,
774};
775
738static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 776static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
739{ 777{
740 struct dvb_tuner_ops *tuner_ops = NULL; 778 struct dvb_tuner_ops *tuner_ops = NULL;
@@ -882,6 +920,19 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
882 return -EIO; 920 return -EIO;
883} 921}
884 922
923static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
924{
925 d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
926 &d->dev->i2c_adap, 0);
927 if (d->fe == NULL)
928 return -EIO;
929 d->fe->ops.set_voltage = dw210x_set_voltage;
930
931 info("Attached STV0900+STB6100A!\n");
932
933 return 0;
934}
935
885static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 936static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
886{ 937{
887 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 938 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -1073,6 +1124,7 @@ static struct usb_device_id dw2102_table[] = {
1073 {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, 1124 {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1074 {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, 1125 {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1075 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, 1126 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1127 {USB_DEVICE(0x3034, 0x7500)},
1076 { } 1128 { }
1077}; 1129};
1078 1130
@@ -1387,9 +1439,30 @@ static struct dvb_usb_device_properties s6x0_properties = {
1387 } 1439 }
1388}; 1440};
1389 1441
1442struct dvb_usb_device_properties *p7500;
1443static struct dvb_usb_device_description d7500 = {
1444 "Prof 7500 USB DVB-S2",
1445 {&dw2102_table[9], NULL},
1446 {NULL},
1447};
1448
1390static int dw2102_probe(struct usb_interface *intf, 1449static int dw2102_probe(struct usb_interface *intf,
1391 const struct usb_device_id *id) 1450 const struct usb_device_id *id)
1392{ 1451{
1452
1453 p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1454 if (!p7500)
1455 return -ENOMEM;
1456 /* copy default structure */
1457 memcpy(p7500, &s6x0_properties,
1458 sizeof(struct dvb_usb_device_properties));
1459 /* fill only different fields */
1460 p7500->firmware = "dvb-usb-p7500.fw";
1461 p7500->devices[0] = d7500;
1462 p7500->rc_key_map = tbs_rc_keys;
1463 p7500->rc_key_map_size = ARRAY_SIZE(tbs_rc_keys);
1464 p7500->adapter->frontend_attach = prof_7500_frontend_attach;
1465
1393 if (0 == dvb_usb_device_init(intf, &dw2102_properties, 1466 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
1394 THIS_MODULE, NULL, adapter_nr) || 1467 THIS_MODULE, NULL, adapter_nr) ||
1395 0 == dvb_usb_device_init(intf, &dw2104_properties, 1468 0 == dvb_usb_device_init(intf, &dw2104_properties,
@@ -1397,6 +1470,8 @@ static int dw2102_probe(struct usb_interface *intf,
1397 0 == dvb_usb_device_init(intf, &dw3101_properties, 1470 0 == dvb_usb_device_init(intf, &dw3101_properties,
1398 THIS_MODULE, NULL, adapter_nr) || 1471 THIS_MODULE, NULL, adapter_nr) ||
1399 0 == dvb_usb_device_init(intf, &s6x0_properties, 1472 0 == dvb_usb_device_init(intf, &s6x0_properties,
1473 THIS_MODULE, NULL, adapter_nr) ||
1474 0 == dvb_usb_device_init(intf, p7500,
1400 THIS_MODULE, NULL, adapter_nr)) 1475 THIS_MODULE, NULL, adapter_nr))
1401 return 0; 1476 return 0;
1402 1477
@@ -1431,6 +1506,6 @@ MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1431MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," 1506MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1432 " DVB-C 3101 USB2.0," 1507 " DVB-C 3101 USB2.0,"
1433 " TeVii S600, S630, S650, S660 USB2.0," 1508 " TeVii S600, S630, S650, S660 USB2.0,"
1434 " Prof 1100 USB2.0 devices"); 1509 " Prof 1100, 7500 USB2.0 devices");
1435MODULE_VERSION("0.1"); 1510MODULE_VERSION("0.1");
1436MODULE_LICENSE("GPL"); 1511MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
index ebb7b9fd115b..d14bd227b502 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -366,7 +366,7 @@ static u8 init_code[][2] = {
366 {0x76, 0x0C}, 366 {0x76, 0x0C},
367}; 367};
368 368
369const static int init_code_len = sizeof(init_code) / sizeof(u8[2]); 369static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
370 370
371static int jdvbt90502_init(struct dvb_frontend *fe) 371static int jdvbt90502_init(struct dvb_frontend *fe)
372{ 372{
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index ef9b7bed13ff..737ffa36ac9c 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -16,6 +16,9 @@
16#include "qt1010.h" 16#include "qt1010.h"
17#include "tda1004x.h" 17#include "tda1004x.h"
18#include "tda827x.h" 18#include "tda827x.h"
19
20#include <media/tuner.h>
21#include "tuner-simple.h"
19#include <asm/unaligned.h> 22#include <asm/unaligned.h>
20 23
21/* debug */ 24/* debug */
@@ -158,11 +161,14 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
158 161
159 case 0x93: 162 case 0x93:
160 case 0x92: 163 case 0x92:
164 case 0x83: /* pinnacle PCTV310e */
165 case 0x82:
161 m->rep_count = 0; 166 m->rep_count = 0;
162 *state = REMOTE_KEY_PRESSED; 167 *state = REMOTE_KEY_PRESSED;
163 goto unlock; 168 goto unlock;
164 169
165 case 0x91: 170 case 0x91:
171 case 0x81: /* pinnacle PCTV310e */
166 /* prevent immediate auto-repeat */ 172 /* prevent immediate auto-repeat */
167 if (++m->rep_count > 2) 173 if (++m->rep_count > 2)
168 *state = REMOTE_KEY_REPEAT; 174 *state = REMOTE_KEY_REPEAT;
@@ -546,6 +552,14 @@ static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
546 return 0; 552 return 0;
547} 553}
548 554
555static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
556{
557 dvb_attach(simple_tuner_attach, adap->fe,
558 &adap->dev->i2c_adap, 0x61,
559 TUNER_PHILIPS_FMD1216ME_MK3);
560 return 0;
561}
562
549/* device-specific initialization */ 563/* device-specific initialization */
550static struct m920x_inits megasky_rc_init [] = { 564static struct m920x_inits megasky_rc_init [] = {
551 { M9206_RC_INIT2, 0xa8 }, 565 { M9206_RC_INIT2, 0xa8 },
@@ -562,6 +576,18 @@ static struct m920x_inits tvwalkertwin_rc_init [] = {
562 { } /* terminating entry */ 576 { } /* terminating entry */
563}; 577};
564 578
579static struct m920x_inits pinnacle310e_init[] = {
580 /* without these the tuner don't work */
581 { 0xff20, 0x9b },
582 { 0xff22, 0x70 },
583
584 /* rc settings */
585 { 0xff50, 0x80 },
586 { M9206_RC_INIT1, 0x00 },
587 { M9206_RC_INIT2, 0xff },
588 { } /* terminating entry */
589};
590
565/* ir keymaps */ 591/* ir keymaps */
566static struct dvb_usb_rc_key megasky_rc_keys [] = { 592static struct dvb_usb_rc_key megasky_rc_keys [] = {
567 { 0x0012, KEY_POWER }, 593 { 0x0012, KEY_POWER },
@@ -602,11 +628,68 @@ static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
602 { 0x001e, KEY_VOLUMEUP }, 628 { 0x001e, KEY_VOLUMEUP },
603}; 629};
604 630
631static struct dvb_usb_rc_key pinnacle310e_rc_keys[] = {
632 { 0x16, KEY_POWER },
633 { 0x17, KEY_FAVORITES },
634 { 0x0f, KEY_TEXT },
635 { 0x48, KEY_MEDIA }, /* preview */
636 { 0x1c, KEY_EPG },
637 { 0x04, KEY_LIST }, /* record list */
638 { 0x03, KEY_1 },
639 { 0x01, KEY_2 },
640 { 0x06, KEY_3 },
641 { 0x09, KEY_4 },
642 { 0x1d, KEY_5 },
643 { 0x1f, KEY_6 },
644 { 0x0d, KEY_7 },
645 { 0x19, KEY_8 },
646 { 0x1b, KEY_9 },
647 { 0x15, KEY_0 },
648 { 0x0c, KEY_CANCEL },
649 { 0x4a, KEY_CLEAR },
650 { 0x13, KEY_BACK },
651 { 0x00, KEY_TAB },
652 { 0x4b, KEY_UP },
653 { 0x4e, KEY_LEFT },
654 { 0x52, KEY_RIGHT },
655 { 0x51, KEY_DOWN },
656 { 0x4f, KEY_ENTER }, /* could also be KEY_OK */
657 { 0x1e, KEY_VOLUMEUP },
658 { 0x0a, KEY_VOLUMEDOWN },
659 { 0x05, KEY_CHANNELUP },
660 { 0x02, KEY_CHANNELDOWN },
661 { 0x11, KEY_RECORD },
662 { 0x14, KEY_PLAY },
663 { 0x4c, KEY_PAUSE },
664 { 0x1a, KEY_STOP },
665 { 0x40, KEY_REWIND },
666 { 0x12, KEY_FASTFORWARD },
667 { 0x41, KEY_PREVIOUSSONG }, /* Replay */
668 { 0x42, KEY_NEXTSONG }, /* Skip */
669 { 0x54, KEY_CAMERA }, /* Capture */
670/* { 0x50, KEY_SAP }, */ /* Sap */
671 { 0x47, KEY_CYCLEWINDOWS }, /* Pip */
672 { 0x4d, KEY_SCREEN }, /* FullScreen */
673 { 0x08, KEY_SUBTITLE },
674 { 0x0e, KEY_MUTE },
675/* { 0x49, KEY_LR }, */ /* L/R */
676 { 0x07, KEY_SLEEP }, /* Hibernate */
677 { 0x08, KEY_MEDIA }, /* A/V */
678 { 0x0e, KEY_MENU }, /* Recall */
679 { 0x45, KEY_ZOOMIN },
680 { 0x46, KEY_ZOOMOUT },
681 { 0x18, KEY_TV }, /* Red */
682 { 0x53, KEY_VCR }, /* Green */
683 { 0x5e, KEY_SAT }, /* Yellow */
684 { 0x5f, KEY_PLAYER }, /* Blue */
685};
686
605/* DVB USB Driver stuff */ 687/* DVB USB Driver stuff */
606static struct dvb_usb_device_properties megasky_properties; 688static struct dvb_usb_device_properties megasky_properties;
607static struct dvb_usb_device_properties digivox_mini_ii_properties; 689static struct dvb_usb_device_properties digivox_mini_ii_properties;
608static struct dvb_usb_device_properties tvwalkertwin_properties; 690static struct dvb_usb_device_properties tvwalkertwin_properties;
609static struct dvb_usb_device_properties dposh_properties; 691static struct dvb_usb_device_properties dposh_properties;
692static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
610 693
611static int m920x_probe(struct usb_interface *intf, 694static int m920x_probe(struct usb_interface *intf,
612 const struct usb_device_id *id) 695 const struct usb_device_id *id)
@@ -652,6 +735,13 @@ static int m920x_probe(struct usb_interface *intf,
652 goto found; 735 goto found;
653 } 736 }
654 737
738 ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
739 THIS_MODULE, &d, adapter_nr);
740 if (ret == 0) {
741 rc_init_seq = pinnacle310e_init;
742 goto found;
743 }
744
655 return ret; 745 return ret;
656 } else { 746 } else {
657 /* Another interface on a multi-tuner device */ 747 /* Another interface on a multi-tuner device */
@@ -682,6 +772,7 @@ static struct usb_device_id m920x_table [] = {
682 USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) }, 772 USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
683 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) }, 773 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
684 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) }, 774 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
775 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
685 { } /* Terminating entry */ 776 { } /* Terminating entry */
686}; 777};
687MODULE_DEVICE_TABLE (usb, m920x_table); 778MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -895,6 +986,56 @@ static struct dvb_usb_device_properties dposh_properties = {
895 } 986 }
896}; 987};
897 988
989static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
990 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
991
992 .usb_ctrl = DEVICE_SPECIFIC,
993 .download_firmware = NULL,
994
995 .rc_interval = 100,
996 .rc_key_map = pinnacle310e_rc_keys,
997 .rc_key_map_size = ARRAY_SIZE(pinnacle310e_rc_keys),
998 .rc_query = m920x_rc_query,
999
1000 .size_of_priv = sizeof(struct m920x_state),
1001
1002 .identify_state = m920x_identify_state,
1003 .num_adapters = 1,
1004 .adapter = {{
1005 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1006 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1007
1008 .pid_filter_count = 8,
1009 .pid_filter = m920x_pid_filter,
1010 .pid_filter_ctrl = m920x_pid_filter_ctrl,
1011
1012 .frontend_attach = m920x_mt352_frontend_attach,
1013 .tuner_attach = m920x_fmd1216me_tuner_attach,
1014
1015 .stream = {
1016 .type = USB_ISOC,
1017 .count = 5,
1018 .endpoint = 0x84,
1019 .u = {
1020 .isoc = {
1021 .framesperurb = 128,
1022 .framesize = 564,
1023 .interval = 1,
1024 }
1025 }
1026 },
1027 } },
1028 .i2c_algo = &m920x_i2c_algo,
1029
1030 .num_device_descs = 1,
1031 .devices = {
1032 { "Pinnacle PCTV 310e",
1033 { &m920x_table[6], NULL },
1034 { NULL },
1035 }
1036 }
1037};
1038
898static struct usb_driver m920x_driver = { 1039static struct usb_driver m920x_driver = {
899 .name = "dvb_usb_m920x", 1040 .name = "dvb_usb_m920x",
900 .probe = m920x_probe, 1041 .probe = m920x_probe,
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h
index 37532890accd..3c061518ffc1 100644
--- a/drivers/media/dvb/dvb-usb/m920x.h
+++ b/drivers/media/dvb/dvb-usb/m920x.h
@@ -18,7 +18,7 @@
18#define M9206_FW 0x30 18#define M9206_FW 0x30
19 19
20#define M9206_MAX_FILTERS 8 20#define M9206_MAX_FILTERS 8
21#define M9206_MAX_ADAPTERS 2 21#define M9206_MAX_ADAPTERS 4
22 22
23/* 23/*
24sequences found in logs: 24sequences found in logs:
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index d4e230941679..830557696ae6 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -138,7 +138,7 @@ static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
138 (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 138 (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
139 msg[i].buf, 139 msg[i].buf,
140 msg[i].len 140 msg[i].len
141 )!= msg[i].len)) { 141 )) != msg[i].len) {
142 break; 142 break;
143 } 143 }
144 if (dvb_usb_opera1_debug & 0x10) 144 if (dvb_usb_opera1_debug & 0x10)
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index 7c5459c27b75..c3e0ec2dcfca 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -90,13 +90,14 @@ static inline struct node_entry *node_of(struct firedtv *fdtv)
90 return container_of(fdtv->device, struct unit_directory, device)->ne; 90 return container_of(fdtv->device, struct unit_directory, device)->ne;
91} 91}
92 92
93static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) 93static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
94{ 94{
95 quadlet_t *d = data;
95 int ret; 96 int ret;
96 97
97 ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, 98 ret = hpsb_node_lock(node_of(fdtv), addr,
98 (__force quadlet_t *)&data[1], (__force quadlet_t)data[0]); 99 EXTCODE_COMPARE_SWAP, &d[1], d[0]);
99 data[0] = data[1]; 100 d[0] = d[1];
100 101
101 return ret; 102 return ret;
102} 103}
@@ -192,9 +193,13 @@ static int node_probe(struct device *dev)
192 int kv_len, err; 193 int kv_len, err;
193 void *kv_str; 194 void *kv_str;
194 195
195 kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); 196 if (ud->model_name_kv) {
196 kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); 197 kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4;
197 198 kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
199 } else {
200 kv_len = 0;
201 kv_str = NULL;
202 }
198 fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); 203 fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
199 if (!fdtv) 204 if (!fdtv)
200 return -ENOMEM; 205 return -ENOMEM;
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 50c42a4b972b..1b31bebc27d6 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -74,7 +74,6 @@
74#define EN50221_TAG_CA_INFO 0x9f8031 74#define EN50221_TAG_CA_INFO 0x9f8031
75 75
76struct avc_command_frame { 76struct avc_command_frame {
77 int length;
78 u8 ctype; 77 u8 ctype;
79 u8 subunit; 78 u8 subunit;
80 u8 opcode; 79 u8 opcode;
@@ -82,13 +81,27 @@ struct avc_command_frame {
82}; 81};
83 82
84struct avc_response_frame { 83struct avc_response_frame {
85 int length;
86 u8 response; 84 u8 response;
87 u8 subunit; 85 u8 subunit;
88 u8 opcode; 86 u8 opcode;
89 u8 operand[509]; 87 u8 operand[509];
90}; 88};
91 89
90#define LAST_OPERAND (509 - 1)
91
92static inline void clear_operands(struct avc_command_frame *c, int from, int to)
93{
94 memset(&c->operand[from], 0, to - from + 1);
95}
96
97static void pad_operands(struct avc_command_frame *c, int from)
98{
99 int to = ALIGN(from, 4);
100
101 if (from <= to && to <= LAST_OPERAND)
102 clear_operands(c, from, to);
103}
104
92#define AVC_DEBUG_READ_DESCRIPTOR 0x0001 105#define AVC_DEBUG_READ_DESCRIPTOR 0x0001
93#define AVC_DEBUG_DSIT 0x0002 106#define AVC_DEBUG_DSIT 0x0002
94#define AVC_DEBUG_DSD 0x0004 107#define AVC_DEBUG_DSD 0x0004
@@ -202,78 +215,65 @@ static void debug_pmt(char *msg, int length)
202 16, 1, msg, length, false); 215 16, 1, msg, length, false);
203} 216}
204 217
205static int __avc_write(struct firedtv *fdtv, 218static int avc_write(struct firedtv *fdtv)
206 const struct avc_command_frame *c, struct avc_response_frame *r)
207{ 219{
208 int err, retry; 220 int err, retry;
209 221
210 if (r) 222 fdtv->avc_reply_received = false;
211 fdtv->avc_reply_received = false;
212 223
213 for (retry = 0; retry < 6; retry++) { 224 for (retry = 0; retry < 6; retry++) {
214 if (unlikely(avc_debug)) 225 if (unlikely(avc_debug))
215 debug_fcp(&c->ctype, c->length); 226 debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
216 227
217 err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, 228 err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
218 (void *)&c->ctype, c->length); 229 fdtv->avc_data, fdtv->avc_data_length);
219 if (err) { 230 if (err) {
220 fdtv->avc_reply_received = true;
221 dev_err(fdtv->device, "FCP command write failed\n"); 231 dev_err(fdtv->device, "FCP command write failed\n");
232
222 return err; 233 return err;
223 } 234 }
224 235
225 if (!r)
226 return 0;
227
228 /* 236 /*
229 * AV/C specs say that answers should be sent within 150 ms. 237 * AV/C specs say that answers should be sent within 150 ms.
230 * Time out after 200 ms. 238 * Time out after 200 ms.
231 */ 239 */
232 if (wait_event_timeout(fdtv->avc_wait, 240 if (wait_event_timeout(fdtv->avc_wait,
233 fdtv->avc_reply_received, 241 fdtv->avc_reply_received,
234 msecs_to_jiffies(200)) != 0) { 242 msecs_to_jiffies(200)) != 0)
235 r->length = fdtv->response_length;
236 memcpy(&r->response, fdtv->response, r->length);
237
238 return 0; 243 return 0;
239 }
240 } 244 }
241 dev_err(fdtv->device, "FCP response timed out\n"); 245 dev_err(fdtv->device, "FCP response timed out\n");
246
242 return -ETIMEDOUT; 247 return -ETIMEDOUT;
243} 248}
244 249
245static int avc_write(struct firedtv *fdtv, 250static bool is_register_rc(struct avc_response_frame *r)
246 const struct avc_command_frame *c, struct avc_response_frame *r)
247{ 251{
248 int ret; 252 return r->opcode == AVC_OPCODE_VENDOR &&
249 253 r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
250 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 254 r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
251 return -EINTR; 255 r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
252 256 r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
253 ret = __avc_write(fdtv, c, r);
254
255 mutex_unlock(&fdtv->avc_mutex);
256 return ret;
257} 257}
258 258
259int avc_recv(struct firedtv *fdtv, void *data, size_t length) 259int avc_recv(struct firedtv *fdtv, void *data, size_t length)
260{ 260{
261 struct avc_response_frame *r = 261 struct avc_response_frame *r = data;
262 data - offsetof(struct avc_response_frame, response);
263 262
264 if (unlikely(avc_debug)) 263 if (unlikely(avc_debug))
265 debug_fcp(data, length); 264 debug_fcp(data, length);
266 265
267 if (length >= 8 && 266 if (length >= 8 && is_register_rc(r)) {
268 r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && 267 switch (r->response) {
269 r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && 268 case AVC_RESPONSE_CHANGED:
270 r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && 269 fdtv_handle_rc(fdtv, r->operand[4] << 8 | r->operand[5]);
271 r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
272 if (r->response == AVC_RESPONSE_CHANGED) {
273 fdtv_handle_rc(fdtv,
274 r->operand[4] << 8 | r->operand[5]);
275 schedule_work(&fdtv->remote_ctrl_work); 270 schedule_work(&fdtv->remote_ctrl_work);
276 } else if (r->response != AVC_RESPONSE_INTERIM) { 271 break;
272 case AVC_RESPONSE_INTERIM:
273 if (is_register_rc((void *)fdtv->avc_data))
274 goto wake;
275 break;
276 default:
277 dev_info(fdtv->device, 277 dev_info(fdtv->device,
278 "remote control result = %d\n", r->response); 278 "remote control result = %d\n", r->response);
279 } 279 }
@@ -285,9 +285,9 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length)
285 return -EIO; 285 return -EIO;
286 } 286 }
287 287
288 memcpy(fdtv->response, data, length); 288 memcpy(fdtv->avc_data, data, length);
289 fdtv->response_length = length; 289 fdtv->avc_data_length = length;
290 290wake:
291 fdtv->avc_reply_received = true; 291 fdtv->avc_reply_received = true;
292 wake_up(&fdtv->avc_wait); 292 wake_up(&fdtv->avc_wait);
293 293
@@ -318,10 +318,11 @@ static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
318 * tuning command for setting the relative LNB frequency 318 * tuning command for setting the relative LNB frequency
319 * (not supported by the AVC standard) 319 * (not supported by the AVC standard)
320 */ 320 */
321static void avc_tuner_tuneqpsk(struct firedtv *fdtv, 321static int avc_tuner_tuneqpsk(struct firedtv *fdtv,
322 struct dvb_frontend_parameters *params, 322 struct dvb_frontend_parameters *params)
323 struct avc_command_frame *c)
324{ 323{
324 struct avc_command_frame *c = (void *)fdtv->avc_data;
325
325 c->opcode = AVC_OPCODE_VENDOR; 326 c->opcode = AVC_OPCODE_VENDOR;
326 327
327 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; 328 c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
@@ -370,16 +371,18 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
370 c->operand[13] = 0x1; 371 c->operand[13] = 0x1;
371 c->operand[14] = 0xff; 372 c->operand[14] = 0xff;
372 c->operand[15] = 0xff; 373 c->operand[15] = 0xff;
373 c->length = 20; 374
375 return 16;
374 } else { 376 } else {
375 c->length = 16; 377 return 13;
376 } 378 }
377} 379}
378 380
379static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, 381static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
380 struct dvb_frontend_parameters *params, 382 struct dvb_frontend_parameters *params)
381 struct avc_command_frame *c)
382{ 383{
384 struct avc_command_frame *c = (void *)fdtv->avc_data;
385
383 c->opcode = AVC_OPCODE_DSD; 386 c->opcode = AVC_OPCODE_DSD;
384 387
385 c->operand[0] = 0; /* source plug */ 388 c->operand[0] = 0; /* source plug */
@@ -440,15 +443,14 @@ static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
440 c->operand[20] = 0x00; 443 c->operand[20] = 0x00;
441 c->operand[21] = 0x00; 444 c->operand[21] = 0x00;
442 445
443 /* Add PIDs to filter */ 446 return 22 + add_pid_filter(fdtv, &c->operand[22]);
444 c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
445} 447}
446 448
447static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, 449static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
448 struct dvb_frontend_parameters *params, 450 struct dvb_frontend_parameters *params)
449 struct avc_command_frame *c)
450{ 451{
451 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm; 452 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
453 struct avc_command_frame *c = (void *)fdtv->avc_data;
452 454
453 c->opcode = AVC_OPCODE_DSD; 455 c->opcode = AVC_OPCODE_DSD;
454 456
@@ -543,55 +545,58 @@ static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
543 c->operand[15] = 0x00; /* network_ID[0] */ 545 c->operand[15] = 0x00; /* network_ID[0] */
544 c->operand[16] = 0x00; /* network_ID[1] */ 546 c->operand[16] = 0x00; /* network_ID[1] */
545 547
546 /* Add PIDs to filter */ 548 return 17 + add_pid_filter(fdtv, &c->operand[17]);
547 c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
548} 549}
549 550
550int avc_tuner_dsd(struct firedtv *fdtv, 551int avc_tuner_dsd(struct firedtv *fdtv,
551 struct dvb_frontend_parameters *params) 552 struct dvb_frontend_parameters *params)
552{ 553{
553 char buffer[sizeof(struct avc_command_frame)]; 554 struct avc_command_frame *c = (void *)fdtv->avc_data;
554 struct avc_command_frame *c = (void *)buffer; 555 int pos, ret;
555 struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
556 556
557 memset(c, 0, sizeof(*c)); 557 mutex_lock(&fdtv->avc_mutex);
558 558
559 c->ctype = AVC_CTYPE_CONTROL; 559 c->ctype = AVC_CTYPE_CONTROL;
560 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 560 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
561 561
562 switch (fdtv->type) { 562 switch (fdtv->type) {
563 case FIREDTV_DVB_S: 563 case FIREDTV_DVB_S:
564 case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; 564 case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, params); break;
565 case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break; 565 case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, params); break;
566 case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break; 566 case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, params); break;
567 default: 567 default:
568 BUG(); 568 BUG();
569 } 569 }
570 pad_operands(c, pos);
570 571
571 if (avc_write(fdtv, c, r) < 0) 572 fdtv->avc_data_length = ALIGN(3 + pos, 4);
572 return -EIO; 573 ret = avc_write(fdtv);
573
574 msleep(500);
575#if 0 574#if 0
576 /* FIXME: */ 575 /*
577 /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ 576 * FIXME:
577 * u8 *status was an out-parameter of avc_tuner_dsd, unused by caller.
578 * Check for AVC_RESPONSE_ACCEPTED here instead?
579 */
578 if (status) 580 if (status)
579 *status = r->operand[2]; 581 *status = r->operand[2];
580#endif 582#endif
581 return 0; 583 mutex_unlock(&fdtv->avc_mutex);
584
585 if (ret == 0)
586 msleep(500);
587
588 return ret;
582} 589}
583 590
584int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) 591int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
585{ 592{
586 char buffer[sizeof(struct avc_command_frame)]; 593 struct avc_command_frame *c = (void *)fdtv->avc_data;
587 struct avc_command_frame *c = (void *)buffer; 594 int ret, pos, k;
588 struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
589 int pos, k;
590 595
591 if (pidc > 16 && pidc != 0xff) 596 if (pidc > 16 && pidc != 0xff)
592 return -EINVAL; 597 return -EINVAL;
593 598
594 memset(c, 0, sizeof(*c)); 599 mutex_lock(&fdtv->avc_mutex);
595 600
596 c->ctype = AVC_CTYPE_CONTROL; 601 c->ctype = AVC_CTYPE_CONTROL;
597 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 602 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -614,24 +619,27 @@ int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
614 c->operand[pos++] = 0x00; /* tableID */ 619 c->operand[pos++] = 0x00; /* tableID */
615 c->operand[pos++] = 0x00; /* filter_length */ 620 c->operand[pos++] = 0x00; /* filter_length */
616 } 621 }
622 pad_operands(c, pos);
617 623
618 c->length = ALIGN(3 + pos, 4); 624 fdtv->avc_data_length = ALIGN(3 + pos, 4);
625 ret = avc_write(fdtv);
619 626
620 if (avc_write(fdtv, c, r) < 0) 627 /* FIXME: check response code? */
621 return -EIO;
622 628
623 msleep(50); 629 mutex_unlock(&fdtv->avc_mutex);
624 return 0; 630
631 if (ret == 0)
632 msleep(50);
633
634 return ret;
625} 635}
626 636
627int avc_tuner_get_ts(struct firedtv *fdtv) 637int avc_tuner_get_ts(struct firedtv *fdtv)
628{ 638{
629 char buffer[sizeof(struct avc_command_frame)]; 639 struct avc_command_frame *c = (void *)fdtv->avc_data;
630 struct avc_command_frame *c = (void *)buffer; 640 int ret, sl;
631 struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
632 int sl;
633 641
634 memset(c, 0, sizeof(*c)); 642 mutex_lock(&fdtv->avc_mutex);
635 643
636 c->ctype = AVC_CTYPE_CONTROL; 644 c->ctype = AVC_CTYPE_CONTROL;
637 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 645 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -646,26 +654,33 @@ int avc_tuner_get_ts(struct firedtv *fdtv)
646 c->operand[4] = 0x00; /* antenna number */ 654 c->operand[4] = 0x00; /* antenna number */
647 c->operand[5] = 0x0; /* system_specific_search_flags */ 655 c->operand[5] = 0x0; /* system_specific_search_flags */
648 c->operand[6] = sl; /* system_specific_multiplex selection_length */ 656 c->operand[6] = sl; /* system_specific_multiplex selection_length */
649 c->operand[7] = 0x00; /* valid_flags [0] */ 657 /*
650 c->operand[8] = 0x00; /* valid_flags [1] */ 658 * operand[7]: valid_flags[0]
651 c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ 659 * operand[8]: valid_flags[1]
660 * operand[7 + sl]: nr_of_dsit_sel_specs (always 0)
661 */
662 clear_operands(c, 7, 24);
652 663
653 c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; 664 fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
665 ret = avc_write(fdtv);
654 666
655 if (avc_write(fdtv, c, r) < 0) 667 /* FIXME: check response code? */
656 return -EIO;
657 668
658 msleep(250); 669 mutex_unlock(&fdtv->avc_mutex);
659 return 0; 670
671 if (ret == 0)
672 msleep(250);
673
674 return ret;
660} 675}
661 676
662int avc_identify_subunit(struct firedtv *fdtv) 677int avc_identify_subunit(struct firedtv *fdtv)
663{ 678{
664 char buffer[sizeof(struct avc_command_frame)]; 679 struct avc_command_frame *c = (void *)fdtv->avc_data;
665 struct avc_command_frame *c = (void *)buffer; 680 struct avc_response_frame *r = (void *)fdtv->avc_data;
666 struct avc_response_frame *r = (void *)buffer; 681 int ret;
667 682
668 memset(c, 0, sizeof(*c)); 683 mutex_lock(&fdtv->avc_mutex);
669 684
670 c->ctype = AVC_CTYPE_CONTROL; 685 c->ctype = AVC_CTYPE_CONTROL;
671 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 686 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -678,31 +693,34 @@ int avc_identify_subunit(struct firedtv *fdtv)
678 c->operand[4] = 0x08; /* length lowbyte */ 693 c->operand[4] = 0x08; /* length lowbyte */
679 c->operand[5] = 0x00; /* offset highbyte */ 694 c->operand[5] = 0x00; /* offset highbyte */
680 c->operand[6] = 0x0d; /* offset lowbyte */ 695 c->operand[6] = 0x0d; /* offset lowbyte */
696 clear_operands(c, 7, 8); /* padding */
681 697
682 c->length = 12; 698 fdtv->avc_data_length = 12;
683 699 ret = avc_write(fdtv);
684 if (avc_write(fdtv, c, r) < 0) 700 if (ret < 0)
685 return -EIO; 701 goto out;
686 702
687 if ((r->response != AVC_RESPONSE_STABLE && 703 if ((r->response != AVC_RESPONSE_STABLE &&
688 r->response != AVC_RESPONSE_ACCEPTED) || 704 r->response != AVC_RESPONSE_ACCEPTED) ||
689 (r->operand[3] << 8) + r->operand[4] != 8) { 705 (r->operand[3] << 8) + r->operand[4] != 8) {
690 dev_err(fdtv->device, "cannot read subunit identifier\n"); 706 dev_err(fdtv->device, "cannot read subunit identifier\n");
691 return -EINVAL; 707 ret = -EINVAL;
692 } 708 }
693 return 0; 709out:
710 mutex_unlock(&fdtv->avc_mutex);
711
712 return ret;
694} 713}
695 714
696#define SIZEOF_ANTENNA_INPUT_INFO 22 715#define SIZEOF_ANTENNA_INPUT_INFO 22
697 716
698int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) 717int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
699{ 718{
700 char buffer[sizeof(struct avc_command_frame)]; 719 struct avc_command_frame *c = (void *)fdtv->avc_data;
701 struct avc_command_frame *c = (void *)buffer; 720 struct avc_response_frame *r = (void *)fdtv->avc_data;
702 struct avc_response_frame *r = (void *)buffer; 721 int length, ret;
703 int length;
704 722
705 memset(c, 0, sizeof(*c)); 723 mutex_lock(&fdtv->avc_mutex);
706 724
707 c->ctype = AVC_CTYPE_CONTROL; 725 c->ctype = AVC_CTYPE_CONTROL;
708 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 726 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -710,27 +728,30 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
710 728
711 c->operand[0] = DESCRIPTOR_TUNER_STATUS; 729 c->operand[0] = DESCRIPTOR_TUNER_STATUS;
712 c->operand[1] = 0xff; /* read_result_status */ 730 c->operand[1] = 0xff; /* read_result_status */
713 c->operand[2] = 0x00; /* reserved */ 731 /*
714 c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ 732 * operand[2]: reserved
715 c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ 733 * operand[3]: SIZEOF_ANTENNA_INPUT_INFO >> 8
716 c->operand[5] = 0x00; 734 * operand[4]: SIZEOF_ANTENNA_INPUT_INFO & 0xff
717 c->operand[6] = 0x00; 735 */
718 736 clear_operands(c, 2, 31);
719 c->length = 12; 737
720 738 fdtv->avc_data_length = 12;
721 if (avc_write(fdtv, c, r) < 0) 739 ret = avc_write(fdtv);
722 return -EIO; 740 if (ret < 0)
741 goto out;
723 742
724 if (r->response != AVC_RESPONSE_STABLE && 743 if (r->response != AVC_RESPONSE_STABLE &&
725 r->response != AVC_RESPONSE_ACCEPTED) { 744 r->response != AVC_RESPONSE_ACCEPTED) {
726 dev_err(fdtv->device, "cannot read tuner status\n"); 745 dev_err(fdtv->device, "cannot read tuner status\n");
727 return -EINVAL; 746 ret = -EINVAL;
747 goto out;
728 } 748 }
729 749
730 length = r->operand[9]; 750 length = r->operand[9];
731 if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { 751 if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
732 dev_err(fdtv->device, "got invalid tuner status\n"); 752 dev_err(fdtv->device, "got invalid tuner status\n");
733 return -EINVAL; 753 ret = -EINVAL;
754 goto out;
734 } 755 }
735 756
736 stat->active_system = r->operand[10]; 757 stat->active_system = r->operand[10];
@@ -766,20 +787,21 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
766 stat->ca_dvb_flag = r->operand[31] >> 3 & 1; 787 stat->ca_dvb_flag = r->operand[31] >> 3 & 1;
767 stat->ca_error_flag = r->operand[31] >> 2 & 1; 788 stat->ca_error_flag = r->operand[31] >> 2 & 1;
768 stat->ca_initialization_status = r->operand[31] >> 1 & 1; 789 stat->ca_initialization_status = r->operand[31] >> 1 & 1;
790out:
791 mutex_unlock(&fdtv->avc_mutex);
769 792
770 return 0; 793 return ret;
771} 794}
772 795
773int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, 796int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
774 char conttone, char nrdiseq, 797 char conttone, char nrdiseq,
775 struct dvb_diseqc_master_cmd *diseqcmd) 798 struct dvb_diseqc_master_cmd *diseqcmd)
776{ 799{
777 char buffer[sizeof(struct avc_command_frame)]; 800 struct avc_command_frame *c = (void *)fdtv->avc_data;
778 struct avc_command_frame *c = (void *)buffer; 801 struct avc_response_frame *r = (void *)fdtv->avc_data;
779 struct avc_response_frame *r = (void *)buffer; 802 int pos, j, k, ret;
780 int i, j, k;
781 803
782 memset(c, 0, sizeof(*c)); 804 mutex_lock(&fdtv->avc_mutex);
783 805
784 c->ctype = AVC_CTYPE_CONTROL; 806 c->ctype = AVC_CTYPE_CONTROL;
785 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 807 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -789,41 +811,41 @@ int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
789 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; 811 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
790 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; 812 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
791 c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; 813 c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
792
793 c->operand[4] = voltage; 814 c->operand[4] = voltage;
794 c->operand[5] = nrdiseq; 815 c->operand[5] = nrdiseq;
795 816
796 i = 6; 817 pos = 6;
797
798 for (j = 0; j < nrdiseq; j++) { 818 for (j = 0; j < nrdiseq; j++) {
799 c->operand[i++] = diseqcmd[j].msg_len; 819 c->operand[pos++] = diseqcmd[j].msg_len;
800 820
801 for (k = 0; k < diseqcmd[j].msg_len; k++) 821 for (k = 0; k < diseqcmd[j].msg_len; k++)
802 c->operand[i++] = diseqcmd[j].msg[k]; 822 c->operand[pos++] = diseqcmd[j].msg[k];
803 } 823 }
824 c->operand[pos++] = burst;
825 c->operand[pos++] = conttone;
826 pad_operands(c, pos);
804 827
805 c->operand[i++] = burst; 828 fdtv->avc_data_length = ALIGN(3 + pos, 4);
806 c->operand[i++] = conttone; 829 ret = avc_write(fdtv);
807 830 if (ret < 0)
808 c->length = ALIGN(3 + i, 4); 831 goto out;
809
810 if (avc_write(fdtv, c, r) < 0)
811 return -EIO;
812 832
813 if (r->response != AVC_RESPONSE_ACCEPTED) { 833 if (r->response != AVC_RESPONSE_ACCEPTED) {
814 dev_err(fdtv->device, "LNB control failed\n"); 834 dev_err(fdtv->device, "LNB control failed\n");
815 return -EINVAL; 835 ret = -EINVAL;
816 } 836 }
837out:
838 mutex_unlock(&fdtv->avc_mutex);
817 839
818 return 0; 840 return ret;
819} 841}
820 842
821int avc_register_remote_control(struct firedtv *fdtv) 843int avc_register_remote_control(struct firedtv *fdtv)
822{ 844{
823 char buffer[sizeof(struct avc_command_frame)]; 845 struct avc_command_frame *c = (void *)fdtv->avc_data;
824 struct avc_command_frame *c = (void *)buffer; 846 int ret;
825 847
826 memset(c, 0, sizeof(*c)); 848 mutex_lock(&fdtv->avc_mutex);
827 849
828 c->ctype = AVC_CTYPE_NOTIFY; 850 c->ctype = AVC_CTYPE_NOTIFY;
829 c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; 851 c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
@@ -833,10 +855,16 @@ int avc_register_remote_control(struct firedtv *fdtv)
833 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; 855 c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
834 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; 856 c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
835 c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; 857 c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
858 c->operand[4] = 0; /* padding */
859
860 fdtv->avc_data_length = 8;
861 ret = avc_write(fdtv);
836 862
837 c->length = 8; 863 /* FIXME: check response code? */
838 864
839 return avc_write(fdtv, c, NULL); 865 mutex_unlock(&fdtv->avc_mutex);
866
867 return ret;
840} 868}
841 869
842void avc_remote_ctrl_work(struct work_struct *work) 870void avc_remote_ctrl_work(struct work_struct *work)
@@ -851,11 +879,10 @@ void avc_remote_ctrl_work(struct work_struct *work)
851#if 0 /* FIXME: unused */ 879#if 0 /* FIXME: unused */
852int avc_tuner_host2ca(struct firedtv *fdtv) 880int avc_tuner_host2ca(struct firedtv *fdtv)
853{ 881{
854 char buffer[sizeof(struct avc_command_frame)]; 882 struct avc_command_frame *c = (void *)fdtv->avc_data;
855 struct avc_command_frame *c = (void *)buffer; 883 int ret;
856 struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
857 884
858 memset(c, 0, sizeof(*c)); 885 mutex_lock(&fdtv->avc_mutex);
859 886
860 c->ctype = AVC_CTYPE_CONTROL; 887 c->ctype = AVC_CTYPE_CONTROL;
861 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 888 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -867,15 +894,16 @@ int avc_tuner_host2ca(struct firedtv *fdtv)
867 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; 894 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
868 c->operand[4] = 0; /* slot */ 895 c->operand[4] = 0; /* slot */
869 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ 896 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
870 c->operand[6] = 0; /* more/last */ 897 clear_operands(c, 6, 8);
871 c->operand[7] = 0; /* length */
872 898
873 c->length = 12; 899 fdtv->avc_data_length = 12;
900 ret = avc_write(fdtv);
874 901
875 if (avc_write(fdtv, c, r) < 0) 902 /* FIXME: check response code? */
876 return -EIO;
877 903
878 return 0; 904 mutex_unlock(&fdtv->avc_mutex);
905
906 return ret;
879} 907}
880#endif 908#endif
881 909
@@ -906,12 +934,11 @@ static int get_ca_object_length(struct avc_response_frame *r)
906 934
907int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) 935int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
908{ 936{
909 char buffer[sizeof(struct avc_command_frame)]; 937 struct avc_command_frame *c = (void *)fdtv->avc_data;
910 struct avc_command_frame *c = (void *)buffer; 938 struct avc_response_frame *r = (void *)fdtv->avc_data;
911 struct avc_response_frame *r = (void *)buffer; 939 int pos, ret;
912 int pos;
913 940
914 memset(c, 0, sizeof(*c)); 941 mutex_lock(&fdtv->avc_mutex);
915 942
916 c->ctype = AVC_CTYPE_STATUS; 943 c->ctype = AVC_CTYPE_STATUS;
917 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 944 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -923,11 +950,12 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
923 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 950 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
924 c->operand[4] = 0; /* slot */ 951 c->operand[4] = 0; /* slot */
925 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ 952 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
953 clear_operands(c, 6, LAST_OPERAND);
926 954
927 c->length = 12; 955 fdtv->avc_data_length = 12;
928 956 ret = avc_write(fdtv);
929 if (avc_write(fdtv, c, r) < 0) 957 if (ret < 0)
930 return -EIO; 958 goto out;
931 959
932 /* FIXME: check response code and validate response data */ 960 /* FIXME: check response code and validate response data */
933 961
@@ -939,18 +967,19 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
939 app_info[4] = 0x01; 967 app_info[4] = 0x01;
940 memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); 968 memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
941 *len = app_info[3] + 4; 969 *len = app_info[3] + 4;
970out:
971 mutex_unlock(&fdtv->avc_mutex);
942 972
943 return 0; 973 return ret;
944} 974}
945 975
946int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) 976int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
947{ 977{
948 char buffer[sizeof(struct avc_command_frame)]; 978 struct avc_command_frame *c = (void *)fdtv->avc_data;
949 struct avc_command_frame *c = (void *)buffer; 979 struct avc_response_frame *r = (void *)fdtv->avc_data;
950 struct avc_response_frame *r = (void *)buffer; 980 int pos, ret;
951 int pos;
952 981
953 memset(c, 0, sizeof(*c)); 982 mutex_lock(&fdtv->avc_mutex);
954 983
955 c->ctype = AVC_CTYPE_STATUS; 984 c->ctype = AVC_CTYPE_STATUS;
956 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 985 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -962,11 +991,14 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
962 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 991 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
963 c->operand[4] = 0; /* slot */ 992 c->operand[4] = 0; /* slot */
964 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ 993 c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
994 clear_operands(c, 6, LAST_OPERAND);
965 995
966 c->length = 12; 996 fdtv->avc_data_length = 12;
997 ret = avc_write(fdtv);
998 if (ret < 0)
999 goto out;
967 1000
968 if (avc_write(fdtv, c, r) < 0) 1001 /* FIXME: check response code and validate response data */
969 return -EIO;
970 1002
971 pos = get_ca_object_pos(r); 1003 pos = get_ca_object_pos(r);
972 app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; 1004 app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
@@ -976,17 +1008,18 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
976 app_info[4] = r->operand[pos + 0]; 1008 app_info[4] = r->operand[pos + 0];
977 app_info[5] = r->operand[pos + 1]; 1009 app_info[5] = r->operand[pos + 1];
978 *len = app_info[3] + 4; 1010 *len = app_info[3] + 4;
1011out:
1012 mutex_unlock(&fdtv->avc_mutex);
979 1013
980 return 0; 1014 return ret;
981} 1015}
982 1016
983int avc_ca_reset(struct firedtv *fdtv) 1017int avc_ca_reset(struct firedtv *fdtv)
984{ 1018{
985 char buffer[sizeof(struct avc_command_frame)]; 1019 struct avc_command_frame *c = (void *)fdtv->avc_data;
986 struct avc_command_frame *c = (void *)buffer; 1020 int ret;
987 struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
988 1021
989 memset(c, 0, sizeof(*c)); 1022 mutex_lock(&fdtv->avc_mutex);
990 1023
991 c->ctype = AVC_CTYPE_CONTROL; 1024 c->ctype = AVC_CTYPE_CONTROL;
992 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1025 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1002,19 +1035,20 @@ int avc_ca_reset(struct firedtv *fdtv)
1002 c->operand[7] = 1; /* length */ 1035 c->operand[7] = 1; /* length */
1003 c->operand[8] = 0; /* force hardware reset */ 1036 c->operand[8] = 0; /* force hardware reset */
1004 1037
1005 c->length = 12; 1038 fdtv->avc_data_length = 12;
1039 ret = avc_write(fdtv);
1006 1040
1007 if (avc_write(fdtv, c, r) < 0) 1041 /* FIXME: check response code? */
1008 return -EIO;
1009 1042
1010 return 0; 1043 mutex_unlock(&fdtv->avc_mutex);
1044
1045 return ret;
1011} 1046}
1012 1047
1013int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) 1048int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1014{ 1049{
1015 char buffer[sizeof(struct avc_command_frame)]; 1050 struct avc_command_frame *c = (void *)fdtv->avc_data;
1016 struct avc_command_frame *c = (void *)buffer; 1051 struct avc_response_frame *r = (void *)fdtv->avc_data;
1017 struct avc_response_frame *r = (void *)buffer;
1018 int list_management; 1052 int list_management;
1019 int program_info_length; 1053 int program_info_length;
1020 int pmt_cmd_id; 1054 int pmt_cmd_id;
@@ -1022,11 +1056,12 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1022 int write_pos; 1056 int write_pos;
1023 int es_info_length; 1057 int es_info_length;
1024 int crc32_csum; 1058 int crc32_csum;
1059 int ret;
1025 1060
1026 if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT)) 1061 if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
1027 debug_pmt(msg, length); 1062 debug_pmt(msg, length);
1028 1063
1029 memset(c, 0, sizeof(*c)); 1064 mutex_lock(&fdtv->avc_mutex);
1030 1065
1031 c->ctype = AVC_CTYPE_CONTROL; 1066 c->ctype = AVC_CTYPE_CONTROL;
1032 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1067 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1058,7 +1093,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1058 1093
1059 c->operand[12] = 0x02; /* Table id=2 */ 1094 c->operand[12] = 0x02; /* Table id=2 */
1060 c->operand[13] = 0x80; /* Section syntax + length */ 1095 c->operand[13] = 0x80; /* Section syntax + length */
1061 /* c->operand[14] = XXXprogram_info_length + 12; */ 1096
1062 c->operand[15] = msg[1]; /* Program number */ 1097 c->operand[15] = msg[1]; /* Program number */
1063 c->operand[16] = msg[2]; 1098 c->operand[16] = msg[2];
1064 c->operand[17] = 0x01; /* Version number=0 + current/next=1 */ 1099 c->operand[17] = 0x01; /* Version number=0 + current/next=1 */
@@ -1106,12 +1141,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1106 write_pos += es_info_length; 1141 write_pos += es_info_length;
1107 } 1142 }
1108 } 1143 }
1109 1144 write_pos += 4; /* CRC */
1110 /* CRC */
1111 c->operand[write_pos++] = 0x00;
1112 c->operand[write_pos++] = 0x00;
1113 c->operand[write_pos++] = 0x00;
1114 c->operand[write_pos++] = 0x00;
1115 1145
1116 c->operand[7] = 0x82; 1146 c->operand[7] = 0x82;
1117 c->operand[8] = (write_pos - 10) >> 8; 1147 c->operand[8] = (write_pos - 10) >> 8;
@@ -1123,28 +1153,31 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1123 c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; 1153 c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
1124 c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; 1154 c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
1125 c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; 1155 c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
1156 pad_operands(c, write_pos);
1126 1157
1127 c->length = ALIGN(3 + write_pos, 4); 1158 fdtv->avc_data_length = ALIGN(3 + write_pos, 4);
1128 1159 ret = avc_write(fdtv);
1129 if (avc_write(fdtv, c, r) < 0) 1160 if (ret < 0)
1130 return -EIO; 1161 goto out;
1131 1162
1132 if (r->response != AVC_RESPONSE_ACCEPTED) { 1163 if (r->response != AVC_RESPONSE_ACCEPTED) {
1133 dev_err(fdtv->device, 1164 dev_err(fdtv->device,
1134 "CA PMT failed with response 0x%x\n", r->response); 1165 "CA PMT failed with response 0x%x\n", r->response);
1135 return -EFAULT; 1166 ret = -EFAULT;
1136 } 1167 }
1168out:
1169 mutex_unlock(&fdtv->avc_mutex);
1137 1170
1138 return 0; 1171 return ret;
1139} 1172}
1140 1173
1141int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) 1174int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
1142{ 1175{
1143 char buffer[sizeof(struct avc_command_frame)]; 1176 struct avc_command_frame *c = (void *)fdtv->avc_data;
1144 struct avc_command_frame *c = (void *)buffer; 1177 struct avc_response_frame *r = (void *)fdtv->avc_data;
1145 struct avc_response_frame *r = (void *)buffer; 1178 int ret;
1146 1179
1147 memset(c, 0, sizeof(*c)); 1180 mutex_lock(&fdtv->avc_mutex);
1148 1181
1149 c->ctype = AVC_CTYPE_STATUS; 1182 c->ctype = AVC_CTYPE_STATUS;
1150 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1183 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1156,28 +1189,28 @@ int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
1156 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 1189 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1157 c->operand[4] = 0; /* slot */ 1190 c->operand[4] = 0; /* slot */
1158 c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ 1191 c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
1159 c->operand[6] = 0; /* more/last */ 1192 clear_operands(c, 6, LAST_OPERAND);
1160 c->operand[7] = 0; /* length */
1161 1193
1162 c->length = 12; 1194 fdtv->avc_data_length = 12;
1163 1195 ret = avc_write(fdtv);
1164 if (avc_write(fdtv, c, r) < 0) 1196 if (ret < 0)
1165 return -EIO; 1197 goto out;
1166 1198
1167 /* FIXME: check response code and validate response data */ 1199 /* FIXME: check response code and validate response data */
1168 1200
1169 *interval = r->operand[get_ca_object_pos(r)]; 1201 *interval = r->operand[get_ca_object_pos(r)];
1202out:
1203 mutex_unlock(&fdtv->avc_mutex);
1170 1204
1171 return 0; 1205 return ret;
1172} 1206}
1173 1207
1174int avc_ca_enter_menu(struct firedtv *fdtv) 1208int avc_ca_enter_menu(struct firedtv *fdtv)
1175{ 1209{
1176 char buffer[sizeof(struct avc_command_frame)]; 1210 struct avc_command_frame *c = (void *)fdtv->avc_data;
1177 struct avc_command_frame *c = (void *)buffer; 1211 int ret;
1178 struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
1179 1212
1180 memset(c, 0, sizeof(*c)); 1213 mutex_lock(&fdtv->avc_mutex);
1181 1214
1182 c->ctype = AVC_CTYPE_STATUS; 1215 c->ctype = AVC_CTYPE_STATUS;
1183 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1216 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1189,24 +1222,25 @@ int avc_ca_enter_menu(struct firedtv *fdtv)
1189 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; 1222 c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
1190 c->operand[4] = 0; /* slot */ 1223 c->operand[4] = 0; /* slot */
1191 c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; 1224 c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
1192 c->operand[6] = 0; /* more/last */ 1225 clear_operands(c, 6, 8);
1193 c->operand[7] = 0; /* length */
1194 1226
1195 c->length = 12; 1227 fdtv->avc_data_length = 12;
1228 ret = avc_write(fdtv);
1196 1229
1197 if (avc_write(fdtv, c, r) < 0) 1230 /* FIXME: check response code? */
1198 return -EIO;
1199 1231
1200 return 0; 1232 mutex_unlock(&fdtv->avc_mutex);
1233
1234 return ret;
1201} 1235}
1202 1236
1203int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) 1237int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1204{ 1238{
1205 char buffer[sizeof(struct avc_command_frame)]; 1239 struct avc_command_frame *c = (void *)fdtv->avc_data;
1206 struct avc_command_frame *c = (void *)buffer; 1240 struct avc_response_frame *r = (void *)fdtv->avc_data;
1207 struct avc_response_frame *r = (void *)buffer; 1241 int ret;
1208 1242
1209 memset(c, 0, sizeof(*c)); 1243 mutex_lock(&fdtv->avc_mutex);
1210 1244
1211 c->ctype = AVC_CTYPE_STATUS; 1245 c->ctype = AVC_CTYPE_STATUS;
1212 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; 1246 c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
@@ -1218,20 +1252,21 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
1218 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; 1252 c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
1219 c->operand[4] = 0; /* slot */ 1253 c->operand[4] = 0; /* slot */
1220 c->operand[5] = SFE_VENDOR_TAG_CA_MMI; 1254 c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
1221 c->operand[6] = 0; /* more/last */ 1255 clear_operands(c, 6, LAST_OPERAND);
1222 c->operand[7] = 0; /* length */
1223 1256
1224 c->length = 12; 1257 fdtv->avc_data_length = 12;
1225 1258 ret = avc_write(fdtv);
1226 if (avc_write(fdtv, c, r) < 0) 1259 if (ret < 0)
1227 return -EIO; 1260 goto out;
1228 1261
1229 /* FIXME: check response code and validate response data */ 1262 /* FIXME: check response code and validate response data */
1230 1263
1231 *len = get_ca_object_length(r); 1264 *len = get_ca_object_length(r);
1232 memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); 1265 memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
1266out:
1267 mutex_unlock(&fdtv->avc_mutex);
1233 1268
1234 return 0; 1269 return ret;
1235} 1270}
1236 1271
1237#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL 1272#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
@@ -1240,14 +1275,14 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1240{ 1275{
1241 int ret; 1276 int ret;
1242 1277
1243 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 1278 mutex_lock(&fdtv->avc_mutex);
1244 return -EINTR;
1245 1279
1246 ret = fdtv->backend->read(fdtv, addr, data); 1280 ret = fdtv->backend->read(fdtv, addr, data);
1247 if (ret < 0) 1281 if (ret < 0)
1248 dev_err(fdtv->device, "CMP: read I/O error\n"); 1282 dev_err(fdtv->device, "CMP: read I/O error\n");
1249 1283
1250 mutex_unlock(&fdtv->avc_mutex); 1284 mutex_unlock(&fdtv->avc_mutex);
1285
1251 return ret; 1286 return ret;
1252} 1287}
1253 1288
@@ -1255,14 +1290,19 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1255{ 1290{
1256 int ret; 1291 int ret;
1257 1292
1258 if (mutex_lock_interruptible(&fdtv->avc_mutex)) 1293 mutex_lock(&fdtv->avc_mutex);
1259 return -EINTR; 1294
1295 /* data[] is stack-allocated and should not be DMA-mapped. */
1296 memcpy(fdtv->avc_data, data, 8);
1260 1297
1261 ret = fdtv->backend->lock(fdtv, addr, data); 1298 ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data);
1262 if (ret < 0) 1299 if (ret < 0)
1263 dev_err(fdtv->device, "CMP: lock I/O error\n"); 1300 dev_err(fdtv->device, "CMP: lock I/O error\n");
1301 else
1302 memcpy(data, fdtv->avc_data, 8);
1264 1303
1265 mutex_unlock(&fdtv->avc_mutex); 1304 mutex_unlock(&fdtv->avc_mutex);
1305
1266 return ret; 1306 return ret;
1267} 1307}
1268 1308
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index fc9996c13e13..079e8c5b0475 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -277,7 +277,6 @@ struct firedtv *fdtv_alloc(struct device *dev,
277 277
278 mutex_init(&fdtv->avc_mutex); 278 mutex_init(&fdtv->avc_mutex);
279 init_waitqueue_head(&fdtv->avc_wait); 279 init_waitqueue_head(&fdtv->avc_wait);
280 fdtv->avc_reply_received = true;
281 mutex_init(&fdtv->demux_mutex); 280 mutex_init(&fdtv->demux_mutex);
282 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); 281 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
283 282
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
index 6223bf01efe9..7a3de16fba06 100644
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -41,7 +41,7 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
41 return rcode != RCODE_COMPLETE ? -EIO : 0; 41 return rcode != RCODE_COMPLETE ? -EIO : 0;
42} 42}
43 43
44static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) 44static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
45{ 45{
46 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); 46 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
47} 47}
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
index 35080dbb3c66..78cc28f36914 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -73,7 +73,7 @@ struct input_dev;
73struct firedtv; 73struct firedtv;
74 74
75struct firedtv_backend { 75struct firedtv_backend {
76 int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]); 76 int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
77 int (*read)(struct firedtv *fdtv, u64 addr, void *data); 77 int (*read)(struct firedtv *fdtv, u64 addr, void *data);
78 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); 78 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
79 int (*start_iso)(struct firedtv *fdtv); 79 int (*start_iso)(struct firedtv *fdtv);
@@ -114,8 +114,8 @@ struct firedtv {
114 unsigned long channel_active; 114 unsigned long channel_active;
115 u16 channel_pid[16]; 115 u16 channel_pid[16];
116 116
117 size_t response_length; 117 int avc_data_length;
118 u8 response[512]; 118 u8 avc_data[512];
119}; 119};
120 120
121/* firedtv-1394.c */ 121/* firedtv-1394.c */
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h
index 28b90c91c766..e90fa92b1c1d 100644
--- a/drivers/media/dvb/frontends/af9013.h
+++ b/drivers/media/dvb/frontends/af9013.h
@@ -44,6 +44,7 @@ enum af9013_tuner {
44 AF9013_TUNER_MT2060_2 = 147, /* Microtune */ 44 AF9013_TUNER_MT2060_2 = 147, /* Microtune */
45 AF9013_TUNER_TDA18271 = 156, /* NXP */ 45 AF9013_TUNER_TDA18271 = 156, /* NXP */
46 AF9013_TUNER_QT1010A = 162, /* Quantek */ 46 AF9013_TUNER_QT1010A = 162, /* Quantek */
47 AF9013_TUNER_TDA18218 = 179, /* NXP */
47}; 48};
48 49
49/* AF9013/5 GPIOs (mostly guessed) 50/* AF9013/5 GPIOs (mostly guessed)
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
index 59881a5944eb..43aac2f85c2e 100644
--- a/drivers/media/dvb/frontends/atbm8830.c
+++ b/drivers/media/dvb/frontends/atbm8830.c
@@ -170,6 +170,19 @@ static int is_locked(struct atbm_state *priv, u8 *locked)
170 return 0; 170 return 0;
171} 171}
172 172
173static int set_agc_config(struct atbm_state *priv,
174 u8 min, u8 max, u8 hold_loop)
175{
176 /* no effect if both min and max are zero */
177 if (!min && !max)
178 return 0;
179
180 atbm8830_write_reg(priv, REG_AGC_MIN, min);
181 atbm8830_write_reg(priv, REG_AGC_MAX, max);
182 atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
183
184 return 0;
185}
173 186
174static int set_static_channel_mode(struct atbm_state *priv) 187static int set_static_channel_mode(struct atbm_state *priv)
175{ 188{
@@ -227,6 +240,9 @@ static int atbm8830_init(struct dvb_frontend *fe)
227 /*Set IF frequency*/ 240 /*Set IF frequency*/
228 set_if_freq(priv, cfg->if_freq); 241 set_if_freq(priv, cfg->if_freq);
229 242
243 /*Set AGC Config*/
244 set_agc_config(priv, cfg->agc_min, cfg->agc_max,
245 cfg->agc_hold_loop);
230 246
231 /*Set static channel mode*/ 247 /*Set static channel mode*/
232 set_static_channel_mode(priv); 248 set_static_channel_mode(priv);
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index 614552709a6f..7eac178f57b2 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -283,7 +283,7 @@ static int dib0090_sleep(struct dvb_frontend *fe)
283 return 0; 283 return 0;
284} 284}
285 285
286extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) 286void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
287{ 287{
288 struct dib0090_state *state = fe->tuner_priv; 288 struct dib0090_state *state = fe->tuner_priv;
289 if (fast) 289 if (fast)
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index 6f6fa29d9ea4..2aa97dd6a8af 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -1999,6 +1999,8 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
1999 struct dib8000_state *state = fe->demodulator_priv; 1999 struct dib8000_state *state = fe->demodulator_priv;
2000 int time, ret; 2000 int time, ret;
2001 2001
2002 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
2003
2002 dib8000_set_output_mode(state, OUTMODE_HIGH_Z); 2004 dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
2003 2005
2004 if (fe->ops.tuner_ops.set_params) 2006 if (fe->ops.tuner_ops.set_params)
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index e6f3d73db9d3..980e02f1575e 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -174,7 +174,7 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
174EXPORT_SYMBOL(dibx000_exit_i2c_master); 174EXPORT_SYMBOL(dibx000_exit_i2c_master);
175 175
176 176
177u32 systime() 177u32 systime(void)
178{ 178{
179 struct timespec t; 179 struct timespec t;
180 180
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index b181bf023ada..13437259eeac 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -158,7 +158,8 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
158 /* override frontend ops */ 158 /* override frontend ops */
159 fe->ops.set_voltage = lnbp21_set_voltage; 159 fe->ops.set_voltage = lnbp21_set_voltage;
160 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 160 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
161 fe->ops.set_tone = lnbp21_set_tone; 161 if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/
162 fe->ops.set_tone = lnbp21_set_tone;
162 printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); 163 printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
163 164
164 return fe; 165 return fe;
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
index 9552a22ccffb..d21a327db629 100644
--- a/drivers/media/dvb/frontends/si21xx.c
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -97,8 +97,6 @@
97#define LNB_SUPPLY_CTRL_REG_4 0xce 97#define LNB_SUPPLY_CTRL_REG_4 0xce
98#define LNB_SUPPLY_STATUS_REG 0xcf 98#define LNB_SUPPLY_STATUS_REG 0xcf
99 99
100#define FALSE 0
101#define TRUE 1
102#define FAIL -1 100#define FAIL -1
103#define PASS 0 101#define PASS 0
104 102
@@ -718,7 +716,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe,
718 int fine_tune_freq; 716 int fine_tune_freq;
719 unsigned char sample_rate = 0; 717 unsigned char sample_rate = 0;
720 /* boolean */ 718 /* boolean */
721 unsigned int inband_interferer_ind; 719 bool inband_interferer_ind;
722 720
723 /* INTERMEDIATE VALUES */ 721 /* INTERMEDIATE VALUES */
724 int icoarse_tune_freq; /* MHz */ 722 int icoarse_tune_freq; /* MHz */
@@ -728,15 +726,8 @@ static int si21xx_set_frontend(struct dvb_frontend *fe,
728 unsigned int x1; 726 unsigned int x1;
729 unsigned int x2; 727 unsigned int x2;
730 int i; 728 int i;
731 unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = { 729 bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
732 FALSE, FALSE, FALSE, FALSE, FALSE, 730 bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
733 FALSE, FALSE, FALSE, FALSE, FALSE
734 };
735 unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = {
736 FALSE, FALSE, FALSE, FALSE, FALSE,
737 FALSE, FALSE, FALSE, FALSE, FALSE
738 };
739
740 int status; 731 int status;
741 732
742 /* allowable sample rates for ADC in MHz */ 733 /* allowable sample rates for ADC in MHz */
@@ -762,7 +753,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe,
762 } 753 }
763 754
764 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) 755 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
765 inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE; 756 inband_interferer_div2[i] = inband_interferer_div4[i] = false;
766 757
767 if_limit_high = -700000; 758 if_limit_high = -700000;
768 if_limit_low = -100000; 759 if_limit_low = -100000;
@@ -798,7 +789,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe,
798 789
799 if (((band_low < x1) && (x1 < band_high)) || 790 if (((band_low < x1) && (x1 < band_high)) ||
800 ((band_low < x2) && (x2 < band_high))) 791 ((band_low < x2) && (x2 < band_high)))
801 inband_interferer_div4[i] = TRUE; 792 inband_interferer_div4[i] = true;
802 793
803 } 794 }
804 795
@@ -811,25 +802,28 @@ static int si21xx_set_frontend(struct dvb_frontend *fe,
811 802
812 if (((band_low < x1) && (x1 < band_high)) || 803 if (((band_low < x1) && (x1 < band_high)) ||
813 ((band_low < x2) && (x2 < band_high))) 804 ((band_low < x2) && (x2 < band_high)))
814 inband_interferer_div2[i] = TRUE; 805 inband_interferer_div2[i] = true;
815 } 806 }
816 807
817 inband_interferer_ind = TRUE; 808 inband_interferer_ind = true;
818 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) 809 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
819 inband_interferer_ind &= inband_interferer_div2[i] | 810 if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
820 inband_interferer_div4[i]; 811 inband_interferer_ind = false;
812 break;
813 }
814 }
821 815
822 if (inband_interferer_ind) { 816 if (inband_interferer_ind) {
823 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { 817 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
824 if (inband_interferer_div2[i] == FALSE) { 818 if (!inband_interferer_div2[i]) {
825 sample_rate = (u8) afs[i]; 819 sample_rate = (u8) afs[i];
826 break; 820 break;
827 } 821 }
828 } 822 }
829 } else { 823 } else {
830 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { 824 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
831 if ((inband_interferer_div2[i] | 825 if ((inband_interferer_div2[i] ||
832 inband_interferer_div4[i]) == FALSE) { 826 !inband_interferer_div4[i])) {
833 sample_rate = (u8) afs[i]; 827 sample_rate = (u8) afs[i];
834 break; 828 break;
835 } 829 }
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
index 29c3fa85c227..e3e35d1ce838 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -49,6 +49,8 @@ struct stv0900_config {
49 u8 tun2_maddress; 49 u8 tun2_maddress;
50 u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ 50 u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
51 u8 tun2_adc; 51 u8 tun2_adc;
52 u8 tun1_type;/* for now 3 for stb6100 auto, else - software */
53 u8 tun2_type;
52 /* Set device param to start dma */ 54 /* Set device param to start dma */
53 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); 55 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
54}; 56};
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 8762c86044a5..01f8f1f802fd 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -177,7 +177,7 @@ u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
177 return buf; 177 return buf;
178} 178}
179 179
180void extract_mask_pos(u32 label, u8 *mask, u8 *pos) 180static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
181{ 181{
182 u8 position = 0, i = 0; 182 u8 position = 0, i = 0;
183 183
@@ -218,7 +218,7 @@ u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
218 return val; 218 return val;
219} 219}
220 220
221enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp) 221static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
222{ 222{
223 s32 i; 223 s32 i;
224 224
@@ -282,7 +282,7 @@ enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
282 return STV0900_NO_ERROR; 282 return STV0900_NO_ERROR;
283} 283}
284 284
285u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk) 285static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
286{ 286{
287 u32 mclk = 90000000, div = 0, ad_div = 0; 287 u32 mclk = 90000000, div = 0, ad_div = 0;
288 288
@@ -296,7 +296,7 @@ u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
296 return mclk; 296 return mclk;
297} 297}
298 298
299enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) 299static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
300{ 300{
301 u32 m_div, clk_sel; 301 u32 m_div, clk_sel;
302 302
@@ -334,7 +334,7 @@ enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
334 return STV0900_NO_ERROR; 334 return STV0900_NO_ERROR;
335} 335}
336 336
337u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr, 337static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
338 enum fe_stv0900_demod_num demod) 338 enum fe_stv0900_demod_num demod)
339{ 339{
340 u32 lsb, msb, hsb, err_val; 340 u32 lsb, msb, hsb, err_val;
@@ -567,6 +567,46 @@ void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
567 } 567 }
568} 568}
569 569
570u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod)
571{
572 u32 freq, round;
573 /* Formulat :
574 Tuner_Frequency(MHz) = Regs / 64
575 Tuner_granularity(MHz) = Regs / 2048
576 real_Tuner_Frequency = Tuner_Frequency(MHz) - Tuner_granularity(MHz)
577 */
578 freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) +
579 (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) +
580 stv0900_get_bits(intp, TUN_RFFREQ0);
581
582 freq = (freq * 1000) / 64;
583
584 round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) +
585 stv0900_get_bits(intp, TUN_RFRESTE0);
586
587 round = (round * 1000) / 2048;
588
589 return freq + round;
590}
591
592void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
593 u32 Bandwidth, int demod)
594{
595 u32 tunerFrequency;
596 /* Formulat:
597 Tuner_frequency_reg= Frequency(MHz)*64
598 */
599 tunerFrequency = (Frequency * 64) / 1000;
600
601 stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10));
602 stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff);
603 stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03));
604 /* Low Pass Filter = BW /2 (MHz)*/
605 stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000);
606 /* Tuner Write trig */
607 stv0900_write_reg(intp, TNRLD, 1);
608}
609
570static s32 stv0900_get_rf_level(struct stv0900_internal *intp, 610static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
571 const struct stv0900_table *lookup, 611 const struct stv0900_table *lookup,
572 enum fe_stv0900_demod_num demod) 612 enum fe_stv0900_demod_num demod)
@@ -1329,7 +1369,6 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1329 enum fe_stv0900_error error = STV0900_NO_ERROR; 1369 enum fe_stv0900_error error = STV0900_NO_ERROR;
1330 enum fe_stv0900_error demodError = STV0900_NO_ERROR; 1370 enum fe_stv0900_error demodError = STV0900_NO_ERROR;
1331 struct stv0900_internal *intp = NULL; 1371 struct stv0900_internal *intp = NULL;
1332
1333 int selosci, i; 1372 int selosci, i;
1334 1373
1335 struct stv0900_inode *temp_int = find_inode(state->i2c_adap, 1374 struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
@@ -1345,7 +1384,14 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1345 } else { 1384 } else {
1346 state->internal = kmalloc(sizeof(struct stv0900_internal), 1385 state->internal = kmalloc(sizeof(struct stv0900_internal),
1347 GFP_KERNEL); 1386 GFP_KERNEL);
1387 if (state->internal == NULL)
1388 return STV0900_INVALID_HANDLE;
1348 temp_int = append_internal(state->internal); 1389 temp_int = append_internal(state->internal);
1390 if (temp_int == NULL) {
1391 kfree(state->internal);
1392 state->internal = NULL;
1393 return STV0900_INVALID_HANDLE;
1394 }
1349 state->internal->dmds_used = 1; 1395 state->internal->dmds_used = 1;
1350 state->internal->i2c_adap = state->i2c_adap; 1396 state->internal->i2c_adap = state->i2c_adap;
1351 state->internal->i2c_addr = state->config->demod_address; 1397 state->internal->i2c_addr = state->config->demod_address;
@@ -1371,11 +1417,6 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1371 return error; 1417 return error;
1372 } 1418 }
1373 1419
1374 if (state->internal == NULL) {
1375 error = STV0900_INVALID_HANDLE;
1376 return error;
1377 }
1378
1379 intp = state->internal; 1420 intp = state->internal;
1380 1421
1381 intp->demod_mode = p_init->demod_mode; 1422 intp->demod_mode = p_init->demod_mode;
@@ -1404,6 +1445,27 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1404 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0); 1445 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
1405 } 1446 }
1406 1447
1448 intp->tuner_type[0] = p_init->tuner1_type;
1449 intp->tuner_type[1] = p_init->tuner2_type;
1450 /* tuner init */
1451 switch (p_init->tuner1_type) {
1452 case 3: /*FE_AUTO_STB6100:*/
1453 stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c);
1454 stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86);
1455 stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18);
1456 stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */
1457 stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05);
1458 stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17);
1459 stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f);
1460 stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0);
1461 stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3);
1462 break;
1463 /* case FE_SW_TUNER: */
1464 default:
1465 stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6);
1466 break;
1467 }
1468
1407 stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); 1469 stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
1408 switch (p_init->tuner1_adc) { 1470 switch (p_init->tuner1_adc) {
1409 case 1: 1471 case 1:
@@ -1413,6 +1475,27 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1413 break; 1475 break;
1414 } 1476 }
1415 1477
1478 stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */
1479
1480 /* tuner init */
1481 switch (p_init->tuner2_type) {
1482 case 3: /*FE_AUTO_STB6100:*/
1483 stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c);
1484 stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86);
1485 stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18);
1486 stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */
1487 stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05);
1488 stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17);
1489 stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f);
1490 stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0);
1491 stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3);
1492 break;
1493 /* case FE_SW_TUNER: */
1494 default:
1495 stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6);
1496 break;
1497 }
1498
1416 stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); 1499 stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
1417 switch (p_init->tuner2_adc) { 1500 switch (p_init->tuner2_adc) {
1418 case 1: 1501 case 1:
@@ -1422,6 +1505,8 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1422 break; 1505 break;
1423 } 1506 }
1424 1507
1508 stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */
1509
1425 stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv); 1510 stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
1426 stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv); 1511 stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
1427 stv0900_set_mclk(intp, 135000000); 1512 stv0900_set_mclk(intp, 135000000);
@@ -1824,10 +1909,12 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
1824 init_params.tun1_maddress = config->tun1_maddress; 1909 init_params.tun1_maddress = config->tun1_maddress;
1825 init_params.tun1_iq_inv = STV0900_IQ_NORMAL; 1910 init_params.tun1_iq_inv = STV0900_IQ_NORMAL;
1826 init_params.tuner1_adc = config->tun1_adc; 1911 init_params.tuner1_adc = config->tun1_adc;
1912 init_params.tuner1_type = config->tun1_type;
1827 init_params.path2_ts_clock = config->path2_mode; 1913 init_params.path2_ts_clock = config->path2_mode;
1828 init_params.ts_config = config->ts_config_regs; 1914 init_params.ts_config = config->ts_config_regs;
1829 init_params.tun2_maddress = config->tun2_maddress; 1915 init_params.tun2_maddress = config->tun2_maddress;
1830 init_params.tuner2_adc = config->tun2_adc; 1916 init_params.tuner2_adc = config->tun2_adc;
1917 init_params.tuner2_type = config->tun2_type;
1831 init_params.tun2_iq_inv = STV0900_IQ_SWAPPED; 1918 init_params.tun2_iq_inv = STV0900_IQ_SWAPPED;
1832 1919
1833 err_stv0900 = stv0900_init_internal(&state->frontend, 1920 err_stv0900 = stv0900_init_internal(&state->frontend,
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
index d8ba8a984abe..b62b0f0a4fef 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -247,6 +247,7 @@ struct stv0900_init_params{
247 247
248 u8 tun1_maddress; 248 u8 tun1_maddress;
249 int tuner1_adc; 249 int tuner1_adc;
250 int tuner1_type;
250 251
251 /* IQ from the tuner1 to the demod */ 252 /* IQ from the tuner1 to the demod */
252 enum stv0900_iq_inversion tun1_iq_inv; 253 enum stv0900_iq_inversion tun1_iq_inv;
@@ -254,6 +255,7 @@ struct stv0900_init_params{
254 255
255 u8 tun2_maddress; 256 u8 tun2_maddress;
256 int tuner2_adc; 257 int tuner2_adc;
258 int tuner2_type;
257 259
258 /* IQ from the tuner2 to the demod */ 260 /* IQ from the tuner2 to the demod */
259 enum stv0900_iq_inversion tun2_iq_inv; 261 enum stv0900_iq_inversion tun2_iq_inv;
@@ -309,6 +311,8 @@ struct stv0900_internal{
309 s32 bw[2]; 311 s32 bw[2];
310 s32 symbol_rate[2]; 312 s32 symbol_rate[2];
311 s32 srch_range[2]; 313 s32 srch_range[2];
314 /* for software/auto tuner */
315 int tuner_type[2];
312 316
313 /* algorithm for search Blind, Cold or Warm*/ 317 /* algorithm for search Blind, Cold or Warm*/
314 enum fe_stv0900_search_algo srch_algo[2]; 318 enum fe_stv0900_search_algo srch_algo[2];
@@ -394,4 +398,11 @@ extern enum
394fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, 398fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
395 enum fe_stv0900_demod_num demod); 399 enum fe_stv0900_demod_num demod);
396 400
401extern u32
402stv0900_get_freq_auto(struct stv0900_internal *intp, int demod);
403
404extern void
405stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
406 u32 Bandwidth, int demod);
407
397#endif 408#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
index 7b8edf192e97..731afe93a823 100644
--- a/drivers/media/dvb/frontends/stv0900_reg.h
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -3174,17 +3174,21 @@ extern s32 shiftx(s32 x, int demod, s32 shift);
3174#define R0900_P1_TNRRF1 0xf4e9 3174#define R0900_P1_TNRRF1 0xf4e9
3175#define TNRRF1 REGx(R0900_P1_TNRRF1) 3175#define TNRRF1 REGx(R0900_P1_TNRRF1)
3176#define F0900_P1_TUN_RFFREQ2 0xf4e900ff 3176#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
3177#define TUN_RFFREQ2 FLDx(F0900_P1_TUN_RFFREQ2)
3177 3178
3178/*P1_TNRRF0*/ 3179/*P1_TNRRF0*/
3179#define R0900_P1_TNRRF0 0xf4ea 3180#define R0900_P1_TNRRF0 0xf4ea
3180#define TNRRF0 REGx(R0900_P1_TNRRF0) 3181#define TNRRF0 REGx(R0900_P1_TNRRF0)
3181#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff 3182#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
3183#define TUN_RFFREQ1 FLDx(F0900_P1_TUN_RFFREQ1)
3182 3184
3183/*P1_TNRBW*/ 3185/*P1_TNRBW*/
3184#define R0900_P1_TNRBW 0xf4eb 3186#define R0900_P1_TNRBW 0xf4eb
3185#define TNRBW REGx(R0900_P1_TNRBW) 3187#define TNRBW REGx(R0900_P1_TNRBW)
3186#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 3188#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
3189#define TUN_RFFREQ0 FLDx(F0900_P1_TUN_RFFREQ0)
3187#define F0900_P1_TUN_BW 0xf4eb003f 3190#define F0900_P1_TUN_BW 0xf4eb003f
3191#define TUN_BW FLDx(F0900_P1_TUN_BW)
3188 3192
3189/*P1_TNRADJ*/ 3193/*P1_TNRADJ*/
3190#define R0900_P1_TNRADJ 0xf4ec 3194#define R0900_P1_TNRADJ 0xf4ec
@@ -3234,11 +3238,13 @@ extern s32 shiftx(s32 x, int demod, s32 shift);
3234#define F0900_P1_TUN_I2CLOCKED 0xf4f60010 3238#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
3235#define F0900_P1_TUN_PROGDONE 0xf4f6000c 3239#define F0900_P1_TUN_PROGDONE 0xf4f6000c
3236#define F0900_P1_TUN_RFRESTE1 0xf4f60003 3240#define F0900_P1_TUN_RFRESTE1 0xf4f60003
3241#define TUN_RFRESTE1 FLDx(F0900_P1_TUN_RFRESTE1)
3237 3242
3238/*P1_TNRRESTE*/ 3243/*P1_TNRRESTE*/
3239#define R0900_P1_TNRRESTE 0xf4f7 3244#define R0900_P1_TNRRESTE 0xf4f7
3240#define TNRRESTE REGx(R0900_P1_TNRRESTE) 3245#define TNRRESTE REGx(R0900_P1_TNRRESTE)
3241#define F0900_P1_TUN_RFRESTE0 0xf4f700ff 3246#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
3247#define TUN_RFRESTE0 FLDx(F0900_P1_TUN_RFRESTE0)
3242 3248
3243/*P1_SMAPCOEF7*/ 3249/*P1_SMAPCOEF7*/
3244#define R0900_P1_SMAPCOEF7 0xf500 3250#define R0900_P1_SMAPCOEF7 0xf500
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
index b8da87fa637f..ba0709b2d433 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -193,7 +193,7 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
193 return lock; 193 return lock;
194} 194}
195 195
196int stv0900_sw_algo(struct stv0900_internal *intp, 196static int stv0900_sw_algo(struct stv0900_internal *intp,
197 enum fe_stv0900_demod_num demod) 197 enum fe_stv0900_demod_num demod)
198{ 198{
199 int lock = FALSE, 199 int lock = FALSE,
@@ -606,7 +606,12 @@ static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
606 tuner_freq -= (current_step * currier_step); 606 tuner_freq -= (current_step * currier_step);
607 607
608 if (intp->chip_id <= 0x20) { 608 if (intp->chip_id <= 0x20) {
609 stv0900_set_tuner(fe, tuner_freq, intp->bw[d]); 609 if (intp->tuner_type[d] == 3)
610 stv0900_set_tuner_auto(intp, tuner_freq,
611 intp->bw[d], demod);
612 else
613 stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
614
610 stv0900_write_reg(intp, DMDISTATE, 0x1c); 615 stv0900_write_reg(intp, DMDISTATE, 0x1c);
611 stv0900_write_reg(intp, CFRINIT1, 0); 616 stv0900_write_reg(intp, CFRINIT1, 0);
612 stv0900_write_reg(intp, CFRINIT0, 0); 617 stv0900_write_reg(intp, CFRINIT0, 0);
@@ -790,7 +795,7 @@ static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
790 return prate; 795 return prate;
791} 796}
792 797
793void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp, 798static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
794 enum fe_stv0900_demod_num demod, 799 enum fe_stv0900_demod_num demod,
795 u32 srate) 800 u32 srate)
796{ 801{
@@ -976,8 +981,16 @@ static void stv0900_track_optimization(struct dvb_frontend *fe)
976 intp->rolloff) + 10000000; 981 intp->rolloff) + 10000000;
977 982
978 if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) { 983 if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
979 if (intp->srch_algo[demod] != STV0900_WARM_START) 984 if (intp->srch_algo[demod] != STV0900_WARM_START) {
980 stv0900_set_bandwidth(fe, intp->bw[demod]); 985 if (intp->tuner_type[demod] == 3)
986 stv0900_set_tuner_auto(intp,
987 intp->freq[demod],
988 intp->bw[demod],
989 demod);
990 else
991 stv0900_set_bandwidth(fe,
992 intp->bw[demod]);
993 }
981 } 994 }
982 995
983 if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) || 996 if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
@@ -1202,7 +1215,11 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
1202 } 1215 }
1203 1216
1204 result->standard = stv0900_get_standard(fe, d); 1217 result->standard = stv0900_get_standard(fe, d);
1205 result->frequency = stv0900_get_tuner_freq(fe); 1218 if (intp->tuner_type[demod] == 3)
1219 result->frequency = stv0900_get_freq_auto(intp, d);
1220 else
1221 result->frequency = stv0900_get_tuner_freq(fe);
1222
1206 offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000; 1223 offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
1207 result->frequency += offsetFreq; 1224 result->frequency += offsetFreq;
1208 result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d); 1225 result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
@@ -1213,6 +1230,9 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
1213 result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; 1230 result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
1214 result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1; 1231 result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
1215 result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); 1232 result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
1233
1234 dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
1235
1216 switch (result->standard) { 1236 switch (result->standard) {
1217 case STV0900_DVBS2_STANDARD: 1237 case STV0900_DVBS2_STANDARD:
1218 result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD); 1238 result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
@@ -1239,7 +1259,11 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
1239 if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) || 1259 if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
1240 (intp->symbol_rate[d] < 10000000)) { 1260 (intp->symbol_rate[d] < 10000000)) {
1241 offsetFreq = result->frequency - intp->freq[d]; 1261 offsetFreq = result->frequency - intp->freq[d];
1242 intp->freq[d] = stv0900_get_tuner_freq(fe); 1262 if (intp->tuner_type[demod] == 3)
1263 intp->freq[d] = stv0900_get_freq_auto(intp, d);
1264 else
1265 intp->freq[d] = stv0900_get_tuner_freq(fe);
1266
1243 if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) 1267 if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1244 range = STV0900_RANGEOK; 1268 range = STV0900_RANGEOK;
1245 else if (ABS(offsetFreq) <= 1269 else if (ABS(offsetFreq) <=
@@ -1481,7 +1505,12 @@ static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
1481 else 1505 else
1482 tuner_freq -= (current_step * currier_step); 1506 tuner_freq -= (current_step * currier_step);
1483 1507
1484 stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]); 1508 if (intp->tuner_type[demod] == 3)
1509 stv0900_set_tuner_auto(intp, tuner_freq,
1510 intp->bw[demod], demod);
1511 else
1512 stv0900_set_tuner(fe, tuner_freq,
1513 intp->bw[demod]);
1485 } 1514 }
1486 } 1515 }
1487 1516
@@ -1608,7 +1637,8 @@ static int stv0900_blind_search_algo(struct dvb_frontend *fe)
1608 1637
1609 agc2_int = stv0900_blind_check_agc2_min_level(intp, demod); 1638 agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
1610 1639
1611 if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH) 1640 dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
1641 if (agc2_int > agc2_th)
1612 return FALSE; 1642 return FALSE;
1613 1643
1614 if (intp->chip_id == 0x10) 1644 if (intp->chip_id == 0x10)
@@ -1875,7 +1905,11 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
1875 1905
1876 } 1906 }
1877 1907
1878 stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]); 1908 if (intp->tuner_type[demod] == 3)
1909 stv0900_set_tuner_auto(intp, intp->freq[demod],
1910 intp->bw[demod], demod);
1911 else
1912 stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
1879 1913
1880 agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), 1914 agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
1881 stv0900_get_bits(intp, AGCIQ_VALUE0)); 1915 stv0900_get_bits(intp, AGCIQ_VALUE0));
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 1573466a5c74..c52c3357dc54 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -37,7 +37,82 @@
37static unsigned int verbose; 37static unsigned int verbose;
38module_param(verbose, int, 0644); 38module_param(verbose, int, 0644);
39 39
40struct mutex demod_lock; 40/* internal params node */
41struct stv090x_dev {
42 /* pointer for internal params, one for each pair of demods */
43 struct stv090x_internal *internal;
44 struct stv090x_dev *next_dev;
45};
46
47/* first internal params */
48static struct stv090x_dev *stv090x_first_dev;
49
50/* find chip by i2c adapter and i2c address */
51static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap,
52 u8 i2c_addr)
53{
54 struct stv090x_dev *temp_dev = stv090x_first_dev;
55
56 /*
57 Search of the last stv0900 chip or
58 find it by i2c adapter and i2c address */
59 while ((temp_dev != NULL) &&
60 ((temp_dev->internal->i2c_adap != i2c_adap) ||
61 (temp_dev->internal->i2c_addr != i2c_addr))) {
62
63 temp_dev = temp_dev->next_dev;
64 }
65
66 return temp_dev;
67}
68
69/* deallocating chip */
70static void remove_dev(struct stv090x_internal *internal)
71{
72 struct stv090x_dev *prev_dev = stv090x_first_dev;
73 struct stv090x_dev *del_dev = find_dev(internal->i2c_adap,
74 internal->i2c_addr);
75
76 if (del_dev != NULL) {
77 if (del_dev == stv090x_first_dev) {
78 stv090x_first_dev = del_dev->next_dev;
79 } else {
80 while (prev_dev->next_dev != del_dev)
81 prev_dev = prev_dev->next_dev;
82
83 prev_dev->next_dev = del_dev->next_dev;
84 }
85
86 kfree(del_dev);
87 }
88}
89
90/* allocating new chip */
91static struct stv090x_dev *append_internal(struct stv090x_internal *internal)
92{
93 struct stv090x_dev *new_dev;
94 struct stv090x_dev *temp_dev;
95
96 new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL);
97 if (new_dev != NULL) {
98 new_dev->internal = internal;
99 new_dev->next_dev = NULL;
100
101 /* append to list */
102 if (stv090x_first_dev == NULL) {
103 stv090x_first_dev = new_dev;
104 } else {
105 temp_dev = stv090x_first_dev;
106 while (temp_dev->next_dev != NULL)
107 temp_dev = temp_dev->next_dev;
108
109 temp_dev->next_dev = new_dev;
110 }
111 }
112
113 return new_dev;
114}
115
41 116
42/* DVBS1 and DSS C/N Lookup table */ 117/* DVBS1 and DSS C/N Lookup table */
43static const struct stv090x_tab stv090x_s1cn_tab[] = { 118static const struct stv090x_tab stv090x_s1cn_tab[] = {
@@ -683,6 +758,9 @@ static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
683 struct stv090x_state *state = fe->demodulator_priv; 758 struct stv090x_state *state = fe->demodulator_priv;
684 u32 reg; 759 u32 reg;
685 760
761 if (enable)
762 mutex_lock(&state->internal->tuner_lock);
763
686 reg = STV090x_READ_DEMOD(state, I2CRPT); 764 reg = STV090x_READ_DEMOD(state, I2CRPT);
687 if (enable) { 765 if (enable) {
688 dprintk(FE_DEBUG, 1, "Enable Gate"); 766 dprintk(FE_DEBUG, 1, "Enable Gate");
@@ -696,9 +774,14 @@ static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
696 if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) 774 if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
697 goto err; 775 goto err;
698 } 776 }
777
778 if (!enable)
779 mutex_unlock(&state->internal->tuner_lock);
780
699 return 0; 781 return 0;
700err: 782err:
701 dprintk(FE_ERROR, 1, "I/O error"); 783 dprintk(FE_ERROR, 1, "I/O error");
784 mutex_unlock(&state->internal->tuner_lock);
702 return -1; 785 return -1;
703} 786}
704 787
@@ -755,13 +838,13 @@ static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
755 838
756 if (srate > 60000000) { 839 if (srate > 60000000) {
757 sym = (srate << 4); /* SR * 2^16 / master_clk */ 840 sym = (srate << 4); /* SR * 2^16 / master_clk */
758 sym /= (state->mclk >> 12); 841 sym /= (state->internal->mclk >> 12);
759 } else if (srate > 6000000) { 842 } else if (srate > 6000000) {
760 sym = (srate << 6); 843 sym = (srate << 6);
761 sym /= (state->mclk >> 10); 844 sym /= (state->internal->mclk >> 10);
762 } else { 845 } else {
763 sym = (srate << 9); 846 sym = (srate << 9);
764 sym /= (state->mclk >> 7); 847 sym /= (state->internal->mclk >> 7);
765 } 848 }
766 849
767 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ 850 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
@@ -782,13 +865,13 @@ static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate
782 srate = 105 * (srate / 100); 865 srate = 105 * (srate / 100);
783 if (srate > 60000000) { 866 if (srate > 60000000) {
784 sym = (srate << 4); /* SR * 2^16 / master_clk */ 867 sym = (srate << 4); /* SR * 2^16 / master_clk */
785 sym /= (state->mclk >> 12); 868 sym /= (state->internal->mclk >> 12);
786 } else if (srate > 6000000) { 869 } else if (srate > 6000000) {
787 sym = (srate << 6); 870 sym = (srate << 6);
788 sym /= (state->mclk >> 10); 871 sym /= (state->internal->mclk >> 10);
789 } else { 872 } else {
790 sym = (srate << 9); 873 sym = (srate << 9);
791 sym /= (state->mclk >> 7); 874 sym /= (state->internal->mclk >> 7);
792 } 875 }
793 876
794 if (sym < 0x7fff) { 877 if (sym < 0x7fff) {
@@ -816,13 +899,13 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate
816 srate = 95 * (srate / 100); 899 srate = 95 * (srate / 100);
817 if (srate > 60000000) { 900 if (srate > 60000000) {
818 sym = (srate << 4); /* SR * 2^16 / master_clk */ 901 sym = (srate << 4); /* SR * 2^16 / master_clk */
819 sym /= (state->mclk >> 12); 902 sym /= (state->internal->mclk >> 12);
820 } else if (srate > 6000000) { 903 } else if (srate > 6000000) {
821 sym = (srate << 6); 904 sym = (srate << 6);
822 sym /= (state->mclk >> 10); 905 sym /= (state->internal->mclk >> 10);
823 } else { 906 } else {
824 sym = (srate << 9); 907 sym = (srate << 9);
825 sym /= (state->mclk >> 7); 908 sym /= (state->internal->mclk >> 7);
826 } 909 }
827 910
828 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ 911 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
@@ -1103,21 +1186,21 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
1103 1186
1104 switch (state->demod) { 1187 switch (state->demod) {
1105 case STV090x_DEMODULATOR_0: 1188 case STV090x_DEMODULATOR_0:
1106 mutex_lock(&demod_lock); 1189 mutex_lock(&state->internal->demod_lock);
1107 reg = stv090x_read_reg(state, STV090x_STOPCLK2); 1190 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
1108 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); 1191 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
1109 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 1192 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
1110 goto err; 1193 goto err;
1111 mutex_unlock(&demod_lock); 1194 mutex_unlock(&state->internal->demod_lock);
1112 break; 1195 break;
1113 1196
1114 case STV090x_DEMODULATOR_1: 1197 case STV090x_DEMODULATOR_1:
1115 mutex_lock(&demod_lock); 1198 mutex_lock(&state->internal->demod_lock);
1116 reg = stv090x_read_reg(state, STV090x_STOPCLK2); 1199 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
1117 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); 1200 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
1118 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 1201 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
1119 goto err; 1202 goto err;
1120 mutex_unlock(&demod_lock); 1203 mutex_unlock(&state->internal->demod_lock);
1121 break; 1204 break;
1122 1205
1123 default: 1206 default:
@@ -1126,14 +1209,14 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
1126 } 1209 }
1127 return 0; 1210 return 0;
1128err: 1211err:
1129 mutex_unlock(&demod_lock); 1212 mutex_unlock(&state->internal->demod_lock);
1130 dprintk(FE_ERROR, 1, "I/O error"); 1213 dprintk(FE_ERROR, 1, "I/O error");
1131 return -1; 1214 return -1;
1132} 1215}
1133 1216
1134static int stv090x_dvbs_track_crl(struct stv090x_state *state) 1217static int stv090x_dvbs_track_crl(struct stv090x_state *state)
1135{ 1218{
1136 if (state->dev_ver >= 0x30) { 1219 if (state->internal->dev_ver >= 0x30) {
1137 /* Set ACLC BCLC optimised value vs SR */ 1220 /* Set ACLC BCLC optimised value vs SR */
1138 if (state->srate >= 15000000) { 1221 if (state->srate >= 15000000) {
1139 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) 1222 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
@@ -1215,7 +1298,7 @@ static int stv090x_delivery_search(struct stv090x_state *state)
1215 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) 1298 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
1216 goto err; 1299 goto err;
1217 1300
1218 if (state->dev_ver <= 0x20) { 1301 if (state->internal->dev_ver <= 0x20) {
1219 /* enable S2 carrier loop */ 1302 /* enable S2 carrier loop */
1220 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) 1303 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
1221 goto err; 1304 goto err;
@@ -1246,6 +1329,10 @@ static int stv090x_delivery_search(struct stv090x_state *state)
1246 default: 1329 default:
1247 /* enable DVB-S2 and DVB-S2 in Auto MODE */ 1330 /* enable DVB-S2 and DVB-S2 in Auto MODE */
1248 reg = STV090x_READ_DEMOD(state, DMDCFGMD); 1331 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1332 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
1333 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
1334 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1335 goto err;
1249 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 1336 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1250 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 1337 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
1251 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 1338 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
@@ -1257,7 +1344,7 @@ static int stv090x_delivery_search(struct stv090x_state *state)
1257 if (stv090x_dvbs_track_crl(state) < 0) 1344 if (stv090x_dvbs_track_crl(state) < 0)
1258 goto err; 1345 goto err;
1259 1346
1260 if (state->dev_ver <= 0x20) { 1347 if (state->internal->dev_ver <= 0x20) {
1261 /* enable S2 carrier loop */ 1348 /* enable S2 carrier loop */
1262 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) 1349 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
1263 goto err; 1350 goto err;
@@ -1304,7 +1391,7 @@ static int stv090x_start_search(struct stv090x_state *state)
1304 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) 1391 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
1305 goto err; 1392 goto err;
1306 1393
1307 if (state->dev_ver <= 0x20) { 1394 if (state->internal->dev_ver <= 0x20) {
1308 if (state->srate <= 5000000) { 1395 if (state->srate <= 5000000) {
1309 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) 1396 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
1310 goto err; 1397 goto err;
@@ -1348,7 +1435,7 @@ static int stv090x_start_search(struct stv090x_state *state)
1348 * CFR max = +1MHz 1435 * CFR max = +1MHz
1349 */ 1436 */
1350 freq_abs = 1000 << 16; 1437 freq_abs = 1000 << 16;
1351 freq_abs /= (state->mclk / 1000); 1438 freq_abs /= (state->internal->mclk / 1000);
1352 freq = (s16) freq_abs; 1439 freq = (s16) freq_abs;
1353 } else { 1440 } else {
1354 /* COLD Start 1441 /* COLD Start
@@ -1358,7 +1445,7 @@ static int stv090x_start_search(struct stv090x_state *state)
1358 */ 1445 */
1359 freq_abs = (state->search_range / 2000) + 600; 1446 freq_abs = (state->search_range / 2000) + 600;
1360 freq_abs = freq_abs << 16; 1447 freq_abs = freq_abs << 16;
1361 freq_abs /= (state->mclk / 1000); 1448 freq_abs /= (state->internal->mclk / 1000);
1362 freq = (s16) freq_abs; 1449 freq = (s16) freq_abs;
1363 } 1450 }
1364 1451
@@ -1381,7 +1468,7 @@ static int stv090x_start_search(struct stv090x_state *state)
1381 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) 1468 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
1382 goto err; 1469 goto err;
1383 1470
1384 if (state->dev_ver >= 0x20) { 1471 if (state->internal->dev_ver >= 0x20) {
1385 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) 1472 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
1386 goto err; 1473 goto err;
1387 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) 1474 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
@@ -1418,10 +1505,10 @@ static int stv090x_start_search(struct stv090x_state *state)
1418 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) 1505 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
1419 goto err; 1506 goto err;
1420 1507
1421 if (state->dev_ver >= 0x20) { 1508 if (state->internal->dev_ver >= 0x20) {
1422 /*Frequency offset detector setting*/ 1509 /*Frequency offset detector setting*/
1423 if (state->srate < 2000000) { 1510 if (state->srate < 2000000) {
1424 if (state->dev_ver <= 0x20) { 1511 if (state->internal->dev_ver <= 0x20) {
1425 /* Cut 2 */ 1512 /* Cut 2 */
1426 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) 1513 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
1427 goto err; 1514 goto err;
@@ -1512,7 +1599,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1512 steps = 1; 1599 steps = 1;
1513 1600
1514 dir = 1; 1601 dir = 1;
1515 freq_step = (1000000 * 256) / (state->mclk / 256); 1602 freq_step = (1000000 * 256) / (state->internal->mclk / 256);
1516 freq_init = 0; 1603 freq_init = 0;
1517 1604
1518 for (i = 0; i < steps; i++) { 1605 for (i = 0; i < steps; i++) {
@@ -1583,7 +1670,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1583 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; 1670 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
1584 u32 agc2th; 1671 u32 agc2th;
1585 1672
1586 if (state->dev_ver >= 0x30) 1673 if (state->internal->dev_ver >= 0x30)
1587 agc2th = 0x2e00; 1674 agc2th = 0x2e00;
1588 else 1675 else
1589 agc2th = 0x1f00; 1676 agc2th = 0x1f00;
@@ -1619,13 +1706,13 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1619 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) 1706 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
1620 goto err; 1707 goto err;
1621 1708
1622 if (state->dev_ver >= 0x30) { 1709 if (state->internal->dev_ver >= 0x30) {
1623 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) 1710 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
1624 goto err; 1711 goto err;
1625 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) 1712 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
1626 goto err; 1713 goto err;
1627 1714
1628 } else if (state->dev_ver >= 0x20) { 1715 } else if (state->internal->dev_ver >= 0x20) {
1629 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) 1716 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
1630 goto err; 1717 goto err;
1631 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) 1718 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
@@ -1677,7 +1764,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1677 STV090x_READ_DEMOD(state, AGC2I0); 1764 STV090x_READ_DEMOD(state, AGC2I0);
1678 } 1765 }
1679 agc2 /= 10; 1766 agc2 /= 10;
1680 srate_coarse = stv090x_get_srate(state, state->mclk); 1767 srate_coarse = stv090x_get_srate(state, state->internal->mclk);
1681 cur_step++; 1768 cur_step++;
1682 dir *= -1; 1769 dir *= -1;
1683 if ((tmg_cpt >= 5) && (agc2 < agc2th) && 1770 if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
@@ -1695,12 +1782,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1695 1782
1696 if (state->config->tuner_set_frequency) { 1783 if (state->config->tuner_set_frequency) {
1697 if (state->config->tuner_set_frequency(fe, freq) < 0) 1784 if (state->config->tuner_set_frequency(fe, freq) < 0)
1698 goto err; 1785 goto err_gateoff;
1699 } 1786 }
1700 1787
1701 if (state->config->tuner_set_bandwidth) { 1788 if (state->config->tuner_set_bandwidth) {
1702 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 1789 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
1703 goto err; 1790 goto err_gateoff;
1704 } 1791 }
1705 1792
1706 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 1793 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -1713,7 +1800,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1713 1800
1714 if (state->config->tuner_get_status) { 1801 if (state->config->tuner_get_status) {
1715 if (state->config->tuner_get_status(fe, &reg) < 0) 1802 if (state->config->tuner_get_status(fe, &reg) < 0)
1716 goto err; 1803 goto err_gateoff;
1717 } 1804 }
1718 1805
1719 if (reg) 1806 if (reg)
@@ -1729,9 +1816,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1729 if (!tmg_lock) 1816 if (!tmg_lock)
1730 srate_coarse = 0; 1817 srate_coarse = 0;
1731 else 1818 else
1732 srate_coarse = stv090x_get_srate(state, state->mclk); 1819 srate_coarse = stv090x_get_srate(state, state->internal->mclk);
1733 1820
1734 return srate_coarse; 1821 return srate_coarse;
1822
1823err_gateoff:
1824 stv090x_i2c_gate_ctrl(fe, 0);
1735err: 1825err:
1736 dprintk(FE_ERROR, 1, "I/O error"); 1826 dprintk(FE_ERROR, 1, "I/O error");
1737 return -1; 1827 return -1;
@@ -1741,7 +1831,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1741{ 1831{
1742 u32 srate_coarse, freq_coarse, sym, reg; 1832 u32 srate_coarse, freq_coarse, sym, reg;
1743 1833
1744 srate_coarse = stv090x_get_srate(state, state->mclk); 1834 srate_coarse = stv090x_get_srate(state, state->internal->mclk);
1745 freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; 1835 freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8;
1746 freq_coarse |= STV090x_READ_DEMOD(state, CFR1); 1836 freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
1747 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ 1837 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
@@ -1767,10 +1857,10 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1767 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 1857 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1768 goto err; 1858 goto err;
1769 1859
1770 if (state->dev_ver >= 0x30) { 1860 if (state->internal->dev_ver >= 0x30) {
1771 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) 1861 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
1772 goto err; 1862 goto err;
1773 } else if (state->dev_ver >= 0x20) { 1863 } else if (state->internal->dev_ver >= 0x20) {
1774 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) 1864 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
1775 goto err; 1865 goto err;
1776 } 1866 }
@@ -1778,20 +1868,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1778 if (srate_coarse > 3000000) { 1868 if (srate_coarse > 3000000) {
1779 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ 1869 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1780 sym = (sym / 1000) * 65536; 1870 sym = (sym / 1000) * 65536;
1781 sym /= (state->mclk / 1000); 1871 sym /= (state->internal->mclk / 1000);
1782 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) 1872 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
1783 goto err; 1873 goto err;
1784 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) 1874 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
1785 goto err; 1875 goto err;
1786 sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ 1876 sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
1787 sym = (sym / 1000) * 65536; 1877 sym = (sym / 1000) * 65536;
1788 sym /= (state->mclk / 1000); 1878 sym /= (state->internal->mclk / 1000);
1789 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) 1879 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
1790 goto err; 1880 goto err;
1791 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) 1881 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
1792 goto err; 1882 goto err;
1793 sym = (srate_coarse / 1000) * 65536; 1883 sym = (srate_coarse / 1000) * 65536;
1794 sym /= (state->mclk / 1000); 1884 sym /= (state->internal->mclk / 1000);
1795 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) 1885 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
1796 goto err; 1886 goto err;
1797 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) 1887 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
@@ -1799,20 +1889,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1799 } else { 1889 } else {
1800 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ 1890 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1801 sym = (sym / 100) * 65536; 1891 sym = (sym / 100) * 65536;
1802 sym /= (state->mclk / 100); 1892 sym /= (state->internal->mclk / 100);
1803 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) 1893 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
1804 goto err; 1894 goto err;
1805 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) 1895 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
1806 goto err; 1896 goto err;
1807 sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ 1897 sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
1808 sym = (sym / 100) * 65536; 1898 sym = (sym / 100) * 65536;
1809 sym /= (state->mclk / 100); 1899 sym /= (state->internal->mclk / 100);
1810 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) 1900 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
1811 goto err; 1901 goto err;
1812 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) 1902 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
1813 goto err; 1903 goto err;
1814 sym = (srate_coarse / 100) * 65536; 1904 sym = (srate_coarse / 100) * 65536;
1815 sym /= (state->mclk / 100); 1905 sym /= (state->internal->mclk / 100);
1816 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) 1906 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
1817 goto err; 1907 goto err;
1818 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) 1908 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
@@ -1874,18 +1964,19 @@ static int stv090x_blind_search(struct stv090x_state *state)
1874 u32 agc2, reg, srate_coarse; 1964 u32 agc2, reg, srate_coarse;
1875 s32 cpt_fail, agc2_ovflw, i; 1965 s32 cpt_fail, agc2_ovflw, i;
1876 u8 k_ref, k_max, k_min; 1966 u8 k_ref, k_max, k_min;
1877 int coarse_fail, lock; 1967 int coarse_fail = 0;
1968 int lock;
1878 1969
1879 k_max = 110; 1970 k_max = 110;
1880 k_min = 10; 1971 k_min = 10;
1881 1972
1882 agc2 = stv090x_get_agc2_min_level(state); 1973 agc2 = stv090x_get_agc2_min_level(state);
1883 1974
1884 if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) { 1975 if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) {
1885 lock = 0; 1976 lock = 0;
1886 } else { 1977 } else {
1887 1978
1888 if (state->dev_ver <= 0x20) { 1979 if (state->internal->dev_ver <= 0x20) {
1889 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) 1980 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
1890 goto err; 1981 goto err;
1891 } else { 1982 } else {
@@ -1897,7 +1988,7 @@ static int stv090x_blind_search(struct stv090x_state *state)
1897 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) 1988 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
1898 goto err; 1989 goto err;
1899 1990
1900 if (state->dev_ver >= 0x20) { 1991 if (state->internal->dev_ver >= 0x20) {
1901 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) 1992 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
1902 goto err; 1993 goto err;
1903 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) 1994 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
@@ -1956,7 +2047,7 @@ static int stv090x_chk_tmg(struct stv090x_state *state)
1956 u32 reg; 2047 u32 reg;
1957 s32 tmg_cpt = 0, i; 2048 s32 tmg_cpt = 0, i;
1958 u8 freq, tmg_thh, tmg_thl; 2049 u8 freq, tmg_thh, tmg_thl;
1959 int tmg_lock; 2050 int tmg_lock = 0;
1960 2051
1961 freq = STV090x_READ_DEMOD(state, CARFREQ); 2052 freq = STV090x_READ_DEMOD(state, CARFREQ);
1962 tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); 2053 tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
@@ -2080,12 +2171,12 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2080 2171
2081 if (state->config->tuner_set_frequency) { 2172 if (state->config->tuner_set_frequency) {
2082 if (state->config->tuner_set_frequency(fe, freq) < 0) 2173 if (state->config->tuner_set_frequency(fe, freq) < 0)
2083 goto err; 2174 goto err_gateoff;
2084 } 2175 }
2085 2176
2086 if (state->config->tuner_set_bandwidth) { 2177 if (state->config->tuner_set_bandwidth) {
2087 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 2178 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
2088 goto err; 2179 goto err_gateoff;
2089 } 2180 }
2090 2181
2091 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2182 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -2098,7 +2189,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2098 2189
2099 if (state->config->tuner_get_status) { 2190 if (state->config->tuner_get_status) {
2100 if (state->config->tuner_get_status(fe, &reg) < 0) 2191 if (state->config->tuner_get_status(fe, &reg) < 0)
2101 goto err; 2192 goto err_gateoff;
2102 } 2193 }
2103 2194
2104 if (reg) 2195 if (reg)
@@ -2129,6 +2220,8 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2129 2220
2130 return lock; 2221 return lock;
2131 2222
2223err_gateoff:
2224 stv090x_i2c_gate_ctrl(fe, 0);
2132err: 2225err:
2133 dprintk(FE_ERROR, 1, "I/O error"); 2226 dprintk(FE_ERROR, 1, "I/O error");
2134 return -1; 2227 return -1;
@@ -2142,13 +2235,13 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s
2142 car_max = state->search_range / 1000; 2235 car_max = state->search_range / 1000;
2143 car_max += car_max / 10; 2236 car_max += car_max / 10;
2144 car_max = 65536 * (car_max / 2); 2237 car_max = 65536 * (car_max / 2);
2145 car_max /= (state->mclk / 1000); 2238 car_max /= (state->internal->mclk / 1000);
2146 2239
2147 if (car_max > 0x4000) 2240 if (car_max > 0x4000)
2148 car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ 2241 car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
2149 2242
2150 inc = srate; 2243 inc = srate;
2151 inc /= state->mclk / 1000; 2244 inc /= state->internal->mclk / 1000;
2152 inc *= 256; 2245 inc *= 256;
2153 inc *= 256; 2246 inc *= 256;
2154 inc /= 1000; 2247 inc /= 1000;
@@ -2209,7 +2302,7 @@ static int stv090x_chk_signal(struct stv090x_state *state)
2209 2302
2210 car_max += (car_max / 10); /* 10% margin */ 2303 car_max += (car_max / 10); /* 10% margin */
2211 car_max = (65536 * car_max / 2); 2304 car_max = (65536 * car_max / 2);
2212 car_max /= state->mclk / 1000; 2305 car_max /= state->internal->mclk / 1000;
2213 2306
2214 if (car_max > 0x4000) 2307 if (car_max > 0x4000)
2215 car_max = 0x4000; 2308 car_max = 0x4000;
@@ -2234,7 +2327,7 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim
2234 car_max = state->search_range / 1000; 2327 car_max = state->search_range / 1000;
2235 car_max += (car_max / 10); 2328 car_max += (car_max / 10);
2236 car_max = (65536 * car_max / 2); 2329 car_max = (65536 * car_max / 2);
2237 car_max /= (state->mclk / 1000); 2330 car_max /= (state->internal->mclk / 1000);
2238 if (car_max > 0x4000) 2331 if (car_max > 0x4000)
2239 car_max = 0x4000; 2332 car_max = 0x4000;
2240 2333
@@ -2304,7 +2397,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
2304 case STV090x_SEARCH_DVBS1: 2397 case STV090x_SEARCH_DVBS1:
2305 case STV090x_SEARCH_DSS: 2398 case STV090x_SEARCH_DSS:
2306 /* accelerate the frequency detector */ 2399 /* accelerate the frequency detector */
2307 if (state->dev_ver >= 0x20) { 2400 if (state->internal->dev_ver >= 0x20) {
2308 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) 2401 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
2309 goto err; 2402 goto err;
2310 } 2403 }
@@ -2315,7 +2408,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
2315 break; 2408 break;
2316 2409
2317 case STV090x_SEARCH_DVBS2: 2410 case STV090x_SEARCH_DVBS2:
2318 if (state->dev_ver >= 0x20) { 2411 if (state->internal->dev_ver >= 0x20) {
2319 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) 2412 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2320 goto err; 2413 goto err;
2321 } 2414 }
@@ -2328,7 +2421,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
2328 case STV090x_SEARCH_AUTO: 2421 case STV090x_SEARCH_AUTO:
2329 default: 2422 default:
2330 /* accelerate the frequency detector */ 2423 /* accelerate the frequency detector */
2331 if (state->dev_ver >= 0x20) { 2424 if (state->internal->dev_ver >= 0x20) {
2332 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) 2425 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
2333 goto err; 2426 goto err;
2334 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) 2427 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
@@ -2350,7 +2443,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
2350 /*run the SW search 2 times maximum*/ 2443 /*run the SW search 2 times maximum*/
2351 if (lock || no_signal || (trials == 2)) { 2444 if (lock || no_signal || (trials == 2)) {
2352 /*Check if the demod is not losing lock in DVBS2*/ 2445 /*Check if the demod is not losing lock in DVBS2*/
2353 if (state->dev_ver >= 0x20) { 2446 if (state->internal->dev_ver >= 0x20) {
2354 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) 2447 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
2355 goto err; 2448 goto err;
2356 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) 2449 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
@@ -2372,7 +2465,7 @@ static int stv090x_sw_algo(struct stv090x_state *state)
2372 /*FALSE lock, The demod is loosing lock */ 2465 /*FALSE lock, The demod is loosing lock */
2373 lock = 0; 2466 lock = 0;
2374 if (trials < 2) { 2467 if (trials < 2) {
2375 if (state->dev_ver >= 0x20) { 2468 if (state->internal->dev_ver >= 0x20) {
2376 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) 2469 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2377 goto err; 2470 goto err;
2378 } 2471 }
@@ -2422,11 +2515,11 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
2422 derot |= STV090x_READ_DEMOD(state, CFR0); 2515 derot |= STV090x_READ_DEMOD(state, CFR0);
2423 2516
2424 derot = comp2(derot, 24); 2517 derot = comp2(derot, 24);
2425 int_1 = state->mclk >> 12; 2518 int_1 = mclk >> 12;
2426 int_2 = derot >> 12; 2519 int_2 = derot >> 12;
2427 2520
2428 /* carrier_frequency = MasterClock * Reg / 2^24 */ 2521 /* carrier_frequency = MasterClock * Reg / 2^24 */
2429 tmp_1 = state->mclk % 0x1000; 2522 tmp_1 = mclk % 0x1000;
2430 tmp_2 = derot % 0x1000; 2523 tmp_2 = derot % 0x1000;
2431 2524
2432 derot = (int_1 * int_2) + 2525 derot = (int_1 * int_2) +
@@ -2502,13 +2595,13 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2502 2595
2503 if (state->config->tuner_get_frequency) { 2596 if (state->config->tuner_get_frequency) {
2504 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) 2597 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
2505 goto err; 2598 goto err_gateoff;
2506 } 2599 }
2507 2600
2508 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2601 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
2509 goto err; 2602 goto err;
2510 2603
2511 offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000; 2604 offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;
2512 state->frequency += offst_freq; 2605 state->frequency += offst_freq;
2513 2606
2514 if (stv090x_get_viterbi(state) < 0) 2607 if (stv090x_get_viterbi(state) < 0)
@@ -2530,7 +2623,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2530 2623
2531 if (state->config->tuner_get_frequency) { 2624 if (state->config->tuner_get_frequency) {
2532 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) 2625 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
2533 goto err; 2626 goto err_gateoff;
2534 } 2627 }
2535 2628
2536 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2629 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -2550,6 +2643,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2550 } 2643 }
2551 2644
2552 return STV090x_OUTOFRANGE; 2645 return STV090x_OUTOFRANGE;
2646
2647err_gateoff:
2648 stv090x_i2c_gate_ctrl(fe, 0);
2553err: 2649err:
2554 dprintk(FE_ERROR, 1, "I/O error"); 2650 dprintk(FE_ERROR, 1, "I/O error");
2555 return -1; 2651 return -1;
@@ -2579,7 +2675,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
2579 s32 i; 2675 s32 i;
2580 struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; 2676 struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
2581 2677
2582 if (state->dev_ver == 0x20) { 2678 if (state->internal->dev_ver == 0x20) {
2583 car_loop = stv090x_s2_crl_cut20; 2679 car_loop = stv090x_s2_crl_cut20;
2584 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; 2680 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20;
2585 car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; 2681 car_loop_apsk_low = stv090x_s2_apsk_crl_cut20;
@@ -2700,7 +2796,7 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
2700 break; 2796 break;
2701 } 2797 }
2702 2798
2703 if (state->dev_ver >= 0x30) { 2799 if (state->internal->dev_ver >= 0x30) {
2704 /* Cut 3.0 and up */ 2800 /* Cut 3.0 and up */
2705 short_crl = stv090x_s2_short_crl_cut30; 2801 short_crl = stv090x_s2_short_crl_cut30;
2706 } else { 2802 } else {
@@ -2732,7 +2828,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2732 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; 2828 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
2733 u32 reg; 2829 u32 reg;
2734 2830
2735 srate = stv090x_get_srate(state, state->mclk); 2831 srate = stv090x_get_srate(state, state->internal->mclk);
2736 srate += stv090x_get_tmgoffst(state, srate); 2832 srate += stv090x_get_tmgoffst(state, srate);
2737 2833
2738 switch (state->delsys) { 2834 switch (state->delsys) {
@@ -2751,7 +2847,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2751 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 2847 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
2752 goto err; 2848 goto err;
2753 2849
2754 if (state->dev_ver >= 0x30) { 2850 if (state->internal->dev_ver >= 0x30) {
2755 if (stv090x_get_viterbi(state) < 0) 2851 if (stv090x_get_viterbi(state) < 0)
2756 goto err; 2852 goto err;
2757 2853
@@ -2868,7 +2964,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2868 goto err; 2964 goto err;
2869 } 2965 }
2870 2966
2871 if (state->dev_ver >= 0x20) { 2967 if (state->internal->dev_ver >= 0x20) {
2872 if ((state->search_mode == STV090x_SEARCH_DVBS1) || 2968 if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
2873 (state->search_mode == STV090x_SEARCH_DSS) || 2969 (state->search_mode == STV090x_SEARCH_DSS) ||
2874 (state->search_mode == STV090x_SEARCH_AUTO)) { 2970 (state->search_mode == STV090x_SEARCH_AUTO)) {
@@ -2890,7 +2986,8 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2890 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) 2986 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
2891 goto err; 2987 goto err;
2892 2988
2893 if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { 2989 if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) ||
2990 (state->srate < 10000000)) {
2894 /* update initial carrier freq with the found freq offset */ 2991 /* update initial carrier freq with the found freq offset */
2895 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) 2992 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
2896 goto err; 2993 goto err;
@@ -2898,7 +2995,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2898 goto err; 2995 goto err;
2899 state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; 2996 state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
2900 2997
2901 if ((state->dev_ver >= 0x20) || (blind_tune == 1)) { 2998 if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) {
2902 2999
2903 if (state->algo != STV090x_WARM_SEARCH) { 3000 if (state->algo != STV090x_WARM_SEARCH) {
2904 3001
@@ -2907,7 +3004,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2907 3004
2908 if (state->config->tuner_set_bandwidth) { 3005 if (state->config->tuner_set_bandwidth) {
2909 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 3006 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
2910 goto err; 3007 goto err_gateoff;
2911 } 3008 }
2912 3009
2913 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 3010 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -2950,7 +3047,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2950 3047
2951 } 3048 }
2952 3049
2953 if (state->dev_ver >= 0x20) { 3050 if (state->internal->dev_ver >= 0x20) {
2954 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) 3051 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
2955 goto err; 3052 goto err;
2956 } 3053 }
@@ -2959,6 +3056,9 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2959 stv090x_set_vit_thtracq(state); 3056 stv090x_set_vit_thtracq(state);
2960 3057
2961 return 0; 3058 return 0;
3059
3060err_gateoff:
3061 stv090x_i2c_gate_ctrl(fe, 0);
2962err: 3062err:
2963 dprintk(FE_ERROR, 1, "I/O error"); 3063 dprintk(FE_ERROR, 1, "I/O error");
2964 return -1; 3064 return -1;
@@ -3026,7 +3126,7 @@ static int stv090x_set_s2rolloff(struct stv090x_state *state)
3026{ 3126{
3027 u32 reg; 3127 u32 reg;
3028 3128
3029 if (state->dev_ver <= 0x20) { 3129 if (state->internal->dev_ver <= 0x20) {
3030 /* rolloff to auto mode if DVBS2 */ 3130 /* rolloff to auto mode if DVBS2 */
3031 reg = STV090x_READ_DEMOD(state, DEMOD); 3131 reg = STV090x_READ_DEMOD(state, DEMOD);
3032 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); 3132 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
@@ -3062,7 +3162,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3062 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ 3162 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
3063 goto err; 3163 goto err;
3064 3164
3065 if (state->dev_ver >= 0x20) { 3165 if (state->internal->dev_ver >= 0x20) {
3066 if (state->srate > 5000000) { 3166 if (state->srate > 5000000) {
3067 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) 3167 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
3068 goto err; 3168 goto err;
@@ -3102,7 +3202,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3102 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 3202 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
3103 goto err; 3203 goto err;
3104 3204
3105 if (state->dev_ver >= 0x20) { 3205 if (state->internal->dev_ver >= 0x20) {
3106 if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) 3206 if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
3107 goto err; 3207 goto err;
3108 if (state->algo == STV090x_COLD_SEARCH) 3208 if (state->algo == STV090x_COLD_SEARCH)
@@ -3120,9 +3220,11 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3120 if (stv090x_set_srate(state, state->srate) < 0) 3220 if (stv090x_set_srate(state, state->srate) < 0)
3121 goto err; 3221 goto err;
3122 3222
3123 if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0) 3223 if (stv090x_set_max_srate(state, state->internal->mclk,
3224 state->srate) < 0)
3124 goto err; 3225 goto err;
3125 if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0) 3226 if (stv090x_set_min_srate(state, state->internal->mclk,
3227 state->srate) < 0)
3126 goto err; 3228 goto err;
3127 3229
3128 if (state->srate >= 10000000) 3230 if (state->srate >= 10000000)
@@ -3136,18 +3238,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3136 goto err; 3238 goto err;
3137 3239
3138 if (state->config->tuner_set_bbgain) { 3240 if (state->config->tuner_set_bbgain) {
3139 if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */ 3241 reg = state->config->tuner_bbgain;
3140 goto err; 3242 if (reg == 0)
3243 reg = 10; /* default: 10dB */
3244 if (state->config->tuner_set_bbgain(fe, reg) < 0)
3245 goto err_gateoff;
3141 } 3246 }
3142 3247
3143 if (state->config->tuner_set_frequency) { 3248 if (state->config->tuner_set_frequency) {
3144 if (state->config->tuner_set_frequency(fe, state->frequency) < 0) 3249 if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
3145 goto err; 3250 goto err_gateoff;
3146 } 3251 }
3147 3252
3148 if (state->config->tuner_set_bandwidth) { 3253 if (state->config->tuner_set_bandwidth) {
3149 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 3254 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
3150 goto err; 3255 goto err_gateoff;
3151 } 3256 }
3152 3257
3153 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 3258 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -3155,21 +3260,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3155 3260
3156 msleep(50); 3261 msleep(50);
3157 3262
3158 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
3159 goto err;
3160
3161 if (state->config->tuner_get_status) { 3263 if (state->config->tuner_get_status) {
3264 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
3265 goto err;
3162 if (state->config->tuner_get_status(fe, &reg) < 0) 3266 if (state->config->tuner_get_status(fe, &reg) < 0)
3267 goto err_gateoff;
3268 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
3163 goto err; 3269 goto err;
3164 }
3165 3270
3166 if (reg) 3271 if (reg)
3167 dprintk(FE_DEBUG, 1, "Tuner phase locked"); 3272 dprintk(FE_DEBUG, 1, "Tuner phase locked");
3168 else 3273 else {
3169 dprintk(FE_DEBUG, 1, "Tuner unlocked"); 3274 dprintk(FE_DEBUG, 1, "Tuner unlocked");
3170 3275 return STV090x_NOCARRIER;
3171 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 3276 }
3172 goto err; 3277 }
3173 3278
3174 msleep(10); 3279 msleep(10);
3175 agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), 3280 agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
@@ -3194,7 +3299,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3194 reg = STV090x_READ_DEMOD(state, DEMOD); 3299 reg = STV090x_READ_DEMOD(state, DEMOD);
3195 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); 3300 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
3196 3301
3197 if (state->dev_ver <= 0x20) { 3302 if (state->internal->dev_ver <= 0x20) {
3198 /* rolloff to auto mode if DVBS2 */ 3303 /* rolloff to auto mode if DVBS2 */
3199 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); 3304 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
3200 } else { 3305 } else {
@@ -3238,7 +3343,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3238 if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ 3343 if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
3239 stv090x_optimize_track(state); 3344 stv090x_optimize_track(state);
3240 3345
3241 if (state->dev_ver >= 0x20) { 3346 if (state->internal->dev_ver >= 0x20) {
3242 /* >= Cut 2.0 :release TS reset after 3347 /* >= Cut 2.0 :release TS reset after
3243 * demod lock and optimized Tracking 3348 * demod lock and optimized Tracking
3244 */ 3349 */
@@ -3293,6 +3398,8 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3293 } 3398 }
3294 return signal_state; 3399 return signal_state;
3295 3400
3401err_gateoff:
3402 stv090x_i2c_gate_ctrl(fe, 0);
3296err: 3403err:
3297 dprintk(FE_ERROR, 1, "I/O error"); 3404 dprintk(FE_ERROR, 1, "I/O error");
3298 return -1; 3405 return -1;
@@ -3303,6 +3410,9 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
3303 struct stv090x_state *state = fe->demodulator_priv; 3410 struct stv090x_state *state = fe->demodulator_priv;
3304 struct dtv_frontend_properties *props = &fe->dtv_property_cache; 3411 struct dtv_frontend_properties *props = &fe->dtv_property_cache;
3305 3412
3413 if (p->frequency == 0)
3414 return DVBFE_ALGO_SEARCH_INVALID;
3415
3306 state->delsys = props->delivery_system; 3416 state->delsys = props->delivery_system;
3307 state->frequency = p->frequency; 3417 state->frequency = p->frequency;
3308 state->srate = p->u.qpsk.symbol_rate; 3418 state->srate = p->u.qpsk.symbol_rate;
@@ -3353,7 +3463,8 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
3353 if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { 3463 if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
3354 reg = STV090x_READ_DEMOD(state, TSSTATUS); 3464 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3355 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { 3465 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3356 *status = FE_HAS_CARRIER | 3466 *status = FE_HAS_SIGNAL |
3467 FE_HAS_CARRIER |
3357 FE_HAS_VITERBI | 3468 FE_HAS_VITERBI |
3358 FE_HAS_SYNC | 3469 FE_HAS_SYNC |
3359 FE_HAS_LOCK; 3470 FE_HAS_LOCK;
@@ -3370,7 +3481,11 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
3370 if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { 3481 if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
3371 reg = STV090x_READ_DEMOD(state, TSSTATUS); 3482 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3372 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { 3483 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3373 *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 3484 *status = FE_HAS_SIGNAL |
3485 FE_HAS_CARRIER |
3486 FE_HAS_VITERBI |
3487 FE_HAS_SYNC |
3488 FE_HAS_LOCK;
3374 } 3489 }
3375 } 3490 }
3376 } 3491 }
@@ -3770,6 +3885,15 @@ static void stv090x_release(struct dvb_frontend *fe)
3770{ 3885{
3771 struct stv090x_state *state = fe->demodulator_priv; 3886 struct stv090x_state *state = fe->demodulator_priv;
3772 3887
3888 state->internal->num_used--;
3889 if (state->internal->num_used <= 0) {
3890
3891 dprintk(FE_ERROR, 1, "Actually removing");
3892
3893 remove_dev(state->internal);
3894 kfree(state->internal);
3895 }
3896
3773 kfree(state); 3897 kfree(state);
3774} 3898}
3775 3899
@@ -3901,10 +4025,10 @@ static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
3901 if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) 4025 if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
3902 goto err; 4026 goto err;
3903 4027
3904 state->mclk = stv090x_get_mclk(state); 4028 state->internal->mclk = stv090x_get_mclk(state);
3905 4029
3906 /*Set the DiseqC frequency to 22KHz */ 4030 /*Set the DiseqC frequency to 22KHz */
3907 div = state->mclk / 704000; 4031 div = state->internal->mclk / 704000;
3908 if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) 4032 if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
3909 goto err; 4033 goto err;
3910 if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) 4034 if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
@@ -3920,7 +4044,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
3920{ 4044{
3921 u32 reg; 4045 u32 reg;
3922 4046
3923 if (state->dev_ver >= 0x20) { 4047 if (state->internal->dev_ver >= 0x20) {
3924 switch (state->config->ts1_mode) { 4048 switch (state->config->ts1_mode) {
3925 case STV090x_TSMODE_PARALLEL_PUNCTURED: 4049 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3926 case STV090x_TSMODE_DVBCI: 4050 case STV090x_TSMODE_DVBCI:
@@ -4092,6 +4216,71 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4092 default: 4216 default:
4093 break; 4217 break;
4094 } 4218 }
4219
4220 if (state->config->ts1_clk > 0) {
4221 u32 speed;
4222
4223 switch (state->config->ts1_mode) {
4224 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4225 case STV090x_TSMODE_DVBCI:
4226 default:
4227 speed = state->internal->mclk /
4228 (state->config->ts1_clk / 4);
4229 if (speed < 0x08)
4230 speed = 0x08;
4231 if (speed > 0xFF)
4232 speed = 0xFF;
4233 break;
4234 case STV090x_TSMODE_SERIAL_PUNCTURED:
4235 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4236 speed = state->internal->mclk /
4237 (state->config->ts1_clk / 32);
4238 if (speed < 0x20)
4239 speed = 0x20;
4240 if (speed > 0xFF)
4241 speed = 0xFF;
4242 break;
4243 }
4244 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
4245 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4246 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
4247 goto err;
4248 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
4249 goto err;
4250 }
4251
4252 if (state->config->ts2_clk > 0) {
4253 u32 speed;
4254
4255 switch (state->config->ts2_mode) {
4256 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4257 case STV090x_TSMODE_DVBCI:
4258 default:
4259 speed = state->internal->mclk /
4260 (state->config->ts2_clk / 4);
4261 if (speed < 0x08)
4262 speed = 0x08;
4263 if (speed > 0xFF)
4264 speed = 0xFF;
4265 break;
4266 case STV090x_TSMODE_SERIAL_PUNCTURED:
4267 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4268 speed = state->internal->mclk /
4269 (state->config->ts2_clk / 32);
4270 if (speed < 0x20)
4271 speed = 0x20;
4272 if (speed > 0xFF)
4273 speed = 0xFF;
4274 break;
4275 }
4276 reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
4277 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4278 if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
4279 goto err;
4280 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)
4281 goto err;
4282 }
4283
4095 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4284 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4096 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); 4285 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
4097 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4286 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4120,6 +4309,15 @@ static int stv090x_init(struct dvb_frontend *fe)
4120 const struct stv090x_config *config = state->config; 4309 const struct stv090x_config *config = state->config;
4121 u32 reg; 4310 u32 reg;
4122 4311
4312 if (state->internal->mclk == 0) {
4313 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
4314 msleep(5);
4315 if (stv090x_write_reg(state, STV090x_SYNTCTRL,
4316 0x20 | config->clk_mode) < 0)
4317 goto err;
4318 stv090x_get_mclk(state);
4319 }
4320
4123 if (stv090x_wakeup(fe) < 0) { 4321 if (stv090x_wakeup(fe) < 0) {
4124 dprintk(FE_ERROR, 1, "Error waking device"); 4322 dprintk(FE_ERROR, 1, "Error waking device");
4125 goto err; 4323 goto err;
@@ -4142,12 +4340,12 @@ static int stv090x_init(struct dvb_frontend *fe)
4142 4340
4143 if (config->tuner_set_mode) { 4341 if (config->tuner_set_mode) {
4144 if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) 4342 if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
4145 goto err; 4343 goto err_gateoff;
4146 } 4344 }
4147 4345
4148 if (config->tuner_init) { 4346 if (config->tuner_init) {
4149 if (config->tuner_init(fe) < 0) 4347 if (config->tuner_init(fe) < 0)
4150 goto err; 4348 goto err_gateoff;
4151 } 4349 }
4152 4350
4153 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 4351 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
@@ -4157,6 +4355,9 @@ static int stv090x_init(struct dvb_frontend *fe)
4157 goto err; 4355 goto err;
4158 4356
4159 return 0; 4357 return 0;
4358
4359err_gateoff:
4360 stv090x_i2c_gate_ctrl(fe, 0);
4160err: 4361err:
4161 dprintk(FE_ERROR, 1, "I/O error"); 4362 dprintk(FE_ERROR, 1, "I/O error");
4162 return -1; 4363 return -1;
@@ -4188,16 +4389,26 @@ static int stv090x_setup(struct dvb_frontend *fe)
4188 } 4389 }
4189 4390
4190 /* STV090x init */ 4391 /* STV090x init */
4191 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */ 4392
4393 /* Stop Demod */
4394 if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
4395 goto err;
4396 if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
4192 goto err; 4397 goto err;
4193 4398
4194 msleep(5); 4399 msleep(5);
4195 4400
4196 if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */ 4401 /* Set No Tuner Mode */
4402 if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
4403 goto err;
4404 if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
4197 goto err; 4405 goto err;
4198 4406
4407 /* I2C repeater OFF */
4199 STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); 4408 STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
4200 if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */ 4409 if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
4410 goto err;
4411 if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
4201 goto err; 4412 goto err;
4202 4413
4203 if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ 4414 if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
@@ -4216,8 +4427,8 @@ static int stv090x_setup(struct dvb_frontend *fe)
4216 goto err; 4427 goto err;
4217 } 4428 }
4218 4429
4219 state->dev_ver = stv090x_read_reg(state, STV090x_MID); 4430 state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);
4220 if (state->dev_ver >= 0x20) { 4431 if (state->internal->dev_ver >= 0x20) {
4221 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) 4432 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
4222 goto err; 4433 goto err;
4223 4434
@@ -4228,27 +4439,35 @@ static int stv090x_setup(struct dvb_frontend *fe)
4228 goto err; 4439 goto err;
4229 } 4440 }
4230 4441
4231 } else if (state->dev_ver < 0x20) { 4442 } else if (state->internal->dev_ver < 0x20) {
4232 dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", 4443 dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
4233 state->dev_ver); 4444 state->internal->dev_ver);
4234 4445
4235 goto err; 4446 goto err;
4236 } else if (state->dev_ver > 0x30) { 4447 } else if (state->internal->dev_ver > 0x30) {
4237 /* we shouldn't bail out from here */ 4448 /* we shouldn't bail out from here */
4238 dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", 4449 dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
4239 state->dev_ver); 4450 state->internal->dev_ver);
4240 } 4451 }
4241 4452
4242 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) 4453 /* ADC1 range */
4454 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
4455 STV090x_SETFIELD(reg, ADC1_INMODE_FIELD,
4456 (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1);
4457 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
4243 goto err; 4458 goto err;
4244 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) 4459
4460 /* ADC2 range */
4461 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
4462 STV090x_SETFIELD(reg, ADC2_INMODE_FIELD,
4463 (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1);
4464 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
4245 goto err; 4465 goto err;
4246 4466
4247 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ 4467 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
4248 msleep(5); 4468 goto err;
4249 if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) 4469 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
4250 goto err; 4470 goto err;
4251 stv090x_get_mclk(state);
4252 4471
4253 return 0; 4472 return 0;
4254err: 4473err:
@@ -4299,6 +4518,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4299 enum stv090x_demodulator demod) 4518 enum stv090x_demodulator demod)
4300{ 4519{
4301 struct stv090x_state *state = NULL; 4520 struct stv090x_state *state = NULL;
4521 struct stv090x_dev *temp_int;
4302 4522
4303 state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); 4523 state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
4304 if (state == NULL) 4524 if (state == NULL)
@@ -4314,8 +4534,32 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4314 state->device = config->device; 4534 state->device = config->device;
4315 state->rolloff = STV090x_RO_35; /* default */ 4535 state->rolloff = STV090x_RO_35; /* default */
4316 4536
4317 if (state->demod == STV090x_DEMODULATOR_0) 4537 temp_int = find_dev(state->i2c,
4318 mutex_init(&demod_lock); 4538 state->config->address);
4539
4540 if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) {
4541 state->internal = temp_int->internal;
4542 state->internal->num_used++;
4543 dprintk(FE_INFO, 1, "Found Internal Structure!");
4544 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4545 state->device == STV0900 ? "STV0900" : "STV0903",
4546 demod,
4547 state->internal->dev_ver);
4548 return &state->frontend;
4549 } else {
4550 state->internal = kmalloc(sizeof(struct stv090x_internal),
4551 GFP_KERNEL);
4552 temp_int = append_internal(state->internal);
4553 state->internal->num_used = 1;
4554 state->internal->mclk = 0;
4555 state->internal->dev_ver = 0;
4556 state->internal->i2c_adap = state->i2c;
4557 state->internal->i2c_addr = state->config->address;
4558 dprintk(FE_INFO, 1, "Create New Internal Structure!");
4559 }
4560
4561 mutex_init(&state->internal->demod_lock);
4562 mutex_init(&state->internal->tuner_lock);
4319 4563
4320 if (stv090x_sleep(&state->frontend) < 0) { 4564 if (stv090x_sleep(&state->frontend) < 0) {
4321 dprintk(FE_ERROR, 1, "Error putting device to sleep"); 4565 dprintk(FE_ERROR, 1, "Error putting device to sleep");
@@ -4331,10 +4575,10 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4331 goto error; 4575 goto error;
4332 } 4576 }
4333 4577
4334 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n", 4578 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4335 state->device == STV0900 ? "STV0900" : "STV0903", 4579 state->device == STV0900 ? "STV0900" : "STV0903",
4336 demod, 4580 demod,
4337 state->dev_ver); 4581 state->internal->dev_ver);
4338 4582
4339 return &state->frontend; 4583 return &state->frontend;
4340 4584
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
index b133807663ea..30f01a6902ac 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -60,6 +60,11 @@ enum stv090x_i2crpt {
60 STV090x_RPTLEVEL_2 = 7, 60 STV090x_RPTLEVEL_2 = 7,
61}; 61};
62 62
63enum stv090x_adc_range {
64 STV090x_ADC_2Vpp = 0,
65 STV090x_ADC_1Vpp = 1
66};
67
63struct stv090x_config { 68struct stv090x_config {
64 enum stv090x_device device; 69 enum stv090x_device device;
65 enum stv090x_mode demod_mode; 70 enum stv090x_mode demod_mode;
@@ -68,13 +73,17 @@ struct stv090x_config {
68 u32 xtal; /* default: 8000000 */ 73 u32 xtal; /* default: 8000000 */
69 u8 address; /* default: 0x68 */ 74 u8 address; /* default: 0x68 */
70 75
71 u32 ref_clk; /* default: 16000000 FIXME to tuner config */
72
73 u8 ts1_mode; 76 u8 ts1_mode;
74 u8 ts2_mode; 77 u8 ts2_mode;
78 u32 ts1_clk;
79 u32 ts2_clk;
75 80
76 enum stv090x_i2crpt repeater_level; 81 enum stv090x_i2crpt repeater_level;
77 82
83 u8 tuner_bbgain; /* default: 10db */
84 enum stv090x_adc_range adc1_range; /* default: 2Vpp */
85 enum stv090x_adc_range adc2_range; /* default: 2Vpp */
86
78 bool diseqc_envelope_mode; 87 bool diseqc_envelope_mode;
79 88
80 int (*tuner_init) (struct dvb_frontend *fe); 89 int (*tuner_init) (struct dvb_frontend *fe);
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
index 5921a8d6c89f..5b780c80d496 100644
--- a/drivers/media/dvb/frontends/stv090x_priv.h
+++ b/drivers/media/dvb/frontends/stv090x_priv.h
@@ -230,11 +230,23 @@ struct stv090x_tab {
230 s32 read; 230 s32 read;
231}; 231};
232 232
233struct stv090x_internal {
234 struct i2c_adapter *i2c_adap;
235 u8 i2c_addr;
236
237 struct mutex demod_lock; /* Lock access to shared register */
238 struct mutex tuner_lock; /* Lock access to tuners */
239 s32 mclk; /* Masterclock Divider factor */
240 u32 dev_ver;
241
242 int num_used;
243};
244
233struct stv090x_state { 245struct stv090x_state {
234 enum stv090x_device device; 246 enum stv090x_device device;
235 enum stv090x_demodulator demod; 247 enum stv090x_demodulator demod;
236 enum stv090x_mode demod_mode; 248 enum stv090x_mode demod_mode;
237 u32 dev_ver; 249 struct stv090x_internal *internal;
238 250
239 struct i2c_adapter *i2c; 251 struct i2c_adapter *i2c;
240 const struct stv090x_config *config; 252 const struct stv090x_config *config;
@@ -256,11 +268,8 @@ struct stv090x_state {
256 u32 frequency; 268 u32 frequency;
257 u32 srate; 269 u32 srate;
258 270
259 s32 mclk; /* Masterclock Divider factor */
260 s32 tuner_bw; 271 s32 tuner_bw;
261 272
262 u32 tuner_refclk;
263
264 s32 search_range; 273 s32 search_range;
265 274
266 s32 DemodTimeout; 275 s32 DemodTimeout;
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index bcfcb652464c..f931ed07e92d 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -35,8 +35,6 @@ static unsigned int verbose;
35module_param(verbose, int, 0644); 35module_param(verbose, int, 0644);
36MODULE_PARM_DESC(verbose, "Set Verbosity level"); 36MODULE_PARM_DESC(verbose, "Set Verbosity level");
37 37
38static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
39
40static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) 38static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
41{ 39{
42 int ret; 40 int ret;
@@ -58,12 +56,23 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
58 return 0; 56 return 0;
59} 57}
60 58
61static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) 59static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
62{ 60{
63 int ret; 61 int ret;
64 const struct stv6110x_config *config = stv6110x->config; 62 const struct stv6110x_config *config = stv6110x->config;
65 u8 buf[] = { reg, data }; 63 u8 buf[len + 1];
66 struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 }; 64 struct i2c_msg msg = {
65 .addr = config->addr,
66 .flags = 0,
67 .buf = buf,
68 .len = len + 1
69 };
70
71 if (start + len > 8)
72 return -EINVAL;
73
74 buf[0] = start;
75 memcpy(&buf[1], data, len);
67 76
68 ret = i2c_transfer(stv6110x->i2c, &msg, 1); 77 ret = i2c_transfer(stv6110x->i2c, &msg, 1);
69 if (ret != 1) { 78 if (ret != 1) {
@@ -74,18 +83,21 @@ static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
74 return 0; 83 return 0;
75} 84}
76 85
86static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
87{
88 return stv6110x_write_regs(stv6110x, reg, &data, 1);
89}
90
77static int stv6110x_init(struct dvb_frontend *fe) 91static int stv6110x_init(struct dvb_frontend *fe)
78{ 92{
79 struct stv6110x_state *stv6110x = fe->tuner_priv; 93 struct stv6110x_state *stv6110x = fe->tuner_priv;
80 int ret; 94 int ret;
81 u8 i;
82 95
83 for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) { 96 ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
84 ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]); 97 ARRAY_SIZE(stv6110x->regs));
85 if (ret < 0) { 98 if (ret < 0) {
86 dprintk(FE_ERROR, 1, "Initialization failed"); 99 dprintk(FE_ERROR, 1, "Initialization failed");
87 return -1; 100 return -1;
88 }
89 } 101 }
90 102
91 return 0; 103 return 0;
@@ -98,23 +110,23 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
98 s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; 110 s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
99 u8 i; 111 u8 i;
100 112
101 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); 113 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
102 114
103 if (frequency <= 1023000) { 115 if (frequency <= 1023000) {
104 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); 116 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
105 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); 117 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
106 pVal = 40; 118 pVal = 40;
107 } else if (frequency <= 1300000) { 119 } else if (frequency <= 1300000) {
108 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); 120 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
109 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); 121 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
110 pVal = 40; 122 pVal = 40;
111 } else if (frequency <= 2046000) { 123 } else if (frequency <= 2046000) {
112 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); 124 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
113 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); 125 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
114 pVal = 20; 126 pVal = 20;
115 } else { 127 } else {
116 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); 128 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
117 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); 129 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
118 pVal = 20; 130 pVal = 20;
119 } 131 }
120 132
@@ -130,21 +142,21 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
130 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; 142 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
131 divider = (divider + 5) / 10; 143 divider = (divider + 5) / 10;
132 144
133 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); 145 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
134 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); 146 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
135 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); 147 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
136 148
137 /* VCO Auto calibration */ 149 /* VCO Auto calibration */
138 STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); 150 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
139 151
140 stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); 152 stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
141 stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]); 153 stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
142 stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]); 154 stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
143 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); 155 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
144 156
145 for (i = 0; i < TRIALS; i++) { 157 for (i = 0; i < TRIALS; i++) {
146 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); 158 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
147 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1])) 159 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
148 break; 160 break;
149 msleep(1); 161 msleep(1);
150 } 162 }
@@ -156,14 +168,14 @@ static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
156{ 168{
157 struct stv6110x_state *stv6110x = fe->tuner_priv; 169 struct stv6110x_state *stv6110x = fe->tuner_priv;
158 170
159 stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]); 171 stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
160 stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]); 172 stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
161 173
162 *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]), 174 *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
163 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz; 175 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
164 176
165 *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) + 177 *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
166 STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1]))); 178 STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
167 179
168 *frequency >>= 2; 180 *frequency >>= 2;
169 181
@@ -179,27 +191,27 @@ static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
179 halfbw = bandwidth >> 1; 191 halfbw = bandwidth >> 1;
180 192
181 if (halfbw > 36000000) 193 if (halfbw > 36000000)
182 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ 194 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
183 else if (halfbw < 5000000) 195 else if (halfbw < 5000000)
184 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ 196 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
185 else 197 else
186 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ 198 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
187 199
188 200
189 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ 201 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
190 STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ 202 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
191 203
192 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); 204 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
193 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); 205 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
194 206
195 for (i = 0; i < TRIALS; i++) { 207 for (i = 0; i < TRIALS; i++) {
196 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); 208 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
197 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1])) 209 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
198 break; 210 break;
199 msleep(1); 211 msleep(1);
200 } 212 }
201 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ 213 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
202 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); 214 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
203 215
204 return 0; 216 return 0;
205} 217}
@@ -208,8 +220,8 @@ static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
208{ 220{
209 struct stv6110x_state *stv6110x = fe->tuner_priv; 221 struct stv6110x_state *stv6110x = fe->tuner_priv;
210 222
211 stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]); 223 stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
212 *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000; 224 *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
213 225
214 return 0; 226 return 0;
215} 227}
@@ -222,20 +234,20 @@ static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
222 switch (refclock) { 234 switch (refclock) {
223 default: 235 default:
224 case 1: 236 case 1:
225 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); 237 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
226 break; 238 break;
227 case 2: 239 case 2:
228 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); 240 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
229 break; 241 break;
230 case 4: 242 case 4:
231 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); 243 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
232 break; 244 break;
233 case 8: 245 case 8:
234 case 0: 246 case 0:
235 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); 247 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
236 break; 248 break;
237 } 249 }
238 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); 250 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
239 251
240 return 0; 252 return 0;
241} 253}
@@ -244,8 +256,8 @@ static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
244{ 256{
245 struct stv6110x_state *stv6110x = fe->tuner_priv; 257 struct stv6110x_state *stv6110x = fe->tuner_priv;
246 258
247 stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]); 259 stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
248 *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]); 260 *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
249 261
250 return 0; 262 return 0;
251} 263}
@@ -254,8 +266,8 @@ static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
254{ 266{
255 struct stv6110x_state *stv6110x = fe->tuner_priv; 267 struct stv6110x_state *stv6110x = fe->tuner_priv;
256 268
257 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); 269 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
258 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); 270 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
259 271
260 return 0; 272 return 0;
261} 273}
@@ -267,19 +279,19 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
267 279
268 switch (mode) { 280 switch (mode) {
269 case TUNER_SLEEP: 281 case TUNER_SLEEP:
270 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0); 282 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
271 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0); 283 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
272 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0); 284 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
273 break; 285 break;
274 286
275 case TUNER_WAKE: 287 case TUNER_WAKE:
276 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1); 288 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
277 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1); 289 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
278 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1); 290 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
279 break; 291 break;
280 } 292 }
281 293
282 ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); 294 ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
283 if (ret < 0) { 295 if (ret < 0) {
284 dprintk(FE_ERROR, 1, "I/O Error"); 296 dprintk(FE_ERROR, 1, "I/O Error");
285 return -EIO; 297 return -EIO;
@@ -297,9 +309,9 @@ static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
297{ 309{
298 struct stv6110x_state *stv6110x = fe->tuner_priv; 310 struct stv6110x_state *stv6110x = fe->tuner_priv;
299 311
300 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); 312 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
301 313
302 if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1])) 314 if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
303 *status = TUNER_PHASELOCKED; 315 *status = TUNER_PHASELOCKED;
304 else 316 else
305 *status = 0; 317 *status = 0;
@@ -349,6 +361,8 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
349 struct i2c_adapter *i2c) 361 struct i2c_adapter *i2c)
350{ 362{
351 struct stv6110x_state *stv6110x; 363 struct stv6110x_state *stv6110x;
364 u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
365 int ret;
352 366
353 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); 367 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
354 if (stv6110x == NULL) 368 if (stv6110x == NULL)
@@ -357,6 +371,44 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
357 stv6110x->i2c = i2c; 371 stv6110x->i2c = i2c;
358 stv6110x->config = config; 372 stv6110x->config = config;
359 stv6110x->devctl = &stv6110x_ctl; 373 stv6110x->devctl = &stv6110x_ctl;
374 memcpy(stv6110x->regs, default_regs, 8);
375
376 /* setup divider */
377 switch (stv6110x->config->clk_div) {
378 default:
379 case 1:
380 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
381 break;
382 case 2:
383 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
384 break;
385 case 4:
386 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
387 break;
388 case 8:
389 case 0:
390 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
391 break;
392 }
393
394 if (fe->ops.i2c_gate_ctrl) {
395 ret = fe->ops.i2c_gate_ctrl(fe, 1);
396 if (ret < 0)
397 goto error;
398 }
399
400 ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
401 ARRAY_SIZE(stv6110x->regs));
402 if (ret < 0) {
403 dprintk(FE_ERROR, 1, "Initialization failed");
404 goto error;
405 }
406
407 if (fe->ops.i2c_gate_ctrl) {
408 ret = fe->ops.i2c_gate_ctrl(fe, 0);
409 if (ret < 0)
410 goto error;
411 }
360 412
361 fe->tuner_priv = stv6110x; 413 fe->tuner_priv = stv6110x;
362 fe->ops.tuner_ops = stv6110x_ops; 414 fe->ops.tuner_ops = stv6110x_ops;
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
index a38257080e01..2429ae6d7847 100644
--- a/drivers/media/dvb/frontends/stv6110x.h
+++ b/drivers/media/dvb/frontends/stv6110x.h
@@ -26,6 +26,7 @@
26struct stv6110x_config { 26struct stv6110x_config {
27 u8 addr; 27 u8 addr;
28 u32 refclk; 28 u32 refclk;
29 u8 clk_div; /* divisor value for the output clock */
29}; 30};
30 31
31enum tuner_mode { 32enum tuner_mode {
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h
index 7260da633d49..0ec936a660a7 100644
--- a/drivers/media/dvb/frontends/stv6110x_priv.h
+++ b/drivers/media/dvb/frontends/stv6110x_priv.h
@@ -68,6 +68,7 @@
68struct stv6110x_state { 68struct stv6110x_state {
69 struct i2c_adapter *i2c; 69 struct i2c_adapter *i2c;
70 const struct stv6110x_config *config; 70 const struct stv6110x_config *config;
71 u8 regs[8];
71 72
72 struct stv6110x_devctl *devctl; 73 struct stv6110x_devctl *devctl;
73}; 74};
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c
index 87d52739c828..c44fefe92d97 100644
--- a/drivers/media/dvb/frontends/tda665x.c
+++ b/drivers/media/dvb/frontends/tda665x.c
@@ -133,7 +133,7 @@ static int tda665x_set_state(struct dvb_frontend *fe,
133 frequency += config->ref_divider >> 1; 133 frequency += config->ref_divider >> 1;
134 frequency /= config->ref_divider; 134 frequency /= config->ref_divider;
135 135
136 buf[0] = (u8) (frequency & 0x7f00) >> 8; 136 buf[0] = (u8) ((frequency & 0x7f00) >> 8);
137 buf[1] = (u8) (frequency & 0x00ff) >> 0; 137 buf[1] = (u8) (frequency & 0x00ff) >> 0;
138 buf[2] = 0x80 | 0x40 | 0x02; 138 buf[2] = 0x80 | 0x40 | 0x02;
139 buf[3] = 0x00; 139 buf[3] = 0x00;
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
index 320c3c36d8b2..614afcec05f1 100644
--- a/drivers/media/dvb/frontends/tda8261.c
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -39,7 +39,7 @@ static int tda8261_read(struct tda8261_state *state, u8 *buf)
39{ 39{
40 const struct tda8261_config *config = state->config; 40 const struct tda8261_config *config = state->config;
41 int err = 0; 41 int err = 0;
42 struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 }; 42 struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 1 };
43 43
44 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) 44 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
45 printk("%s: read error, err=%d\n", __func__, err); 45 printk("%s: read error, err=%d\n", __func__, err);
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
index 4e814ff22b23..34c5de491d2b 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -411,7 +411,7 @@ static int zl10036_init_regs(struct zl10036_state *state)
411 state->bf = 0xff; 411 state->bf = 0xff;
412 412
413 if (!state->config->rf_loop_enable) 413 if (!state->config->rf_loop_enable)
414 zl10036_init_tab[1][2] |= 0x01; 414 zl10036_init_tab[1][0] |= 0x01;
415 415
416 deb_info("%s\n", __func__); 416 deb_info("%s\n", __func__);
417 417
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c
index 11b29cb883e6..c085e58a94bf 100644
--- a/drivers/media/dvb/frontends/zl10039.c
+++ b/drivers/media/dvb/frontends/zl10039.c
@@ -287,7 +287,6 @@ struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
287 break; 287 break;
288 default: 288 default:
289 dprintk("Chip ID=%x does not match a known type\n", state->id); 289 dprintk("Chip ID=%x does not match a known type\n", state->id);
290 break;
291 goto error; 290 goto error;
292 } 291 }
293 292
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c
index 7477dac628b4..5772ebb3a69e 100644
--- a/drivers/media/dvb/mantis/mantis_hif.c
+++ b/drivers/media/dvb/mantis/mantis_hif.c
@@ -22,8 +22,6 @@
22#include <linux/signal.h> 22#include <linux/signal.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24 24
25#include <linux/signal.h>
26#include <linux/sched.h>
27#include <linux/interrupt.h> 25#include <linux/interrupt.h>
28 26
29#include "dmxdev.h" 27#include "dmxdev.h"
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index 6a9df779441f..4675a3b53c7d 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -126,7 +126,7 @@ int mantis_input_init(struct mantis_pci *mantis)
126 rc->id.version = 1; 126 rc->id.version = 1;
127 rc->dev = mantis->pdev->dev; 127 rc->dev = mantis->pdev->dev;
128 128
129 err = ir_input_register(rc, &ir_mantis); 129 err = ir_input_register(rc, &ir_mantis, NULL);
130 if (err) { 130 if (err) {
131 dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); 131 dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
132 input_free_device(rc); 132 input_free_device(rc);
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c
index 6c7534af6b44..59feeb84aec7 100644
--- a/drivers/media/dvb/mantis/mantis_pci.c
+++ b/drivers/media/dvb/mantis/mantis_pci.c
@@ -41,11 +41,6 @@
41#include "dvb_frontend.h" 41#include "dvb_frontend.h"
42#include "dvb_net.h" 42#include "dvb_net.h"
43 43
44#include <asm/irq.h>
45#include <linux/signal.h>
46#include <linux/sched.h>
47#include <linux/interrupt.h>
48
49#include "mantis_common.h" 44#include "mantis_common.h"
50#include "mantis_reg.h" 45#include "mantis_reg.h"
51#include "mantis_pci.h" 46#include "mantis_pci.h"
diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig
new file mode 100644
index 000000000000..3ec8e6fcbb1d
--- /dev/null
+++ b/drivers/media/dvb/ngene/Kconfig
@@ -0,0 +1,9 @@
1config DVB_NGENE
2 tristate "Micronas nGene support"
3 depends on DVB_CORE && PCI && I2C
4 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
5 select DVB_STV6110x if !DVB_FE_CUSTOMISE
6 select DVB_STV090x if !DVB_FE_CUSTOMISE
7 ---help---
8 Support for Micronas PCI express cards with nGene bridge.
9
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
new file mode 100644
index 000000000000..40435cad4819
--- /dev/null
+++ b/drivers/media/dvb/ngene/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the nGene device driver
3#
4
5ngene-objs := ngene-core.o
6
7obj-$(CONFIG_DVB_NGENE) += ngene.o
8
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
11
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
new file mode 100644
index 000000000000..0150dfe7cfbb
--- /dev/null
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -0,0 +1,2024 @@
1/*
2 * ngene.c: nGene PCIe bridge driver
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
7 * Modifications for new nGene firmware,
8 * support for EEPROM-copying,
9 * support for new dual DVB-S2 card prototype
10 *
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 only, as published by the Free Software Foundation.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * 02110-1301, USA
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/slab.h>
34#include <linux/poll.h>
35#include <linux/io.h>
36#include <asm/div64.h>
37#include <linux/pci.h>
38#include <linux/pci_ids.h>
39#include <linux/smp_lock.h>
40#include <linux/timer.h>
41#include <linux/version.h>
42#include <linux/byteorder/generic.h>
43#include <linux/firmware.h>
44#include <linux/vmalloc.h>
45
46#include "ngene.h"
47
48#include "stv6110x.h"
49#include "stv090x.h"
50#include "lnbh24.h"
51
52static int one_adapter = 1;
53module_param(one_adapter, int, 0444);
54MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
55
56
57static int debug;
58module_param(debug, int, 0444);
59MODULE_PARM_DESC(debug, "Print debugging information.");
60
61DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
62
63#define COMMAND_TIMEOUT_WORKAROUND
64
65#define dprintk if (debug) printk
66
67#define DEVICE_NAME "ngene"
68
69#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
70#define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr)))
71#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
72#define ngreadl(adr) readl(dev->iomem + (adr))
73#define ngreadb(adr) readb(dev->iomem + (adr))
74#define ngcpyto(adr, src, count) memcpy_toio((char *) \
75 (dev->iomem + (adr)), (src), (count))
76#define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \
77 (dev->iomem + (adr)), (count))
78
79/****************************************************************************/
80/* nGene interrupt handler **************************************************/
81/****************************************************************************/
82
83static void event_tasklet(unsigned long data)
84{
85 struct ngene *dev = (struct ngene *)data;
86
87 while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) {
88 struct EVENT_BUFFER Event =
89 dev->EventQueue[dev->EventQueueReadIndex];
90 dev->EventQueueReadIndex =
91 (dev->EventQueueReadIndex + 1) & (EVENT_QUEUE_SIZE - 1);
92
93 if ((Event.UARTStatus & 0x01) && (dev->TxEventNotify))
94 dev->TxEventNotify(dev, Event.TimeStamp);
95 if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify))
96 dev->RxEventNotify(dev, Event.TimeStamp,
97 Event.RXCharacter);
98 }
99}
100
101static void demux_tasklet(unsigned long data)
102{
103 struct ngene_channel *chan = (struct ngene_channel *)data;
104 struct SBufferHeader *Cur = chan->nextBuffer;
105
106 spin_lock_irq(&chan->state_lock);
107
108 while (Cur->ngeneBuffer.SR.Flags & 0x80) {
109 if (chan->mode & NGENE_IO_TSOUT) {
110 u32 Flags = chan->DataFormatFlags;
111 if (Cur->ngeneBuffer.SR.Flags & 0x20)
112 Flags |= BEF_OVERFLOW;
113 if (chan->pBufferExchange) {
114 if (!chan->pBufferExchange(chan,
115 Cur->Buffer1,
116 chan->Capture1Length,
117 Cur->ngeneBuffer.SR.
118 Clock, Flags)) {
119 /*
120 We didn't get data
121 Clear in service flag to make sure we
122 get called on next interrupt again.
123 leave fill/empty (0x80) flag alone
124 to avoid hardware running out of
125 buffers during startup, we hold only
126 in run state ( the source may be late
127 delivering data )
128 */
129
130 if (chan->HWState == HWSTATE_RUN) {
131 Cur->ngeneBuffer.SR.Flags &=
132 ~0x40;
133 break;
134 /* Stop proccessing stream */
135 }
136 } else {
137 /* We got a valid buffer,
138 so switch to run state */
139 chan->HWState = HWSTATE_RUN;
140 }
141 } else {
142 printk(KERN_ERR DEVICE_NAME ": OOPS\n");
143 if (chan->HWState == HWSTATE_RUN) {
144 Cur->ngeneBuffer.SR.Flags &= ~0x40;
145 break; /* Stop proccessing stream */
146 }
147 }
148 if (chan->AudioDTOUpdated) {
149 printk(KERN_INFO DEVICE_NAME
150 ": Update AudioDTO = %d\n",
151 chan->AudioDTOValue);
152 Cur->ngeneBuffer.SR.DTOUpdate =
153 chan->AudioDTOValue;
154 chan->AudioDTOUpdated = 0;
155 }
156 } else {
157 if (chan->HWState == HWSTATE_RUN) {
158 u32 Flags = 0;
159 if (Cur->ngeneBuffer.SR.Flags & 0x01)
160 Flags |= BEF_EVEN_FIELD;
161 if (Cur->ngeneBuffer.SR.Flags & 0x20)
162 Flags |= BEF_OVERFLOW;
163 if (chan->pBufferExchange)
164 chan->pBufferExchange(chan,
165 Cur->Buffer1,
166 chan->
167 Capture1Length,
168 Cur->ngeneBuffer.
169 SR.Clock, Flags);
170 if (chan->pBufferExchange2)
171 chan->pBufferExchange2(chan,
172 Cur->Buffer2,
173 chan->
174 Capture2Length,
175 Cur->ngeneBuffer.
176 SR.Clock, Flags);
177 } else if (chan->HWState != HWSTATE_STOP)
178 chan->HWState = HWSTATE_RUN;
179 }
180 Cur->ngeneBuffer.SR.Flags = 0x00;
181 Cur = Cur->Next;
182 }
183 chan->nextBuffer = Cur;
184
185 spin_unlock_irq(&chan->state_lock);
186}
187
188static irqreturn_t irq_handler(int irq, void *dev_id)
189{
190 struct ngene *dev = (struct ngene *)dev_id;
191 u32 icounts = 0;
192 irqreturn_t rc = IRQ_NONE;
193 u32 i = MAX_STREAM;
194 u8 *tmpCmdDoneByte;
195
196 if (dev->BootFirmware) {
197 icounts = ngreadl(NGENE_INT_COUNTS);
198 if (icounts != dev->icounts) {
199 ngwritel(0, FORCE_NMI);
200 dev->cmd_done = 1;
201 wake_up(&dev->cmd_wq);
202 dev->icounts = icounts;
203 rc = IRQ_HANDLED;
204 }
205 return rc;
206 }
207
208 ngwritel(0, FORCE_NMI);
209
210 spin_lock(&dev->cmd_lock);
211 tmpCmdDoneByte = dev->CmdDoneByte;
212 if (tmpCmdDoneByte &&
213 (*tmpCmdDoneByte ||
214 (dev->ngenetohost[0] == 1 && dev->ngenetohost[1] != 0))) {
215 dev->CmdDoneByte = NULL;
216 dev->cmd_done = 1;
217 wake_up(&dev->cmd_wq);
218 rc = IRQ_HANDLED;
219 }
220 spin_unlock(&dev->cmd_lock);
221
222 if (dev->EventBuffer->EventStatus & 0x80) {
223 u8 nextWriteIndex =
224 (dev->EventQueueWriteIndex + 1) &
225 (EVENT_QUEUE_SIZE - 1);
226 if (nextWriteIndex != dev->EventQueueReadIndex) {
227 dev->EventQueue[dev->EventQueueWriteIndex] =
228 *(dev->EventBuffer);
229 dev->EventQueueWriteIndex = nextWriteIndex;
230 } else {
231 printk(KERN_ERR DEVICE_NAME ": event overflow\n");
232 dev->EventQueueOverflowCount += 1;
233 dev->EventQueueOverflowFlag = 1;
234 }
235 dev->EventBuffer->EventStatus &= ~0x80;
236 tasklet_schedule(&dev->event_tasklet);
237 rc = IRQ_HANDLED;
238 }
239
240 while (i > 0) {
241 i--;
242 spin_lock(&dev->channel[i].state_lock);
243 /* if (dev->channel[i].State>=KSSTATE_RUN) { */
244 if (dev->channel[i].nextBuffer) {
245 if ((dev->channel[i].nextBuffer->
246 ngeneBuffer.SR.Flags & 0xC0) == 0x80) {
247 dev->channel[i].nextBuffer->
248 ngeneBuffer.SR.Flags |= 0x40;
249 tasklet_schedule(
250 &dev->channel[i].demux_tasklet);
251 rc = IRQ_HANDLED;
252 }
253 }
254 spin_unlock(&dev->channel[i].state_lock);
255 }
256
257 /* Request might have been processed by a previous call. */
258 return IRQ_HANDLED;
259}
260
261/****************************************************************************/
262/* nGene command interface **************************************************/
263/****************************************************************************/
264
265static void dump_command_io(struct ngene *dev)
266{
267 u8 buf[8], *b;
268
269 ngcpyfrom(buf, HOST_TO_NGENE, 8);
270 printk(KERN_ERR "host_to_ngene (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n",
271 HOST_TO_NGENE, buf[0], buf[1], buf[2], buf[3],
272 buf[4], buf[5], buf[6], buf[7]);
273
274 ngcpyfrom(buf, NGENE_TO_HOST, 8);
275 printk(KERN_ERR "ngene_to_host (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n",
276 NGENE_TO_HOST, buf[0], buf[1], buf[2], buf[3],
277 buf[4], buf[5], buf[6], buf[7]);
278
279 b = dev->hosttongene;
280 printk(KERN_ERR "dev->hosttongene (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n",
281 b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
282
283 b = dev->ngenetohost;
284 printk(KERN_ERR "dev->ngenetohost (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n",
285 b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
286}
287
288static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com)
289{
290 int ret;
291 u8 *tmpCmdDoneByte;
292
293 dev->cmd_done = 0;
294
295 if (com->cmd.hdr.Opcode == CMD_FWLOAD_PREPARE) {
296 dev->BootFirmware = 1;
297 dev->icounts = ngreadl(NGENE_INT_COUNTS);
298 ngwritel(0, NGENE_COMMAND);
299 ngwritel(0, NGENE_COMMAND_HI);
300 ngwritel(0, NGENE_STATUS);
301 ngwritel(0, NGENE_STATUS_HI);
302 ngwritel(0, NGENE_EVENT);
303 ngwritel(0, NGENE_EVENT_HI);
304 } else if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) {
305 u64 fwio = dev->PAFWInterfaceBuffer;
306
307 ngwritel(fwio & 0xffffffff, NGENE_COMMAND);
308 ngwritel(fwio >> 32, NGENE_COMMAND_HI);
309 ngwritel((fwio + 256) & 0xffffffff, NGENE_STATUS);
310 ngwritel((fwio + 256) >> 32, NGENE_STATUS_HI);
311 ngwritel((fwio + 512) & 0xffffffff, NGENE_EVENT);
312 ngwritel((fwio + 512) >> 32, NGENE_EVENT_HI);
313 }
314
315 memcpy(dev->FWInterfaceBuffer, com->cmd.raw8, com->in_len + 2);
316
317 if (dev->BootFirmware)
318 ngcpyto(HOST_TO_NGENE, com->cmd.raw8, com->in_len + 2);
319
320 spin_lock_irq(&dev->cmd_lock);
321 tmpCmdDoneByte = dev->ngenetohost + com->out_len;
322 if (!com->out_len)
323 tmpCmdDoneByte++;
324 *tmpCmdDoneByte = 0;
325 dev->ngenetohost[0] = 0;
326 dev->ngenetohost[1] = 0;
327 dev->CmdDoneByte = tmpCmdDoneByte;
328 spin_unlock_irq(&dev->cmd_lock);
329
330 /* Notify 8051. */
331 ngwritel(1, FORCE_INT);
332
333 ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ);
334 if (!ret) {
335 /*ngwritel(0, FORCE_NMI);*/
336
337 printk(KERN_ERR DEVICE_NAME
338 ": Command timeout cmd=%02x prev=%02x\n",
339 com->cmd.hdr.Opcode, dev->prev_cmd);
340 dump_command_io(dev);
341 return -1;
342 }
343 if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH)
344 dev->BootFirmware = 0;
345
346 dev->prev_cmd = com->cmd.hdr.Opcode;
347
348 if (!com->out_len)
349 return 0;
350
351 memcpy(com->cmd.raw8, dev->ngenetohost, com->out_len);
352
353 return 0;
354}
355
356static int ngene_command(struct ngene *dev, struct ngene_command *com)
357{
358 int result;
359
360 down(&dev->cmd_mutex);
361 result = ngene_command_mutex(dev, com);
362 up(&dev->cmd_mutex);
363 return result;
364}
365
366
367static int ngene_command_i2c_read(struct ngene *dev, u8 adr,
368 u8 *out, u8 outlen, u8 *in, u8 inlen, int flag)
369{
370 struct ngene_command com;
371
372 com.cmd.hdr.Opcode = CMD_I2C_READ;
373 com.cmd.hdr.Length = outlen + 3;
374 com.cmd.I2CRead.Device = adr << 1;
375 memcpy(com.cmd.I2CRead.Data, out, outlen);
376 com.cmd.I2CRead.Data[outlen] = inlen;
377 com.cmd.I2CRead.Data[outlen + 1] = 0;
378 com.in_len = outlen + 3;
379 com.out_len = inlen + 1;
380
381 if (ngene_command(dev, &com) < 0)
382 return -EIO;
383
384 if ((com.cmd.raw8[0] >> 1) != adr)
385 return -EIO;
386
387 if (flag)
388 memcpy(in, com.cmd.raw8, inlen + 1);
389 else
390 memcpy(in, com.cmd.raw8 + 1, inlen);
391 return 0;
392}
393
394static int ngene_command_i2c_write(struct ngene *dev, u8 adr,
395 u8 *out, u8 outlen)
396{
397 struct ngene_command com;
398
399
400 com.cmd.hdr.Opcode = CMD_I2C_WRITE;
401 com.cmd.hdr.Length = outlen + 1;
402 com.cmd.I2CRead.Device = adr << 1;
403 memcpy(com.cmd.I2CRead.Data, out, outlen);
404 com.in_len = outlen + 1;
405 com.out_len = 1;
406
407 if (ngene_command(dev, &com) < 0)
408 return -EIO;
409
410 if (com.cmd.raw8[0] == 1)
411 return -EIO;
412
413 return 0;
414}
415
416static int ngene_command_load_firmware(struct ngene *dev,
417 u8 *ngene_fw, u32 size)
418{
419#define FIRSTCHUNK (1024)
420 u32 cleft;
421 struct ngene_command com;
422
423 com.cmd.hdr.Opcode = CMD_FWLOAD_PREPARE;
424 com.cmd.hdr.Length = 0;
425 com.in_len = 0;
426 com.out_len = 0;
427
428 ngene_command(dev, &com);
429
430 cleft = (size + 3) & ~3;
431 if (cleft > FIRSTCHUNK) {
432 ngcpyto(PROGRAM_SRAM + FIRSTCHUNK, ngene_fw + FIRSTCHUNK,
433 cleft - FIRSTCHUNK);
434 cleft = FIRSTCHUNK;
435 }
436 ngcpyto(DATA_FIFO_AREA, ngene_fw, cleft);
437
438 memset(&com, 0, sizeof(struct ngene_command));
439 com.cmd.hdr.Opcode = CMD_FWLOAD_FINISH;
440 com.cmd.hdr.Length = 4;
441 com.cmd.FWLoadFinish.Address = DATA_FIFO_AREA;
442 com.cmd.FWLoadFinish.Length = (unsigned short)cleft;
443 com.in_len = 4;
444 com.out_len = 0;
445
446 return ngene_command(dev, &com);
447}
448
449
450static int ngene_command_config_buf(struct ngene *dev, u8 config)
451{
452 struct ngene_command com;
453
454 com.cmd.hdr.Opcode = CMD_CONFIGURE_BUFFER;
455 com.cmd.hdr.Length = 1;
456 com.cmd.ConfigureBuffers.config = config;
457 com.in_len = 1;
458 com.out_len = 0;
459
460 if (ngene_command(dev, &com) < 0)
461 return -EIO;
462 return 0;
463}
464
465static int ngene_command_config_free_buf(struct ngene *dev, u8 *config)
466{
467 struct ngene_command com;
468
469 com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER;
470 com.cmd.hdr.Length = 6;
471 memcpy(&com.cmd.ConfigureBuffers.config, config, 6);
472 com.in_len = 6;
473 com.out_len = 0;
474
475 if (ngene_command(dev, &com) < 0)
476 return -EIO;
477
478 return 0;
479}
480
481static int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level)
482{
483 struct ngene_command com;
484
485 com.cmd.hdr.Opcode = CMD_SET_GPIO_PIN;
486 com.cmd.hdr.Length = 1;
487 com.cmd.SetGpioPin.select = select | (level << 7);
488 com.in_len = 1;
489 com.out_len = 0;
490
491 return ngene_command(dev, &com);
492}
493
494
495/*
496 02000640 is sample on rising edge.
497 02000740 is sample on falling edge.
498 02000040 is ignore "valid" signal
499
500 0: FD_CTL1 Bit 7,6 must be 0,1
501 7 disable(fw controlled)
502 6 0-AUX,1-TS
503 5 0-par,1-ser
504 4 0-lsb/1-msb
505 3,2 reserved
506 1,0 0-no sync, 1-use ext. start, 2-use 0x47, 3-both
507 1: FD_CTL2 has 3-valid must be hi, 2-use valid, 1-edge
508 2: FD_STA is read-only. 0-sync
509 3: FD_INSYNC is number of 47s to trigger "in sync".
510 4: FD_OUTSYNC is number of 47s to trigger "out of sync".
511 5: FD_MAXBYTE1 is low-order of bytes per packet.
512 6: FD_MAXBYTE2 is high-order of bytes per packet.
513 7: Top byte is unused.
514*/
515
516/****************************************************************************/
517
518static u8 TSFeatureDecoderSetup[8 * 4] = {
519 0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,
520 0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */
521 0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */
522 0x72, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */
523};
524
525/* Set NGENE I2S Config to 16 bit packed */
526static u8 I2SConfiguration[] = {
527 0x00, 0x10, 0x00, 0x00,
528 0x80, 0x10, 0x00, 0x00,
529};
530
531static u8 SPDIFConfiguration[10] = {
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
533};
534
535/* Set NGENE I2S Config to transport stream compatible mode */
536
537static u8 TS_I2SConfiguration[4] = { 0x3E, 0x1A, 0x00, 0x00 }; /*3e 18 00 00 ?*/
538
539static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 };
540
541static u8 ITUDecoderSetup[4][16] = {
542 {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */
543 0x00, 0x00, 0x01, 0xb0, 0x9c, 0x00, 0x00, 0x00},
544 {0x9c, 0x03, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00,
545 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
546 {0x9f, 0x00, 0x23, 0xC0, 0x60, 0x0F, 0x13, 0x00, /* HDTV 1080i50 */
547 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
548 {0x9c, 0x01, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00, /* HDTV 1080i60 */
549 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00},
550};
551
552/*
553 * 50 48 60 gleich
554 * 27p50 9f 00 22 80 42 69 18 ...
555 * 27p60 93 00 22 80 82 69 1c ...
556 */
557
558/* Maxbyte to 1144 (for raw data) */
559static u8 ITUFeatureDecoderSetup[8] = {
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00
561};
562
563static void FillTSBuffer(void *Buffer, int Length, u32 Flags)
564{
565 u32 *ptr = Buffer;
566
567 memset(Buffer, 0xff, Length);
568 while (Length > 0) {
569 if (Flags & DF_SWAP32)
570 *ptr = 0x471FFF10;
571 else
572 *ptr = 0x10FF1F47;
573 ptr += (188 / 4);
574 Length -= 188;
575 }
576}
577
578
579static void flush_buffers(struct ngene_channel *chan)
580{
581 u8 val;
582
583 do {
584 msleep(1);
585 spin_lock_irq(&chan->state_lock);
586 val = chan->nextBuffer->ngeneBuffer.SR.Flags & 0x80;
587 spin_unlock_irq(&chan->state_lock);
588 } while (val);
589}
590
591static void clear_buffers(struct ngene_channel *chan)
592{
593 struct SBufferHeader *Cur = chan->nextBuffer;
594
595 do {
596 memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR));
597 if (chan->mode & NGENE_IO_TSOUT)
598 FillTSBuffer(Cur->Buffer1,
599 chan->Capture1Length,
600 chan->DataFormatFlags);
601 Cur = Cur->Next;
602 } while (Cur != chan->nextBuffer);
603
604 if (chan->mode & NGENE_IO_TSOUT) {
605 chan->nextBuffer->ngeneBuffer.SR.DTOUpdate =
606 chan->AudioDTOValue;
607 chan->AudioDTOUpdated = 0;
608
609 Cur = chan->TSIdleBuffer.Head;
610
611 do {
612 memset(&Cur->ngeneBuffer.SR, 0,
613 sizeof(Cur->ngeneBuffer.SR));
614 FillTSBuffer(Cur->Buffer1,
615 chan->Capture1Length,
616 chan->DataFormatFlags);
617 Cur = Cur->Next;
618 } while (Cur != chan->TSIdleBuffer.Head);
619 }
620}
621
622static int ngene_command_stream_control(struct ngene *dev, u8 stream,
623 u8 control, u8 mode, u8 flags)
624{
625 struct ngene_channel *chan = &dev->channel[stream];
626 struct ngene_command com;
627 u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300);
628 u16 BsSDI = ((stream & 1) ? 0x9600 : 0x9500);
629 u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
630 u16 BsSDO = 0x9B00;
631
632 /* down(&dev->stream_mutex); */
633 while (down_trylock(&dev->stream_mutex)) {
634 printk(KERN_INFO DEVICE_NAME ": SC locked\n");
635 msleep(1);
636 }
637 memset(&com, 0, sizeof(com));
638 com.cmd.hdr.Opcode = CMD_CONTROL;
639 com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
640 com.cmd.StreamControl.Stream = stream | (control ? 8 : 0);
641 if (chan->mode & NGENE_IO_TSOUT)
642 com.cmd.StreamControl.Stream |= 0x07;
643 com.cmd.StreamControl.Control = control |
644 (flags & SFLAG_ORDER_LUMA_CHROMA);
645 com.cmd.StreamControl.Mode = mode;
646 com.in_len = sizeof(struct FW_STREAM_CONTROL);
647 com.out_len = 0;
648
649 dprintk(KERN_INFO DEVICE_NAME
650 ": Stream=%02x, Control=%02x, Mode=%02x\n",
651 com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control,
652 com.cmd.StreamControl.Mode);
653
654 chan->Mode = mode;
655
656 if (!(control & 0x80)) {
657 spin_lock_irq(&chan->state_lock);
658 if (chan->State == KSSTATE_RUN) {
659 chan->State = KSSTATE_ACQUIRE;
660 chan->HWState = HWSTATE_STOP;
661 spin_unlock_irq(&chan->state_lock);
662 if (ngene_command(dev, &com) < 0) {
663 up(&dev->stream_mutex);
664 return -1;
665 }
666 /* clear_buffers(chan); */
667 flush_buffers(chan);
668 up(&dev->stream_mutex);
669 return 0;
670 }
671 spin_unlock_irq(&chan->state_lock);
672 up(&dev->stream_mutex);
673 return 0;
674 }
675
676 if (mode & SMODE_AUDIO_CAPTURE) {
677 com.cmd.StreamControl.CaptureBlockCount =
678 chan->Capture1Length / AUDIO_BLOCK_SIZE;
679 com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
680 } else if (mode & SMODE_TRANSPORT_STREAM) {
681 com.cmd.StreamControl.CaptureBlockCount =
682 chan->Capture1Length / TS_BLOCK_SIZE;
683 com.cmd.StreamControl.MaxLinesPerField =
684 chan->Capture1Length / TS_BLOCK_SIZE;
685 com.cmd.StreamControl.Buffer_Address =
686 chan->TSRingBuffer.PAHead;
687 if (chan->mode & NGENE_IO_TSOUT) {
688 com.cmd.StreamControl.BytesPerVBILine =
689 chan->Capture1Length / TS_BLOCK_SIZE;
690 com.cmd.StreamControl.Stream |= 0x07;
691 }
692 } else {
693 com.cmd.StreamControl.BytesPerVideoLine = chan->nBytesPerLine;
694 com.cmd.StreamControl.MaxLinesPerField = chan->nLines;
695 com.cmd.StreamControl.MinLinesPerField = 100;
696 com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead;
697
698 if (mode & SMODE_VBI_CAPTURE) {
699 com.cmd.StreamControl.MaxVBILinesPerField =
700 chan->nVBILines;
701 com.cmd.StreamControl.MinVBILinesPerField = 0;
702 com.cmd.StreamControl.BytesPerVBILine =
703 chan->nBytesPerVBILine;
704 }
705 if (flags & SFLAG_COLORBAR)
706 com.cmd.StreamControl.Stream |= 0x04;
707 }
708
709 spin_lock_irq(&chan->state_lock);
710 if (mode & SMODE_AUDIO_CAPTURE) {
711 chan->nextBuffer = chan->RingBuffer.Head;
712 if (mode & SMODE_AUDIO_SPDIF) {
713 com.cmd.StreamControl.SetupDataLen =
714 sizeof(SPDIFConfiguration);
715 com.cmd.StreamControl.SetupDataAddr = BsSPI;
716 memcpy(com.cmd.StreamControl.SetupData,
717 SPDIFConfiguration, sizeof(SPDIFConfiguration));
718 } else {
719 com.cmd.StreamControl.SetupDataLen = 4;
720 com.cmd.StreamControl.SetupDataAddr = BsSDI;
721 memcpy(com.cmd.StreamControl.SetupData,
722 I2SConfiguration +
723 4 * dev->card_info->i2s[stream], 4);
724 }
725 } else if (mode & SMODE_TRANSPORT_STREAM) {
726 chan->nextBuffer = chan->TSRingBuffer.Head;
727 if (stream >= STREAM_AUDIOIN1) {
728 if (chan->mode & NGENE_IO_TSOUT) {
729 com.cmd.StreamControl.SetupDataLen =
730 sizeof(TS_I2SOutConfiguration);
731 com.cmd.StreamControl.SetupDataAddr = BsSDO;
732 memcpy(com.cmd.StreamControl.SetupData,
733 TS_I2SOutConfiguration,
734 sizeof(TS_I2SOutConfiguration));
735 } else {
736 com.cmd.StreamControl.SetupDataLen =
737 sizeof(TS_I2SConfiguration);
738 com.cmd.StreamControl.SetupDataAddr = BsSDI;
739 memcpy(com.cmd.StreamControl.SetupData,
740 TS_I2SConfiguration,
741 sizeof(TS_I2SConfiguration));
742 }
743 } else {
744 com.cmd.StreamControl.SetupDataLen = 8;
745 com.cmd.StreamControl.SetupDataAddr = BsUVI + 0x10;
746 memcpy(com.cmd.StreamControl.SetupData,
747 TSFeatureDecoderSetup +
748 8 * dev->card_info->tsf[stream], 8);
749 }
750 } else {
751 chan->nextBuffer = chan->RingBuffer.Head;
752 com.cmd.StreamControl.SetupDataLen =
753 16 + sizeof(ITUFeatureDecoderSetup);
754 com.cmd.StreamControl.SetupDataAddr = BsUVI;
755 memcpy(com.cmd.StreamControl.SetupData,
756 ITUDecoderSetup[chan->itumode], 16);
757 memcpy(com.cmd.StreamControl.SetupData + 16,
758 ITUFeatureDecoderSetup, sizeof(ITUFeatureDecoderSetup));
759 }
760 clear_buffers(chan);
761 chan->State = KSSTATE_RUN;
762 if (mode & SMODE_TRANSPORT_STREAM)
763 chan->HWState = HWSTATE_RUN;
764 else
765 chan->HWState = HWSTATE_STARTUP;
766 spin_unlock_irq(&chan->state_lock);
767
768 if (ngene_command(dev, &com) < 0) {
769 up(&dev->stream_mutex);
770 return -1;
771 }
772 up(&dev->stream_mutex);
773 return 0;
774}
775
776
777/****************************************************************************/
778/* I2C **********************************************************************/
779/****************************************************************************/
780
781static void ngene_i2c_set_bus(struct ngene *dev, int bus)
782{
783 if (!(dev->card_info->i2c_access & 2))
784 return;
785 if (dev->i2c_current_bus == bus)
786 return;
787
788 switch (bus) {
789 case 0:
790 ngene_command_gpio_set(dev, 3, 0);
791 ngene_command_gpio_set(dev, 2, 1);
792 break;
793
794 case 1:
795 ngene_command_gpio_set(dev, 2, 0);
796 ngene_command_gpio_set(dev, 3, 1);
797 break;
798 }
799 dev->i2c_current_bus = bus;
800}
801
802static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
803 struct i2c_msg msg[], int num)
804{
805 struct ngene_channel *chan =
806 (struct ngene_channel *)i2c_get_adapdata(adapter);
807 struct ngene *dev = chan->dev;
808
809 down(&dev->i2c_switch_mutex);
810 ngene_i2c_set_bus(dev, chan->number);
811
812 if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
813 if (!ngene_command_i2c_read(dev, msg[0].addr,
814 msg[0].buf, msg[0].len,
815 msg[1].buf, msg[1].len, 0))
816 goto done;
817
818 if (num == 1 && !(msg[0].flags & I2C_M_RD))
819 if (!ngene_command_i2c_write(dev, msg[0].addr,
820 msg[0].buf, msg[0].len))
821 goto done;
822 if (num == 1 && (msg[0].flags & I2C_M_RD))
823 if (!ngene_command_i2c_read(dev, msg[0].addr, 0, 0,
824 msg[0].buf, msg[0].len, 0))
825 goto done;
826
827 up(&dev->i2c_switch_mutex);
828 return -EIO;
829
830done:
831 up(&dev->i2c_switch_mutex);
832 return num;
833}
834
835
836static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
837{
838 return I2C_FUNC_SMBUS_EMUL;
839}
840
841static struct i2c_algorithm ngene_i2c_algo = {
842 .master_xfer = ngene_i2c_master_xfer,
843 .functionality = ngene_i2c_functionality,
844};
845
846static int ngene_i2c_init(struct ngene *dev, int dev_nr)
847{
848 struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
849
850 i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
851 adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
852
853 strcpy(adap->name, "nGene");
854
855 adap->algo = &ngene_i2c_algo;
856 adap->algo_data = (void *)&(dev->channel[dev_nr]);
857 adap->dev.parent = &dev->pci_dev->dev;
858
859 return i2c_add_adapter(adap);
860}
861
862
863/****************************************************************************/
864/* DVB functions and API interface ******************************************/
865/****************************************************************************/
866
867static void swap_buffer(u32 *p, u32 len)
868{
869 while (len) {
870 *p = swab32(*p);
871 p++;
872 len -= 4;
873 }
874}
875
876
877static void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
878{
879 struct ngene_channel *chan = priv;
880
881
882#ifdef COMMAND_TIMEOUT_WORKAROUND
883 if (chan->users > 0)
884#endif
885 dvb_dmx_swfilter(&chan->demux, buf, len);
886 return 0;
887}
888
889u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 };
890
891static void *tsout_exchange(void *priv, void *buf, u32 len,
892 u32 clock, u32 flags)
893{
894 struct ngene_channel *chan = priv;
895 struct ngene *dev = chan->dev;
896 u32 alen;
897
898 alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
899 alen -= alen % 188;
900
901 if (alen < len)
902 FillTSBuffer(buf + alen, len - alen, flags);
903 else
904 alen = len;
905 dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
906 if (flags & DF_SWAP32)
907 swap_buffer((u32 *)buf, alen);
908 wake_up_interruptible(&dev->tsout_rbuf.queue);
909 return buf;
910}
911
912
913static void set_transfer(struct ngene_channel *chan, int state)
914{
915 u8 control = 0, mode = 0, flags = 0;
916 struct ngene *dev = chan->dev;
917 int ret;
918
919 /*
920 printk(KERN_INFO DEVICE_NAME ": st %d\n", state);
921 msleep(100);
922 */
923
924 if (state) {
925 if (chan->running) {
926 printk(KERN_INFO DEVICE_NAME ": already running\n");
927 return;
928 }
929 } else {
930 if (!chan->running) {
931 printk(KERN_INFO DEVICE_NAME ": already stopped\n");
932 return;
933 }
934 }
935
936 if (dev->card_info->switch_ctrl)
937 dev->card_info->switch_ctrl(chan, 1, state ^ 1);
938
939 if (state) {
940 spin_lock_irq(&chan->state_lock);
941
942 /* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
943 ngreadl(0x9310)); */
944 dvb_ringbuffer_flush(&dev->tsout_rbuf);
945 control = 0x80;
946 if (chan->mode & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
947 chan->Capture1Length = 512 * 188;
948 mode = SMODE_TRANSPORT_STREAM;
949 }
950 if (chan->mode & NGENE_IO_TSOUT) {
951 chan->pBufferExchange = tsout_exchange;
952 /* 0x66666666 = 50MHz *2^33 /250MHz */
953 chan->AudioDTOValue = 0x66666666;
954 /* set_dto(chan, 38810700+1000); */
955 /* set_dto(chan, 19392658); */
956 }
957 if (chan->mode & NGENE_IO_TSIN)
958 chan->pBufferExchange = tsin_exchange;
959 /* ngwritel(0, 0x9310); */
960 spin_unlock_irq(&chan->state_lock);
961 } else
962 ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
963 ngreadl(0x9310)); */
964
965 ret = ngene_command_stream_control(dev, chan->number,
966 control, mode, flags);
967 if (!ret)
968 chan->running = state;
969 else
970 printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n",
971 state);
972 if (!state) {
973 spin_lock_irq(&chan->state_lock);
974 chan->pBufferExchange = 0;
975 dvb_ringbuffer_flush(&dev->tsout_rbuf);
976 spin_unlock_irq(&chan->state_lock);
977 }
978}
979
980static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
981{
982 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
983 struct ngene_channel *chan = dvbdmx->priv;
984
985 if (chan->users == 0) {
986#ifdef COMMAND_TIMEOUT_WORKAROUND
987 if (!chan->running)
988#endif
989 set_transfer(chan, 1);
990 /* msleep(10); */
991 }
992
993 return ++chan->users;
994}
995
996static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
997{
998 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
999 struct ngene_channel *chan = dvbdmx->priv;
1000
1001 if (--chan->users)
1002 return chan->users;
1003
1004#ifndef COMMAND_TIMEOUT_WORKAROUND
1005 set_transfer(chan, 0);
1006#endif
1007
1008 return 0;
1009}
1010
1011
1012
1013static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
1014 int (*start_feed)(struct dvb_demux_feed *),
1015 int (*stop_feed)(struct dvb_demux_feed *),
1016 void *priv)
1017{
1018 dvbdemux->priv = priv;
1019
1020 dvbdemux->filternum = 256;
1021 dvbdemux->feednum = 256;
1022 dvbdemux->start_feed = start_feed;
1023 dvbdemux->stop_feed = stop_feed;
1024 dvbdemux->write_to_decoder = 0;
1025 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
1026 DMX_SECTION_FILTERING |
1027 DMX_MEMORY_BASED_FILTERING);
1028 return dvb_dmx_init(dvbdemux);
1029}
1030
1031static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
1032 struct dvb_demux *dvbdemux,
1033 struct dmx_frontend *hw_frontend,
1034 struct dmx_frontend *mem_frontend,
1035 struct dvb_adapter *dvb_adapter)
1036{
1037 int ret;
1038
1039 dmxdev->filternum = 256;
1040 dmxdev->demux = &dvbdemux->dmx;
1041 dmxdev->capabilities = 0;
1042 ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
1043 if (ret < 0)
1044 return ret;
1045
1046 hw_frontend->source = DMX_FRONTEND_0;
1047 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
1048 mem_frontend->source = DMX_MEMORY_FE;
1049 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
1050 return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
1051}
1052
1053
1054/****************************************************************************/
1055/* nGene hardware init and release functions ********************************/
1056/****************************************************************************/
1057
1058static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb)
1059{
1060 struct SBufferHeader *Cur = rb->Head;
1061 u32 j;
1062
1063 if (!Cur)
1064 return;
1065
1066 for (j = 0; j < rb->NumBuffers; j++, Cur = Cur->Next) {
1067 if (Cur->Buffer1)
1068 pci_free_consistent(dev->pci_dev,
1069 rb->Buffer1Length,
1070 Cur->Buffer1,
1071 Cur->scList1->Address);
1072
1073 if (Cur->Buffer2)
1074 pci_free_consistent(dev->pci_dev,
1075 rb->Buffer2Length,
1076 Cur->Buffer2,
1077 Cur->scList2->Address);
1078 }
1079
1080 if (rb->SCListMem)
1081 pci_free_consistent(dev->pci_dev, rb->SCListMemSize,
1082 rb->SCListMem, rb->PASCListMem);
1083
1084 pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead);
1085}
1086
1087static void free_idlebuffer(struct ngene *dev,
1088 struct SRingBufferDescriptor *rb,
1089 struct SRingBufferDescriptor *tb)
1090{
1091 int j;
1092 struct SBufferHeader *Cur = tb->Head;
1093
1094 if (!rb->Head)
1095 return;
1096 free_ringbuffer(dev, rb);
1097 for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) {
1098 Cur->Buffer2 = 0;
1099 Cur->scList2 = 0;
1100 Cur->ngeneBuffer.Address_of_first_entry_2 = 0;
1101 Cur->ngeneBuffer.Number_of_entries_2 = 0;
1102 }
1103}
1104
1105static void free_common_buffers(struct ngene *dev)
1106{
1107 u32 i;
1108 struct ngene_channel *chan;
1109
1110 for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
1111 chan = &dev->channel[i];
1112 free_idlebuffer(dev, &chan->TSIdleBuffer, &chan->TSRingBuffer);
1113 free_ringbuffer(dev, &chan->RingBuffer);
1114 free_ringbuffer(dev, &chan->TSRingBuffer);
1115 }
1116
1117 if (dev->OverflowBuffer)
1118 pci_free_consistent(dev->pci_dev,
1119 OVERFLOW_BUFFER_SIZE,
1120 dev->OverflowBuffer, dev->PAOverflowBuffer);
1121
1122 if (dev->FWInterfaceBuffer)
1123 pci_free_consistent(dev->pci_dev,
1124 4096,
1125 dev->FWInterfaceBuffer,
1126 dev->PAFWInterfaceBuffer);
1127}
1128
1129/****************************************************************************/
1130/* Ring buffer handling *****************************************************/
1131/****************************************************************************/
1132
1133static int create_ring_buffer(struct pci_dev *pci_dev,
1134 struct SRingBufferDescriptor *descr, u32 NumBuffers)
1135{
1136 dma_addr_t tmp;
1137 struct SBufferHeader *Head;
1138 u32 i;
1139 u32 MemSize = SIZEOF_SBufferHeader * NumBuffers;
1140 u64 PARingBufferHead;
1141 u64 PARingBufferCur;
1142 u64 PARingBufferNext;
1143 struct SBufferHeader *Cur, *Next;
1144
1145 descr->Head = 0;
1146 descr->MemSize = 0;
1147 descr->PAHead = 0;
1148 descr->NumBuffers = 0;
1149
1150 if (MemSize < 4096)
1151 MemSize = 4096;
1152
1153 Head = pci_alloc_consistent(pci_dev, MemSize, &tmp);
1154 PARingBufferHead = tmp;
1155
1156 if (!Head)
1157 return -ENOMEM;
1158
1159 memset(Head, 0, MemSize);
1160
1161 PARingBufferCur = PARingBufferHead;
1162 Cur = Head;
1163
1164 for (i = 0; i < NumBuffers - 1; i++) {
1165 Next = (struct SBufferHeader *)
1166 (((u8 *) Cur) + SIZEOF_SBufferHeader);
1167 PARingBufferNext = PARingBufferCur + SIZEOF_SBufferHeader;
1168 Cur->Next = Next;
1169 Cur->ngeneBuffer.Next = PARingBufferNext;
1170 Cur = Next;
1171 PARingBufferCur = PARingBufferNext;
1172 }
1173 /* Last Buffer points back to first one */
1174 Cur->Next = Head;
1175 Cur->ngeneBuffer.Next = PARingBufferHead;
1176
1177 descr->Head = Head;
1178 descr->MemSize = MemSize;
1179 descr->PAHead = PARingBufferHead;
1180 descr->NumBuffers = NumBuffers;
1181
1182 return 0;
1183}
1184
1185static int AllocateRingBuffers(struct pci_dev *pci_dev,
1186 dma_addr_t of,
1187 struct SRingBufferDescriptor *pRingBuffer,
1188 u32 Buffer1Length, u32 Buffer2Length)
1189{
1190 dma_addr_t tmp;
1191 u32 i, j;
1192 int status = 0;
1193 u32 SCListMemSize = pRingBuffer->NumBuffers
1194 * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) :
1195 NUM_SCATTER_GATHER_ENTRIES)
1196 * sizeof(struct HW_SCATTER_GATHER_ELEMENT);
1197
1198 u64 PASCListMem;
1199 struct HW_SCATTER_GATHER_ELEMENT *SCListEntry;
1200 u64 PASCListEntry;
1201 struct SBufferHeader *Cur;
1202 void *SCListMem;
1203
1204 if (SCListMemSize < 4096)
1205 SCListMemSize = 4096;
1206
1207 SCListMem = pci_alloc_consistent(pci_dev, SCListMemSize, &tmp);
1208
1209 PASCListMem = tmp;
1210 if (SCListMem == NULL)
1211 return -ENOMEM;
1212
1213 memset(SCListMem, 0, SCListMemSize);
1214
1215 pRingBuffer->SCListMem = SCListMem;
1216 pRingBuffer->PASCListMem = PASCListMem;
1217 pRingBuffer->SCListMemSize = SCListMemSize;
1218 pRingBuffer->Buffer1Length = Buffer1Length;
1219 pRingBuffer->Buffer2Length = Buffer2Length;
1220
1221 SCListEntry = SCListMem;
1222 PASCListEntry = PASCListMem;
1223 Cur = pRingBuffer->Head;
1224
1225 for (i = 0; i < pRingBuffer->NumBuffers; i += 1, Cur = Cur->Next) {
1226 u64 PABuffer;
1227
1228 void *Buffer = pci_alloc_consistent(pci_dev, Buffer1Length,
1229 &tmp);
1230 PABuffer = tmp;
1231
1232 if (Buffer == NULL)
1233 return -ENOMEM;
1234
1235 Cur->Buffer1 = Buffer;
1236
1237 SCListEntry->Address = PABuffer;
1238 SCListEntry->Length = Buffer1Length;
1239
1240 Cur->scList1 = SCListEntry;
1241 Cur->ngeneBuffer.Address_of_first_entry_1 = PASCListEntry;
1242 Cur->ngeneBuffer.Number_of_entries_1 =
1243 NUM_SCATTER_GATHER_ENTRIES;
1244
1245 SCListEntry += 1;
1246 PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
1247
1248#if NUM_SCATTER_GATHER_ENTRIES > 1
1249 for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j += 1) {
1250 SCListEntry->Address = of;
1251 SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
1252 SCListEntry += 1;
1253 PASCListEntry +=
1254 sizeof(struct HW_SCATTER_GATHER_ELEMENT);
1255 }
1256#endif
1257
1258 if (!Buffer2Length)
1259 continue;
1260
1261 Buffer = pci_alloc_consistent(pci_dev, Buffer2Length, &tmp);
1262 PABuffer = tmp;
1263
1264 if (Buffer == NULL)
1265 return -ENOMEM;
1266
1267 Cur->Buffer2 = Buffer;
1268
1269 SCListEntry->Address = PABuffer;
1270 SCListEntry->Length = Buffer2Length;
1271
1272 Cur->scList2 = SCListEntry;
1273 Cur->ngeneBuffer.Address_of_first_entry_2 = PASCListEntry;
1274 Cur->ngeneBuffer.Number_of_entries_2 =
1275 NUM_SCATTER_GATHER_ENTRIES;
1276
1277 SCListEntry += 1;
1278 PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT);
1279
1280#if NUM_SCATTER_GATHER_ENTRIES > 1
1281 for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j++) {
1282 SCListEntry->Address = of;
1283 SCListEntry->Length = OVERFLOW_BUFFER_SIZE;
1284 SCListEntry += 1;
1285 PASCListEntry +=
1286 sizeof(struct HW_SCATTER_GATHER_ELEMENT);
1287 }
1288#endif
1289
1290 }
1291
1292 return status;
1293}
1294
1295static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer,
1296 struct SRingBufferDescriptor *pRingBuffer)
1297{
1298 int status = 0;
1299
1300 /* Copy pointer to scatter gather list in TSRingbuffer
1301 structure for buffer 2
1302 Load number of buffer
1303 */
1304 u32 n = pRingBuffer->NumBuffers;
1305
1306 /* Point to first buffer entry */
1307 struct SBufferHeader *Cur = pRingBuffer->Head;
1308 int i;
1309 /* Loop thru all buffer and set Buffer 2 pointers to TSIdlebuffer */
1310 for (i = 0; i < n; i++) {
1311 Cur->Buffer2 = pIdleBuffer->Head->Buffer1;
1312 Cur->scList2 = pIdleBuffer->Head->scList1;
1313 Cur->ngeneBuffer.Address_of_first_entry_2 =
1314 pIdleBuffer->Head->ngeneBuffer.
1315 Address_of_first_entry_1;
1316 Cur->ngeneBuffer.Number_of_entries_2 =
1317 pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1;
1318 Cur = Cur->Next;
1319 }
1320 return status;
1321}
1322
1323static u32 RingBufferSizes[MAX_STREAM] = {
1324 RING_SIZE_VIDEO,
1325 RING_SIZE_VIDEO,
1326 RING_SIZE_AUDIO,
1327 RING_SIZE_AUDIO,
1328 RING_SIZE_AUDIO,
1329};
1330
1331static u32 Buffer1Sizes[MAX_STREAM] = {
1332 MAX_VIDEO_BUFFER_SIZE,
1333 MAX_VIDEO_BUFFER_SIZE,
1334 MAX_AUDIO_BUFFER_SIZE,
1335 MAX_AUDIO_BUFFER_SIZE,
1336 MAX_AUDIO_BUFFER_SIZE
1337};
1338
1339static u32 Buffer2Sizes[MAX_STREAM] = {
1340 MAX_VBI_BUFFER_SIZE,
1341 MAX_VBI_BUFFER_SIZE,
1342 0,
1343 0,
1344 0
1345};
1346
1347
1348static int AllocCommonBuffers(struct ngene *dev)
1349{
1350 int status = 0, i;
1351
1352 dev->FWInterfaceBuffer = pci_alloc_consistent(dev->pci_dev, 4096,
1353 &dev->PAFWInterfaceBuffer);
1354 if (!dev->FWInterfaceBuffer)
1355 return -ENOMEM;
1356 dev->hosttongene = dev->FWInterfaceBuffer;
1357 dev->ngenetohost = dev->FWInterfaceBuffer + 256;
1358 dev->EventBuffer = dev->FWInterfaceBuffer + 512;
1359
1360 dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev,
1361 OVERFLOW_BUFFER_SIZE,
1362 &dev->PAOverflowBuffer);
1363 if (!dev->OverflowBuffer)
1364 return -ENOMEM;
1365 memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE);
1366
1367 for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) {
1368 int type = dev->card_info->io_type[i];
1369
1370 dev->channel[i].State = KSSTATE_STOP;
1371
1372 if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) {
1373 status = create_ring_buffer(dev->pci_dev,
1374 &dev->channel[i].RingBuffer,
1375 RingBufferSizes[i]);
1376 if (status < 0)
1377 break;
1378
1379 if (type & (NGENE_IO_TV | NGENE_IO_AIN)) {
1380 status = AllocateRingBuffers(dev->pci_dev,
1381 dev->
1382 PAOverflowBuffer,
1383 &dev->channel[i].
1384 RingBuffer,
1385 Buffer1Sizes[i],
1386 Buffer2Sizes[i]);
1387 if (status < 0)
1388 break;
1389 } else if (type & NGENE_IO_HDTV) {
1390 status = AllocateRingBuffers(dev->pci_dev,
1391 dev->
1392 PAOverflowBuffer,
1393 &dev->channel[i].
1394 RingBuffer,
1395 MAX_HDTV_BUFFER_SIZE,
1396 0);
1397 if (status < 0)
1398 break;
1399 }
1400 }
1401
1402 if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
1403
1404 status = create_ring_buffer(dev->pci_dev,
1405 &dev->channel[i].
1406 TSRingBuffer, RING_SIZE_TS);
1407 if (status < 0)
1408 break;
1409
1410 status = AllocateRingBuffers(dev->pci_dev,
1411 dev->PAOverflowBuffer,
1412 &dev->channel[i].
1413 TSRingBuffer,
1414 MAX_TS_BUFFER_SIZE, 0);
1415 if (status)
1416 break;
1417 }
1418
1419 if (type & NGENE_IO_TSOUT) {
1420 status = create_ring_buffer(dev->pci_dev,
1421 &dev->channel[i].
1422 TSIdleBuffer, 1);
1423 if (status < 0)
1424 break;
1425 status = AllocateRingBuffers(dev->pci_dev,
1426 dev->PAOverflowBuffer,
1427 &dev->channel[i].
1428 TSIdleBuffer,
1429 MAX_TS_BUFFER_SIZE, 0);
1430 if (status)
1431 break;
1432 FillTSIdleBuffer(&dev->channel[i].TSIdleBuffer,
1433 &dev->channel[i].TSRingBuffer);
1434 }
1435 }
1436 return status;
1437}
1438
1439static void ngene_release_buffers(struct ngene *dev)
1440{
1441 if (dev->iomem)
1442 iounmap(dev->iomem);
1443 free_common_buffers(dev);
1444 vfree(dev->tsout_buf);
1445 vfree(dev->ain_buf);
1446 vfree(dev->vin_buf);
1447 vfree(dev);
1448}
1449
1450static int ngene_get_buffers(struct ngene *dev)
1451{
1452 if (AllocCommonBuffers(dev))
1453 return -ENOMEM;
1454 if (dev->card_info->io_type[4] & NGENE_IO_TSOUT) {
1455 dev->tsout_buf = vmalloc(TSOUT_BUF_SIZE);
1456 if (!dev->tsout_buf)
1457 return -ENOMEM;
1458 dvb_ringbuffer_init(&dev->tsout_rbuf,
1459 dev->tsout_buf, TSOUT_BUF_SIZE);
1460 }
1461 if (dev->card_info->io_type[2] & NGENE_IO_AIN) {
1462 dev->ain_buf = vmalloc(AIN_BUF_SIZE);
1463 if (!dev->ain_buf)
1464 return -ENOMEM;
1465 dvb_ringbuffer_init(&dev->ain_rbuf, dev->ain_buf, AIN_BUF_SIZE);
1466 }
1467 if (dev->card_info->io_type[0] & NGENE_IO_HDTV) {
1468 dev->vin_buf = vmalloc(VIN_BUF_SIZE);
1469 if (!dev->vin_buf)
1470 return -ENOMEM;
1471 dvb_ringbuffer_init(&dev->vin_rbuf, dev->vin_buf, VIN_BUF_SIZE);
1472 }
1473 dev->iomem = ioremap(pci_resource_start(dev->pci_dev, 0),
1474 pci_resource_len(dev->pci_dev, 0));
1475 if (!dev->iomem)
1476 return -ENOMEM;
1477
1478 return 0;
1479}
1480
1481static void ngene_init(struct ngene *dev)
1482{
1483 int i;
1484
1485 tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev);
1486
1487 memset_io(dev->iomem + 0xc000, 0x00, 0x220);
1488 memset_io(dev->iomem + 0xc400, 0x00, 0x100);
1489
1490 for (i = 0; i < MAX_STREAM; i++) {
1491 dev->channel[i].dev = dev;
1492 dev->channel[i].number = i;
1493 }
1494
1495 dev->fw_interface_version = 0;
1496
1497 ngwritel(0, NGENE_INT_ENABLE);
1498
1499 dev->icounts = ngreadl(NGENE_INT_COUNTS);
1500
1501 dev->device_version = ngreadl(DEV_VER) & 0x0f;
1502 printk(KERN_INFO DEVICE_NAME ": Device version %d\n",
1503 dev->device_version);
1504}
1505
1506static int ngene_load_firm(struct ngene *dev)
1507{
1508 u32 size;
1509 const struct firmware *fw = NULL;
1510 u8 *ngene_fw;
1511 char *fw_name;
1512 int err, version;
1513
1514 version = dev->card_info->fw_version;
1515
1516 switch (version) {
1517 default:
1518 case 15:
1519 version = 15;
1520 size = 23466;
1521 fw_name = "ngene_15.fw";
1522 break;
1523 case 16:
1524 size = 23498;
1525 fw_name = "ngene_16.fw";
1526 break;
1527 case 17:
1528 size = 24446;
1529 fw_name = "ngene_17.fw";
1530 break;
1531 }
1532
1533 if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
1534 printk(KERN_ERR DEVICE_NAME
1535 ": Could not load firmware file %s.\n", fw_name);
1536 printk(KERN_INFO DEVICE_NAME
1537 ": Copy %s to your hotplug directory!\n", fw_name);
1538 return -1;
1539 }
1540 if (size != fw->size) {
1541 printk(KERN_ERR DEVICE_NAME
1542 ": Firmware %s has invalid size!", fw_name);
1543 err = -1;
1544 } else {
1545 printk(KERN_INFO DEVICE_NAME
1546 ": Loading firmware file %s.\n", fw_name);
1547 ngene_fw = (u8 *) fw->data;
1548 err = ngene_command_load_firmware(dev, ngene_fw, size);
1549 }
1550
1551 release_firmware(fw);
1552
1553 return err;
1554}
1555
1556static void ngene_stop(struct ngene *dev)
1557{
1558 down(&dev->cmd_mutex);
1559 i2c_del_adapter(&(dev->channel[0].i2c_adapter));
1560 i2c_del_adapter(&(dev->channel[1].i2c_adapter));
1561 ngwritel(0, NGENE_INT_ENABLE);
1562 ngwritel(0, NGENE_COMMAND);
1563 ngwritel(0, NGENE_COMMAND_HI);
1564 ngwritel(0, NGENE_STATUS);
1565 ngwritel(0, NGENE_STATUS_HI);
1566 ngwritel(0, NGENE_EVENT);
1567 ngwritel(0, NGENE_EVENT_HI);
1568 free_irq(dev->pci_dev->irq, dev);
1569}
1570
1571static int ngene_start(struct ngene *dev)
1572{
1573 int stat;
1574 int i;
1575
1576 pci_set_master(dev->pci_dev);
1577 ngene_init(dev);
1578
1579 stat = request_irq(dev->pci_dev->irq, irq_handler,
1580 IRQF_SHARED, "nGene",
1581 (void *)dev);
1582 if (stat < 0)
1583 return stat;
1584
1585 init_waitqueue_head(&dev->cmd_wq);
1586 init_waitqueue_head(&dev->tx_wq);
1587 init_waitqueue_head(&dev->rx_wq);
1588 sema_init(&dev->cmd_mutex, 1);
1589 sema_init(&dev->stream_mutex, 1);
1590 sema_init(&dev->pll_mutex, 1);
1591 sema_init(&dev->i2c_switch_mutex, 1);
1592 spin_lock_init(&dev->cmd_lock);
1593 for (i = 0; i < MAX_STREAM; i++)
1594 spin_lock_init(&dev->channel[i].state_lock);
1595 ngwritel(1, TIMESTAMPS);
1596
1597 ngwritel(1, NGENE_INT_ENABLE);
1598
1599 stat = ngene_load_firm(dev);
1600 if (stat < 0)
1601 goto fail;
1602
1603 stat = ngene_i2c_init(dev, 0);
1604 if (stat < 0)
1605 goto fail;
1606
1607 stat = ngene_i2c_init(dev, 1);
1608 if (stat < 0)
1609 goto fail;
1610
1611 if (dev->card_info->fw_version == 17) {
1612 u8 tsin4_config[6] = {
1613 3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0};
1614 u8 default_config[6] = {
1615 4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0};
1616 u8 *bconf = default_config;
1617
1618 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1619 bconf = tsin4_config;
1620 dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n");
1621 stat = ngene_command_config_free_buf(dev, bconf);
1622 } else {
1623 int bconf = BUFFER_CONFIG_4422;
1624 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1625 bconf = BUFFER_CONFIG_3333;
1626 stat = ngene_command_config_buf(dev, bconf);
1627 }
1628 return stat;
1629fail:
1630 ngwritel(0, NGENE_INT_ENABLE);
1631 free_irq(dev->pci_dev->irq, dev);
1632 return stat;
1633}
1634
1635
1636
1637/****************************************************************************/
1638/* Switch control (I2C gates, etc.) *****************************************/
1639/****************************************************************************/
1640
1641
1642/****************************************************************************/
1643/* Demod/tuner attachment ***************************************************/
1644/****************************************************************************/
1645
1646static int tuner_attach_stv6110(struct ngene_channel *chan)
1647{
1648 struct stv090x_config *feconf = (struct stv090x_config *)
1649 chan->dev->card_info->fe_config[chan->number];
1650 struct stv6110x_config *tunerconf = (struct stv6110x_config *)
1651 chan->dev->card_info->tuner_config[chan->number];
1652 struct stv6110x_devctl *ctl;
1653
1654 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf,
1655 &chan->i2c_adapter);
1656 if (ctl == NULL) {
1657 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
1658 return -ENODEV;
1659 }
1660
1661 feconf->tuner_init = ctl->tuner_init;
1662 feconf->tuner_set_mode = ctl->tuner_set_mode;
1663 feconf->tuner_set_frequency = ctl->tuner_set_frequency;
1664 feconf->tuner_get_frequency = ctl->tuner_get_frequency;
1665 feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
1666 feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
1667 feconf->tuner_set_bbgain = ctl->tuner_set_bbgain;
1668 feconf->tuner_get_bbgain = ctl->tuner_get_bbgain;
1669 feconf->tuner_set_refclk = ctl->tuner_set_refclk;
1670 feconf->tuner_get_status = ctl->tuner_get_status;
1671
1672 return 0;
1673}
1674
1675
1676static int demod_attach_stv0900(struct ngene_channel *chan)
1677{
1678 struct stv090x_config *feconf = (struct stv090x_config *)
1679 chan->dev->card_info->fe_config[chan->number];
1680
1681 chan->fe = dvb_attach(stv090x_attach,
1682 feconf,
1683 &chan->i2c_adapter,
1684 chan->number == 0 ? STV090x_DEMODULATOR_0 :
1685 STV090x_DEMODULATOR_1);
1686 if (chan->fe == NULL) {
1687 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
1688 return -ENODEV;
1689 }
1690
1691 if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0,
1692 0, chan->dev->card_info->lnb[chan->number])) {
1693 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
1694 dvb_frontend_detach(chan->fe);
1695 return -ENODEV;
1696 }
1697
1698 return 0;
1699}
1700
1701/****************************************************************************/
1702/****************************************************************************/
1703/****************************************************************************/
1704
1705static void release_channel(struct ngene_channel *chan)
1706{
1707 struct dvb_demux *dvbdemux = &chan->demux;
1708 struct ngene *dev = chan->dev;
1709 struct ngene_info *ni = dev->card_info;
1710 int io = ni->io_type[chan->number];
1711
1712#ifdef COMMAND_TIMEOUT_WORKAROUND
1713 if (chan->running)
1714 set_transfer(chan, 0);
1715#endif
1716
1717 tasklet_kill(&chan->demux_tasklet);
1718
1719 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
1720 if (chan->fe) {
1721 dvb_unregister_frontend(chan->fe);
1722 dvb_frontend_detach(chan->fe);
1723 chan->fe = 0;
1724 }
1725 dvbdemux->dmx.close(&dvbdemux->dmx);
1726 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
1727 &chan->hw_frontend);
1728 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
1729 &chan->mem_frontend);
1730 dvb_dmxdev_release(&chan->dmxdev);
1731 dvb_dmx_release(&chan->demux);
1732
1733 if (chan->number == 0 || !one_adapter)
1734 dvb_unregister_adapter(&dev->adapter[chan->number]);
1735 }
1736}
1737
1738static int init_channel(struct ngene_channel *chan)
1739{
1740 int ret = 0, nr = chan->number;
1741 struct dvb_adapter *adapter = NULL;
1742 struct dvb_demux *dvbdemux = &chan->demux;
1743 struct ngene *dev = chan->dev;
1744 struct ngene_info *ni = dev->card_info;
1745 int io = ni->io_type[nr];
1746
1747 tasklet_init(&chan->demux_tasklet, demux_tasklet, (unsigned long)chan);
1748 chan->users = 0;
1749 chan->type = io;
1750 chan->mode = chan->type; /* for now only one mode */
1751
1752 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
1753 if (nr >= STREAM_AUDIOIN1)
1754 chan->DataFormatFlags = DF_SWAP32;
1755 if (nr == 0 || !one_adapter) {
1756 adapter = &dev->adapter[nr];
1757 ret = dvb_register_adapter(adapter, "nGene",
1758 THIS_MODULE,
1759 &chan->dev->pci_dev->dev,
1760 adapter_nr);
1761 if (ret < 0)
1762 return ret;
1763 } else {
1764 adapter = &dev->adapter[0];
1765 }
1766
1767 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
1768 ngene_start_feed,
1769 ngene_stop_feed, chan);
1770 ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux,
1771 &chan->hw_frontend,
1772 &chan->mem_frontend, adapter);
1773 }
1774
1775 if (io & NGENE_IO_TSIN) {
1776 chan->fe = NULL;
1777 if (ni->demod_attach[nr])
1778 ni->demod_attach[nr](chan);
1779 if (chan->fe) {
1780 if (dvb_register_frontend(adapter, chan->fe) < 0) {
1781 if (chan->fe->ops.release)
1782 chan->fe->ops.release(chan->fe);
1783 chan->fe = NULL;
1784 }
1785 }
1786 if (chan->fe && ni->tuner_attach[nr])
1787 if (ni->tuner_attach[nr] (chan) < 0) {
1788 printk(KERN_ERR DEVICE_NAME
1789 ": Tuner attach failed on channel %d!\n",
1790 nr);
1791 }
1792 }
1793 return ret;
1794}
1795
1796static int init_channels(struct ngene *dev)
1797{
1798 int i, j;
1799
1800 for (i = 0; i < MAX_STREAM; i++) {
1801 if (init_channel(&dev->channel[i]) < 0) {
1802 for (j = i - 1; j >= 0; j--)
1803 release_channel(&dev->channel[j]);
1804 return -1;
1805 }
1806 }
1807 return 0;
1808}
1809
1810/****************************************************************************/
1811/* device probe/remove calls ************************************************/
1812/****************************************************************************/
1813
1814static void __devexit ngene_remove(struct pci_dev *pdev)
1815{
1816 struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
1817 int i;
1818
1819 tasklet_kill(&dev->event_tasklet);
1820 for (i = MAX_STREAM - 1; i >= 0; i--)
1821 release_channel(&dev->channel[i]);
1822 ngene_stop(dev);
1823 ngene_release_buffers(dev);
1824 pci_set_drvdata(pdev, 0);
1825 pci_disable_device(pdev);
1826}
1827
1828static int __devinit ngene_probe(struct pci_dev *pci_dev,
1829 const struct pci_device_id *id)
1830{
1831 struct ngene *dev;
1832 int stat = 0;
1833
1834 if (pci_enable_device(pci_dev) < 0)
1835 return -ENODEV;
1836
1837 dev = vmalloc(sizeof(struct ngene));
1838 if (dev == NULL) {
1839 stat = -ENOMEM;
1840 goto fail0;
1841 }
1842 memset(dev, 0, sizeof(struct ngene));
1843
1844 dev->pci_dev = pci_dev;
1845 dev->card_info = (struct ngene_info *)id->driver_data;
1846 printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name);
1847
1848 pci_set_drvdata(pci_dev, dev);
1849
1850 /* Alloc buffers and start nGene */
1851 stat = ngene_get_buffers(dev);
1852 if (stat < 0)
1853 goto fail1;
1854 stat = ngene_start(dev);
1855 if (stat < 0)
1856 goto fail1;
1857
1858 dev->i2c_current_bus = -1;
1859
1860 /* Register DVB adapters and devices for both channels */
1861 if (init_channels(dev) < 0)
1862 goto fail2;
1863
1864 return 0;
1865
1866fail2:
1867 ngene_stop(dev);
1868fail1:
1869 ngene_release_buffers(dev);
1870fail0:
1871 pci_disable_device(pci_dev);
1872 pci_set_drvdata(pci_dev, 0);
1873 return stat;
1874}
1875
1876/****************************************************************************/
1877/* Card configs *************************************************************/
1878/****************************************************************************/
1879
1880static struct stv090x_config fe_cineS2 = {
1881 .device = STV0900,
1882 .demod_mode = STV090x_DUAL,
1883 .clk_mode = STV090x_CLK_EXT,
1884
1885 .xtal = 27000000,
1886 .address = 0x68,
1887
1888 .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
1889 .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
1890
1891 .repeater_level = STV090x_RPTLEVEL_16,
1892
1893 .adc1_range = STV090x_ADC_1Vpp,
1894 .adc2_range = STV090x_ADC_1Vpp,
1895
1896 .diseqc_envelope_mode = true,
1897};
1898
1899static struct stv6110x_config tuner_cineS2_0 = {
1900 .addr = 0x60,
1901 .refclk = 27000000,
1902 .clk_div = 1,
1903};
1904
1905static struct stv6110x_config tuner_cineS2_1 = {
1906 .addr = 0x63,
1907 .refclk = 27000000,
1908 .clk_div = 1,
1909};
1910
1911static struct ngene_info ngene_info_cineS2 = {
1912 .type = NGENE_SIDEWINDER,
1913 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner",
1914 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
1915 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
1916 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
1917 .fe_config = {&fe_cineS2, &fe_cineS2},
1918 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
1919 .lnb = {0x0b, 0x08},
1920 .tsf = {3, 3},
1921 .fw_version = 15,
1922};
1923
1924static struct ngene_info ngene_info_satixs2 = {
1925 .type = NGENE_SIDEWINDER,
1926 .name = "Mystique SaTiX-S2 Dual",
1927 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
1928 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
1929 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
1930 .fe_config = {&fe_cineS2, &fe_cineS2},
1931 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
1932 .lnb = {0x0b, 0x08},
1933 .tsf = {3, 3},
1934 .fw_version = 15,
1935};
1936
1937/****************************************************************************/
1938
1939
1940
1941/****************************************************************************/
1942/* PCI Subsystem ID *********************************************************/
1943/****************************************************************************/
1944
1945#define NGENE_ID(_subvend, _subdev, _driverdata) { \
1946 .vendor = NGENE_VID, .device = NGENE_PID, \
1947 .subvendor = _subvend, .subdevice = _subdev, \
1948 .driver_data = (unsigned long) &_driverdata }
1949
1950/****************************************************************************/
1951
1952static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
1953 NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
1954 NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
1955 NGENE_ID(0x18c3, 0xdb01, ngene_info_satixs2),
1956 {0}
1957};
1958MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
1959
1960/****************************************************************************/
1961/* Init/Exit ****************************************************************/
1962/****************************************************************************/
1963
1964static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
1965 enum pci_channel_state state)
1966{
1967 printk(KERN_ERR DEVICE_NAME ": PCI error\n");
1968 if (state == pci_channel_io_perm_failure)
1969 return PCI_ERS_RESULT_DISCONNECT;
1970 if (state == pci_channel_io_frozen)
1971 return PCI_ERS_RESULT_NEED_RESET;
1972 return PCI_ERS_RESULT_CAN_RECOVER;
1973}
1974
1975static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
1976{
1977 printk(KERN_INFO DEVICE_NAME ": link reset\n");
1978 return 0;
1979}
1980
1981static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
1982{
1983 printk(KERN_INFO DEVICE_NAME ": slot reset\n");
1984 return 0;
1985}
1986
1987static void ngene_resume(struct pci_dev *dev)
1988{
1989 printk(KERN_INFO DEVICE_NAME ": resume\n");
1990}
1991
1992static struct pci_error_handlers ngene_errors = {
1993 .error_detected = ngene_error_detected,
1994 .link_reset = ngene_link_reset,
1995 .slot_reset = ngene_slot_reset,
1996 .resume = ngene_resume,
1997};
1998
1999static struct pci_driver ngene_pci_driver = {
2000 .name = "ngene",
2001 .id_table = ngene_id_tbl,
2002 .probe = ngene_probe,
2003 .remove = __devexit_p(ngene_remove),
2004 .err_handler = &ngene_errors,
2005};
2006
2007static __init int module_init_ngene(void)
2008{
2009 printk(KERN_INFO
2010 "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
2011 return pci_register_driver(&ngene_pci_driver);
2012}
2013
2014static __exit void module_exit_ngene(void)
2015{
2016 pci_unregister_driver(&ngene_pci_driver);
2017}
2018
2019module_init(module_init_ngene);
2020module_exit(module_exit_ngene);
2021
2022MODULE_DESCRIPTION("nGene");
2023MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
2024MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h
new file mode 100644
index 000000000000..a7eb29846310
--- /dev/null
+++ b/drivers/media/dvb/ngene/ngene.h
@@ -0,0 +1,859 @@
1/*
2 * ngene.h: nGene PCIe bridge driver
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef _NGENE_H_
25#define _NGENE_H_
26
27#include <linux/types.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h>
30#include <linux/i2c.h>
31#include <asm/dma.h>
32#include <linux/scatterlist.h>
33
34#include <linux/dvb/frontend.h>
35
36#include "dmxdev.h"
37#include "dvbdev.h"
38#include "dvb_demux.h"
39#include "dvb_frontend.h"
40#include "dvb_ringbuffer.h"
41
42#define NGENE_VID 0x18c3
43#define NGENE_PID 0x0720
44
45#ifndef VIDEO_CAP_VC1
46#define VIDEO_CAP_AVC 128
47#define VIDEO_CAP_H264 128
48#define VIDEO_CAP_VC1 256
49#define VIDEO_CAP_WMV9 256
50#define VIDEO_CAP_MPEG4 512
51#endif
52
53enum STREAM {
54 STREAM_VIDEOIN1 = 0, /* ITU656 or TS Input */
55 STREAM_VIDEOIN2,
56 STREAM_AUDIOIN1, /* I2S or SPI Input */
57 STREAM_AUDIOIN2,
58 STREAM_AUDIOOUT,
59 MAX_STREAM
60};
61
62enum SMODE_BITS {
63 SMODE_AUDIO_SPDIF = 0x20,
64 SMODE_AVSYNC = 0x10,
65 SMODE_TRANSPORT_STREAM = 0x08,
66 SMODE_AUDIO_CAPTURE = 0x04,
67 SMODE_VBI_CAPTURE = 0x02,
68 SMODE_VIDEO_CAPTURE = 0x01
69};
70
71enum STREAM_FLAG_BITS {
72 SFLAG_CHROMA_FORMAT_2COMP = 0x01, /* Chroma Format : 2's complement */
73 SFLAG_CHROMA_FORMAT_OFFSET = 0x00, /* Chroma Format : Binary offset */
74 SFLAG_ORDER_LUMA_CHROMA = 0x02, /* Byte order: Y,Cb,Y,Cr */
75 SFLAG_ORDER_CHROMA_LUMA = 0x00, /* Byte order: Cb,Y,Cr,Y */
76 SFLAG_COLORBAR = 0x04, /* Select colorbar */
77};
78
79#define PROGRAM_ROM 0x0000
80#define PROGRAM_SRAM 0x1000
81#define PERIPHERALS0 0x8000
82#define PERIPHERALS1 0x9000
83#define SHARED_BUFFER 0xC000
84
85#define HOST_TO_NGENE (SHARED_BUFFER+0x0000)
86#define NGENE_TO_HOST (SHARED_BUFFER+0x0100)
87#define NGENE_COMMAND (SHARED_BUFFER+0x0200)
88#define NGENE_COMMAND_HI (SHARED_BUFFER+0x0204)
89#define NGENE_STATUS (SHARED_BUFFER+0x0208)
90#define NGENE_STATUS_HI (SHARED_BUFFER+0x020C)
91#define NGENE_EVENT (SHARED_BUFFER+0x0210)
92#define NGENE_EVENT_HI (SHARED_BUFFER+0x0214)
93#define VARIABLES (SHARED_BUFFER+0x0210)
94
95#define NGENE_INT_COUNTS (SHARED_BUFFER+0x0260)
96#define NGENE_INT_ENABLE (SHARED_BUFFER+0x0264)
97#define NGENE_VBI_LINE_COUNT (SHARED_BUFFER+0x0268)
98
99#define BUFFER_GP_XMIT (SHARED_BUFFER+0x0800)
100#define BUFFER_GP_RECV (SHARED_BUFFER+0x0900)
101#define EEPROM_AREA (SHARED_BUFFER+0x0A00)
102
103#define SG_V_IN_1 (SHARED_BUFFER+0x0A80)
104#define SG_VBI_1 (SHARED_BUFFER+0x0B00)
105#define SG_A_IN_1 (SHARED_BUFFER+0x0B80)
106#define SG_V_IN_2 (SHARED_BUFFER+0x0C00)
107#define SG_VBI_2 (SHARED_BUFFER+0x0C80)
108#define SG_A_IN_2 (SHARED_BUFFER+0x0D00)
109#define SG_V_OUT (SHARED_BUFFER+0x0D80)
110#define SG_A_OUT2 (SHARED_BUFFER+0x0E00)
111
112#define DATA_A_IN_1 (SHARED_BUFFER+0x0E80)
113#define DATA_A_IN_2 (SHARED_BUFFER+0x0F00)
114#define DATA_A_OUT (SHARED_BUFFER+0x0F80)
115#define DATA_V_IN_1 (SHARED_BUFFER+0x1000)
116#define DATA_V_IN_2 (SHARED_BUFFER+0x2000)
117#define DATA_V_OUT (SHARED_BUFFER+0x3000)
118
119#define DATA_FIFO_AREA (SHARED_BUFFER+0x1000)
120
121#define TIMESTAMPS 0xA000
122#define SCRATCHPAD 0xA080
123#define FORCE_INT 0xA088
124#define FORCE_NMI 0xA090
125#define INT_STATUS 0xA0A0
126
127#define DEV_VER 0x9004
128
129#define FW_DEBUG_DEFAULT (PROGRAM_SRAM+0x00FF)
130
131struct SG_ADDR {
132 u64 start;
133 u64 curr;
134 u16 curr_ptr;
135 u16 elements;
136 u32 pad[3];
137} __attribute__ ((__packed__));
138
139struct SHARED_MEMORY {
140 /* C000 */
141 u32 HostToNgene[64];
142
143 /* C100 */
144 u32 NgeneToHost[64];
145
146 /* C200 */
147 u64 NgeneCommand;
148 u64 NgeneStatus;
149 u64 NgeneEvent;
150
151 /* C210 */
152 u8 pad1[0xc260 - 0xc218];
153
154 /* C260 */
155 u32 IntCounts;
156 u32 IntEnable;
157
158 /* C268 */
159 u8 pad2[0xd000 - 0xc268];
160
161} __attribute__ ((__packed__));
162
163struct BUFFER_STREAM_RESULTS {
164 u32 Clock; /* Stream time in 100ns units */
165 u16 RemainingLines; /* Remaining lines in this field.
166 0 for complete field */
167 u8 FieldCount; /* Video field number */
168 u8 Flags; /* Bit 7 = Done, Bit 6 = seen, Bit 5 = overflow,
169 Bit 0 = FieldID */
170 u16 BlockCount; /* Audio block count (unused) */
171 u8 Reserved[2];
172 u32 DTOUpdate;
173} __attribute__ ((__packed__));
174
175struct HW_SCATTER_GATHER_ELEMENT {
176 u64 Address;
177 u32 Length;
178 u32 Reserved;
179} __attribute__ ((__packed__));
180
181struct BUFFER_HEADER {
182 u64 Next;
183 struct BUFFER_STREAM_RESULTS SR;
184
185 u32 Number_of_entries_1;
186 u32 Reserved5;
187 u64 Address_of_first_entry_1;
188
189 u32 Number_of_entries_2;
190 u32 Reserved7;
191 u64 Address_of_first_entry_2;
192} __attribute__ ((__packed__));
193
194struct EVENT_BUFFER {
195 u32 TimeStamp;
196 u8 GPIOStatus;
197 u8 UARTStatus;
198 u8 RXCharacter;
199 u8 EventStatus;
200 u32 Reserved[2];
201} __attribute__ ((__packed__));
202
203/* Firmware commands. */
204
205enum OPCODES {
206 CMD_NOP = 0,
207 CMD_FWLOAD_PREPARE = 0x01,
208 CMD_FWLOAD_FINISH = 0x02,
209 CMD_I2C_READ = 0x03,
210 CMD_I2C_WRITE = 0x04,
211
212 CMD_I2C_WRITE_NOSTOP = 0x05,
213 CMD_I2C_CONTINUE_WRITE = 0x06,
214 CMD_I2C_CONTINUE_WRITE_NOSTOP = 0x07,
215
216 CMD_DEBUG_OUTPUT = 0x09,
217
218 CMD_CONTROL = 0x10,
219 CMD_CONFIGURE_BUFFER = 0x11,
220 CMD_CONFIGURE_FREE_BUFFER = 0x12,
221
222 CMD_SPI_READ = 0x13,
223 CMD_SPI_WRITE = 0x14,
224
225 CMD_MEM_READ = 0x20,
226 CMD_MEM_WRITE = 0x21,
227 CMD_SFR_READ = 0x22,
228 CMD_SFR_WRITE = 0x23,
229 CMD_IRAM_READ = 0x24,
230 CMD_IRAM_WRITE = 0x25,
231 CMD_SET_GPIO_PIN = 0x26,
232 CMD_SET_GPIO_INT = 0x27,
233 CMD_CONFIGURE_UART = 0x28,
234 CMD_WRITE_UART = 0x29,
235 MAX_CMD
236};
237
238enum RESPONSES {
239 OK = 0,
240 ERROR = 1
241};
242
243struct FW_HEADER {
244 u8 Opcode;
245 u8 Length;
246} __attribute__ ((__packed__));
247
248struct FW_I2C_WRITE {
249 struct FW_HEADER hdr;
250 u8 Device;
251 u8 Data[250];
252} __attribute__ ((__packed__));
253
254struct FW_I2C_CONTINUE_WRITE {
255 struct FW_HEADER hdr;
256 u8 Data[250];
257} __attribute__ ((__packed__));
258
259struct FW_I2C_READ {
260 struct FW_HEADER hdr;
261 u8 Device;
262 u8 Data[252]; /* followed by two bytes of read data count */
263} __attribute__ ((__packed__));
264
265struct FW_SPI_WRITE {
266 struct FW_HEADER hdr;
267 u8 ModeSelect;
268 u8 Data[250];
269} __attribute__ ((__packed__));
270
271struct FW_SPI_READ {
272 struct FW_HEADER hdr;
273 u8 ModeSelect;
274 u8 Data[252]; /* followed by two bytes of read data count */
275} __attribute__ ((__packed__));
276
277struct FW_FWLOAD_PREPARE {
278 struct FW_HEADER hdr;
279} __attribute__ ((__packed__));
280
281struct FW_FWLOAD_FINISH {
282 struct FW_HEADER hdr;
283 u16 Address; /* address of final block */
284 u16 Length;
285} __attribute__ ((__packed__));
286
287/*
288 * Meaning of FW_STREAM_CONTROL::Mode bits:
289 * Bit 7: Loopback PEXin to PEXout using TVOut channel
290 * Bit 6: AVLOOP
291 * Bit 5: Audio select; 0=I2S, 1=SPDIF
292 * Bit 4: AVSYNC
293 * Bit 3: Enable transport stream
294 * Bit 2: Enable audio capture
295 * Bit 1: Enable ITU-Video VBI capture
296 * Bit 0: Enable ITU-Video capture
297 *
298 * Meaning of FW_STREAM_CONTROL::Control bits (see UVI1_CTL)
299 * Bit 7: continuous capture
300 * Bit 6: capture one field
301 * Bit 5: capture one frame
302 * Bit 4: unused
303 * Bit 3: starting field; 0=odd, 1=even
304 * Bit 2: sample size; 0=8-bit, 1=10-bit
305 * Bit 1: data format; 0=UYVY, 1=YUY2
306 * Bit 0: resets buffer pointers
307*/
308
309enum FSC_MODE_BITS {
310 SMODE_LOOPBACK = 0x80,
311 SMODE_AVLOOP = 0x40,
312 _SMODE_AUDIO_SPDIF = 0x20,
313 _SMODE_AVSYNC = 0x10,
314 _SMODE_TRANSPORT_STREAM = 0x08,
315 _SMODE_AUDIO_CAPTURE = 0x04,
316 _SMODE_VBI_CAPTURE = 0x02,
317 _SMODE_VIDEO_CAPTURE = 0x01
318};
319
320
321/* Meaning of FW_STREAM_CONTROL::Stream bits:
322 * Bit 3: Audio sample count: 0 = relative, 1 = absolute
323 * Bit 2: color bar select; 1=color bars, 0=CV3 decoder
324 * Bits 1-0: stream select, UVI1, UVI2, TVOUT
325 */
326
327struct FW_STREAM_CONTROL {
328 struct FW_HEADER hdr;
329 u8 Stream; /* Stream number (UVI1, UVI2, TVOUT) */
330 u8 Control; /* Value written to UVI1_CTL */
331 u8 Mode; /* Controls clock source */
332 u8 SetupDataLen; /* Length of setup data, MSB=1 write
333 backwards */
334 u16 CaptureBlockCount; /* Blocks (a 256 Bytes) to capture per buffer
335 for TS and Audio */
336 u64 Buffer_Address; /* Address of first buffer header */
337 u16 BytesPerVideoLine;
338 u16 MaxLinesPerField;
339 u16 MinLinesPerField;
340 u16 Reserved_1;
341 u16 BytesPerVBILine;
342 u16 MaxVBILinesPerField;
343 u16 MinVBILinesPerField;
344 u16 SetupDataAddr; /* ngene relative address of setup data */
345 u8 SetupData[32]; /* setup data */
346} __attribute__((__packed__));
347
348#define AUDIO_BLOCK_SIZE 256
349#define TS_BLOCK_SIZE 256
350
351struct FW_MEM_READ {
352 struct FW_HEADER hdr;
353 u16 address;
354} __attribute__ ((__packed__));
355
356struct FW_MEM_WRITE {
357 struct FW_HEADER hdr;
358 u16 address;
359 u8 data;
360} __attribute__ ((__packed__));
361
362struct FW_SFR_IRAM_READ {
363 struct FW_HEADER hdr;
364 u8 address;
365} __attribute__ ((__packed__));
366
367struct FW_SFR_IRAM_WRITE {
368 struct FW_HEADER hdr;
369 u8 address;
370 u8 data;
371} __attribute__ ((__packed__));
372
373struct FW_SET_GPIO_PIN {
374 struct FW_HEADER hdr;
375 u8 select;
376} __attribute__ ((__packed__));
377
378struct FW_SET_GPIO_INT {
379 struct FW_HEADER hdr;
380 u8 select;
381} __attribute__ ((__packed__));
382
383struct FW_SET_DEBUGMODE {
384 struct FW_HEADER hdr;
385 u8 debug_flags;
386} __attribute__ ((__packed__));
387
388struct FW_CONFIGURE_BUFFERS {
389 struct FW_HEADER hdr;
390 u8 config;
391} __attribute__ ((__packed__));
392
393enum _BUFFER_CONFIGS {
394 /* 4k UVI1, 4k UVI2, 2k AUD1, 2k AUD2 (standard usage) */
395 BUFFER_CONFIG_4422 = 0,
396 /* 3k UVI1, 3k UVI2, 3k AUD1, 3k AUD2 (4x TS input usage) */
397 BUFFER_CONFIG_3333 = 1,
398 /* 8k UVI1, 0k UVI2, 2k AUD1, 2k I2SOut (HDTV decoder usage) */
399 BUFFER_CONFIG_8022 = 2,
400 BUFFER_CONFIG_FW17 = 255, /* Use new FW 17 command */
401};
402
403struct FW_CONFIGURE_FREE_BUFFERS {
404 struct FW_HEADER hdr;
405 u8 UVI1_BufferLength;
406 u8 UVI2_BufferLength;
407 u8 TVO_BufferLength;
408 u8 AUD1_BufferLength;
409 u8 AUD2_BufferLength;
410 u8 TVA_BufferLength;
411} __attribute__ ((__packed__));
412
413struct FW_CONFIGURE_UART {
414 struct FW_HEADER hdr;
415 u8 UartControl;
416} __attribute__ ((__packed__));
417
418enum _UART_CONFIG {
419 _UART_BAUDRATE_19200 = 0,
420 _UART_BAUDRATE_9600 = 1,
421 _UART_BAUDRATE_4800 = 2,
422 _UART_BAUDRATE_2400 = 3,
423 _UART_RX_ENABLE = 0x40,
424 _UART_TX_ENABLE = 0x80,
425};
426
427struct FW_WRITE_UART {
428 struct FW_HEADER hdr;
429 u8 Data[252];
430} __attribute__ ((__packed__));
431
432
433struct ngene_command {
434 u32 in_len;
435 u32 out_len;
436 union {
437 u32 raw[64];
438 u8 raw8[256];
439 struct FW_HEADER hdr;
440 struct FW_I2C_WRITE I2CWrite;
441 struct FW_I2C_CONTINUE_WRITE I2CContinueWrite;
442 struct FW_I2C_READ I2CRead;
443 struct FW_STREAM_CONTROL StreamControl;
444 struct FW_FWLOAD_PREPARE FWLoadPrepare;
445 struct FW_FWLOAD_FINISH FWLoadFinish;
446 struct FW_MEM_READ MemoryRead;
447 struct FW_MEM_WRITE MemoryWrite;
448 struct FW_SFR_IRAM_READ SfrIramRead;
449 struct FW_SFR_IRAM_WRITE SfrIramWrite;
450 struct FW_SPI_WRITE SPIWrite;
451 struct FW_SPI_READ SPIRead;
452 struct FW_SET_GPIO_PIN SetGpioPin;
453 struct FW_SET_GPIO_INT SetGpioInt;
454 struct FW_SET_DEBUGMODE SetDebugMode;
455 struct FW_CONFIGURE_BUFFERS ConfigureBuffers;
456 struct FW_CONFIGURE_FREE_BUFFERS ConfigureFreeBuffers;
457 struct FW_CONFIGURE_UART ConfigureUart;
458 struct FW_WRITE_UART WriteUart;
459 } cmd;
460} __attribute__ ((__packed__));
461
462#define NGENE_INTERFACE_VERSION 0x103
463#define MAX_VIDEO_BUFFER_SIZE (417792) /* 288*1440 rounded up to next page */
464#define MAX_AUDIO_BUFFER_SIZE (8192) /* Gives room for about 23msec@48KHz */
465#define MAX_VBI_BUFFER_SIZE (28672) /* 1144*18 rounded up to next page */
466#define MAX_TS_BUFFER_SIZE (98304) /* 512*188 rounded up to next page */
467#define MAX_HDTV_BUFFER_SIZE (2080768) /* 541*1920*2 rounded up to next page
468 Max: (1920x1080i60) */
469
470#define OVERFLOW_BUFFER_SIZE (8192)
471
472#define RING_SIZE_VIDEO 4
473#define RING_SIZE_AUDIO 8
474#define RING_SIZE_TS 8
475
476#define NUM_SCATTER_GATHER_ENTRIES 8
477
478#define MAX_DMA_LENGTH (((MAX_VIDEO_BUFFER_SIZE + MAX_VBI_BUFFER_SIZE) * \
479 RING_SIZE_VIDEO * 2) + \
480 (MAX_AUDIO_BUFFER_SIZE * RING_SIZE_AUDIO * 2) + \
481 (MAX_TS_BUFFER_SIZE * RING_SIZE_TS * 4) + \
482 (RING_SIZE_VIDEO * PAGE_SIZE * 2) + \
483 (RING_SIZE_AUDIO * PAGE_SIZE * 2) + \
484 (RING_SIZE_TS * PAGE_SIZE * 4) + \
485 8 * PAGE_SIZE + OVERFLOW_BUFFER_SIZE + PAGE_SIZE)
486
487#define EVENT_QUEUE_SIZE 16
488
489/* Gathers the current state of a single channel. */
490
491struct SBufferHeader {
492 struct BUFFER_HEADER ngeneBuffer; /* Physical descriptor */
493 struct SBufferHeader *Next;
494 void *Buffer1;
495 struct HW_SCATTER_GATHER_ELEMENT *scList1;
496 void *Buffer2;
497 struct HW_SCATTER_GATHER_ELEMENT *scList2;
498};
499
500/* Sizeof SBufferHeader aligned to next 64 Bit boundary (hw restriction) */
501#define SIZEOF_SBufferHeader ((sizeof(struct SBufferHeader) + 63) & ~63)
502
503enum HWSTATE {
504 HWSTATE_STOP,
505 HWSTATE_STARTUP,
506 HWSTATE_RUN,
507 HWSTATE_PAUSE,
508};
509
510enum KSSTATE {
511 KSSTATE_STOP,
512 KSSTATE_ACQUIRE,
513 KSSTATE_PAUSE,
514 KSSTATE_RUN,
515};
516
517struct SRingBufferDescriptor {
518 struct SBufferHeader *Head; /* Points to first buffer in ring buffer
519 structure*/
520 u64 PAHead; /* Physical address of first buffer */
521 u32 MemSize; /* Memory size of allocated ring buffers
522 (needed for freeing) */
523 u32 NumBuffers; /* Number of buffers in the ring */
524 u32 Buffer1Length; /* Allocated length of Buffer 1 */
525 u32 Buffer2Length; /* Allocated length of Buffer 2 */
526 void *SCListMem; /* Memory to hold scatter gather lists for this
527 ring */
528 u64 PASCListMem; /* Physical address .. */
529 u32 SCListMemSize; /* Size of this memory */
530};
531
532enum STREAMMODEFLAGS {
533 StreamMode_NONE = 0, /* Stream not used */
534 StreamMode_ANALOG = 1, /* Analog: Stream 0,1 = Video, 2,3 = Audio */
535 StreamMode_TSIN = 2, /* Transport stream input (all) */
536 StreamMode_HDTV = 4, /* HDTV: Maximum 1920x1080p30,1920x1080i60
537 (only stream 0) */
538 StreamMode_TSOUT = 8, /* Transport stream output (only stream 3) */
539};
540
541
542enum BufferExchangeFlags {
543 BEF_EVEN_FIELD = 0x00000001,
544 BEF_CONTINUATION = 0x00000002,
545 BEF_MORE_DATA = 0x00000004,
546 BEF_OVERFLOW = 0x00000008,
547 DF_SWAP32 = 0x00010000,
548};
549
550typedef void *(IBufferExchange)(void *, void *, u32, u32, u32);
551
552struct MICI_STREAMINFO {
553 IBufferExchange *pExchange;
554 IBufferExchange *pExchangeVBI; /* Secondary (VBI, ancillary) */
555 u8 Stream;
556 u8 Flags;
557 u8 Mode;
558 u8 Reserved;
559 u16 nLinesVideo;
560 u16 nBytesPerLineVideo;
561 u16 nLinesVBI;
562 u16 nBytesPerLineVBI;
563 u32 CaptureLength; /* Used for audio and transport stream */
564};
565
566/****************************************************************************/
567/* STRUCTS ******************************************************************/
568/****************************************************************************/
569
570/* sound hardware definition */
571#define MIXER_ADDR_TVTUNER 0
572#define MIXER_ADDR_LAST 0
573
574struct ngene_channel;
575
576/*struct sound chip*/
577
578struct mychip {
579 struct ngene_channel *chan;
580 struct snd_card *card;
581 struct pci_dev *pci;
582 struct snd_pcm_substream *substream;
583 struct snd_pcm *pcm;
584 unsigned long port;
585 int irq;
586 spinlock_t mixer_lock;
587 spinlock_t lock;
588 int mixer_volume[MIXER_ADDR_LAST + 1][2];
589 int capture_source[MIXER_ADDR_LAST + 1][2];
590};
591
592#ifdef NGENE_V4L
593struct ngene_overlay {
594 int tvnorm;
595 struct v4l2_rect w;
596 enum v4l2_field field;
597 struct v4l2_clip *clips;
598 int nclips;
599 int setup_ok;
600};
601
602struct ngene_tvnorm {
603 int v4l2_id;
604 char *name;
605 u16 swidth, sheight; /* scaled standard width, height */
606 int tuner_norm;
607 int soundstd;
608};
609
610struct ngene_vopen {
611 struct ngene_channel *ch;
612 enum v4l2_priority prio;
613 int width;
614 int height;
615 int depth;
616 struct videobuf_queue vbuf_q;
617 struct videobuf_queue vbi;
618 int fourcc;
619 int picxcount;
620 int resources;
621 enum v4l2_buf_type type;
622 const struct ngene_format *fmt;
623
624 const struct ngene_format *ovfmt;
625 struct ngene_overlay ov;
626};
627#endif
628
629struct ngene_channel {
630 struct device device;
631 struct i2c_adapter i2c_adapter;
632
633 struct ngene *dev;
634 int number;
635 int type;
636 int mode;
637
638 struct dvb_frontend *fe;
639 struct dmxdev dmxdev;
640 struct dvb_demux demux;
641 struct dmx_frontend hw_frontend;
642 struct dmx_frontend mem_frontend;
643 int users;
644 struct video_device *v4l_dev;
645 struct tasklet_struct demux_tasklet;
646
647 struct SBufferHeader *nextBuffer;
648 enum KSSTATE State;
649 enum HWSTATE HWState;
650 u8 Stream;
651 u8 Flags;
652 u8 Mode;
653 IBufferExchange *pBufferExchange;
654 IBufferExchange *pBufferExchange2;
655
656 spinlock_t state_lock;
657 u16 nLines;
658 u16 nBytesPerLine;
659 u16 nVBILines;
660 u16 nBytesPerVBILine;
661 u16 itumode;
662 u32 Capture1Length;
663 u32 Capture2Length;
664 struct SRingBufferDescriptor RingBuffer;
665 struct SRingBufferDescriptor TSRingBuffer;
666 struct SRingBufferDescriptor TSIdleBuffer;
667
668 u32 DataFormatFlags;
669
670 int AudioDTOUpdated;
671 u32 AudioDTOValue;
672
673 int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t);
674 u8 lnbh;
675
676 /* stuff from analog driver */
677
678 int minor;
679 struct mychip *mychip;
680 struct snd_card *soundcard;
681 u8 *evenbuffer;
682 u8 dma_on;
683 int soundstreamon;
684 int audiomute;
685 int soundbuffisallocated;
686 int sndbuffflag;
687 int tun_rdy;
688 int dec_rdy;
689 int tun_dec_rdy;
690 int lastbufferflag;
691
692 struct ngene_tvnorm *tvnorms;
693 int tvnorm_num;
694 int tvnorm;
695
696#ifdef NGENE_V4L
697 int videousers;
698 struct v4l2_prio_state prio;
699 struct ngene_vopen init;
700 int resources;
701 struct v4l2_framebuffer fbuf;
702 struct ngene_buffer *screen; /* overlay */
703 struct list_head capture; /* video capture queue */
704 spinlock_t s_lock;
705 struct semaphore reslock;
706#endif
707
708 int running;
709};
710
711struct ngene;
712
713typedef void (rx_cb_t)(struct ngene *, u32, u8);
714typedef void (tx_cb_t)(struct ngene *, u32);
715
716struct ngene {
717 int nr;
718 struct pci_dev *pci_dev;
719 unsigned char *iomem;
720
721 /*struct i2c_adapter i2c_adapter;*/
722
723 u32 device_version;
724 u32 fw_interface_version;
725 u32 icounts;
726
727 u8 *CmdDoneByte;
728 int BootFirmware;
729 void *OverflowBuffer;
730 dma_addr_t PAOverflowBuffer;
731 void *FWInterfaceBuffer;
732 dma_addr_t PAFWInterfaceBuffer;
733 u8 *ngenetohost;
734 u8 *hosttongene;
735
736 struct EVENT_BUFFER EventQueue[EVENT_QUEUE_SIZE];
737 int EventQueueOverflowCount;
738 int EventQueueOverflowFlag;
739 struct tasklet_struct event_tasklet;
740 struct EVENT_BUFFER *EventBuffer;
741 int EventQueueWriteIndex;
742 int EventQueueReadIndex;
743
744 wait_queue_head_t cmd_wq;
745 int cmd_done;
746 struct semaphore cmd_mutex;
747 struct semaphore stream_mutex;
748 struct semaphore pll_mutex;
749 struct semaphore i2c_switch_mutex;
750 int i2c_current_channel;
751 int i2c_current_bus;
752 spinlock_t cmd_lock;
753
754 struct dvb_adapter adapter[MAX_STREAM];
755 struct ngene_channel channel[MAX_STREAM];
756
757 struct ngene_info *card_info;
758
759 tx_cb_t *TxEventNotify;
760 rx_cb_t *RxEventNotify;
761 int tx_busy;
762 wait_queue_head_t tx_wq;
763 wait_queue_head_t rx_wq;
764#define UART_RBUF_LEN 4096
765 u8 uart_rbuf[UART_RBUF_LEN];
766 int uart_rp, uart_wp;
767
768 u8 *tsout_buf;
769#define TSOUT_BUF_SIZE (512*188*8)
770 struct dvb_ringbuffer tsout_rbuf;
771
772 u8 *ain_buf;
773#define AIN_BUF_SIZE (128*1024)
774 struct dvb_ringbuffer ain_rbuf;
775
776
777 u8 *vin_buf;
778#define VIN_BUF_SIZE (4*1920*1080)
779 struct dvb_ringbuffer vin_rbuf;
780
781 unsigned long exp_val;
782 int prev_cmd;
783};
784
785struct ngene_info {
786 int type;
787#define NGENE_APP 0
788#define NGENE_TERRATEC 1
789#define NGENE_SIDEWINDER 2
790#define NGENE_RACER 3
791#define NGENE_VIPER 4
792#define NGENE_PYTHON 5
793#define NGENE_VBOX_V1 6
794#define NGENE_VBOX_V2 7
795
796 int fw_version;
797 char *name;
798
799 int io_type[MAX_STREAM];
800#define NGENE_IO_NONE 0
801#define NGENE_IO_TV 1
802#define NGENE_IO_HDTV 2
803#define NGENE_IO_TSIN 4
804#define NGENE_IO_TSOUT 8
805#define NGENE_IO_AIN 16
806
807 void *fe_config[4];
808 void *tuner_config[4];
809
810 int (*demod_attach[4])(struct ngene_channel *);
811 int (*tuner_attach[4])(struct ngene_channel *);
812
813 u8 avf[4];
814 u8 msp[4];
815 u8 demoda[4];
816 u8 lnb[4];
817 int i2c_access;
818 u8 ntsc;
819 u8 tsf[4];
820 u8 i2s[4];
821
822 int (*gate_ctrl)(struct dvb_frontend *, int);
823 int (*switch_ctrl)(struct ngene_channel *, int, int);
824};
825
826#ifdef NGENE_V4L
827struct ngene_format{
828 char *name;
829 int fourcc; /* video4linux 2 */
830 int btformat; /* BT848_COLOR_FMT_* */
831 int format;
832 int btswap; /* BT848_COLOR_CTL_* */
833 int depth; /* bit/pixel */
834 int flags;
835 int hshift, vshift; /* for planar modes */
836 int palette;
837};
838
839#define RESOURCE_OVERLAY 1
840#define RESOURCE_VIDEO 2
841#define RESOURCE_VBI 4
842
843struct ngene_buffer {
844 /* common v4l buffer stuff -- must be first */
845 struct videobuf_buffer vb;
846
847 /* ngene specific */
848 const struct ngene_format *fmt;
849 int tvnorm;
850 int btformat;
851 int btswap;
852};
853#endif
854
855
856#endif
857
858/* LocalWords: Endif
859 */
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 1067b22eb0c6..cff77e2eb557 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -62,6 +62,7 @@ static struct sms_board sms_boards[] = {
62 [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { 62 [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
63 .name = "Hauppauge WinTV MiniStick", 63 .name = "Hauppauge WinTV MiniStick",
64 .type = SMS_NOVA_B0, 64 .type = SMS_NOVA_B0,
65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
65 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
66 .board_cfg.leds_power = 26, 67 .board_cfg.leds_power = 26,
67 .board_cfg.led0 = 27, 68 .board_cfg.led0 = 27,
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index ca758bcb48c9..4bfd3451b568 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -1459,8 +1459,10 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1459 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { 1459 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1460 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; 1460 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1461 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, 1461 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1462 &groupCfg) != 0) 1462 &groupCfg) != 0) {
1463 return -EINVAL; 1463 rc = -EINVAL;
1464 goto free;
1465 }
1464 1466
1465 pMsg->msgData[1] = TranslatedPinNum; 1467 pMsg->msgData[1] = TranslatedPinNum;
1466 pMsg->msgData[2] = GroupNum; 1468 pMsg->msgData[2] = GroupNum;
@@ -1490,6 +1492,7 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1490 else 1492 else
1491 sms_err("smscore_gpio_configure error"); 1493 sms_err("smscore_gpio_configure error");
1492 } 1494 }
1495free:
1493 kfree(buffer); 1496 kfree(buffer);
1494 1497
1495 return rc; 1498 return rc;
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index eec18aaf5512..8ecadecaa9d0 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -212,6 +212,8 @@ struct smscore_device_t {
212#define MSG_SMS_DAB_CHANNEL 607 212#define MSG_SMS_DAB_CHANNEL 607
213#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 213#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
214#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 214#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
215#define MSG_SMS_GET_STATISTICS_RES 616
216#define MSG_SMS_GET_STATISTICS_REQ 615
215#define MSG_SMS_HO_PER_SLICES_IND 630 217#define MSG_SMS_HO_PER_SLICES_IND 630
216#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 218#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
217#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 219#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
@@ -339,7 +341,7 @@ struct SmsFirmware_ST {
339 341
340/* Statistics information returned as response for 342/* Statistics information returned as response for
341 * SmsHostApiGetStatistics_Req */ 343 * SmsHostApiGetStatistics_Req */
342struct SMSHOSTLIB_STATISTICS_S { 344struct SMSHOSTLIB_STATISTICS_ST {
343 u32 Reserved; /* Reserved */ 345 u32 Reserved; /* Reserved */
344 346
345 /* Common parameters */ 347 /* Common parameters */
@@ -424,6 +426,79 @@ struct SMSHOSTLIB_STATISTICS_S {
424 u32 ReservedFields[10]; /* Reserved */ 426 u32 ReservedFields[10]; /* Reserved */
425}; 427};
426 428
429struct SmsMsgStatisticsInfo_ST {
430 u32 RequestResult;
431
432 struct SMSHOSTLIB_STATISTICS_ST Stat;
433
434 /* Split the calc of the SNR in DAB */
435 u32 Signal; /* dB */
436 u32 Noise; /* dB */
437
438};
439
440struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
441 /* Per-layer information */
442 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
443 * 255 means layer does not exist */
444 u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
445 * 255 means layer does not exist */
446 u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
447 u32 BERErrorCount; /* Post Viterbi Error Bits Count */
448 u32 BERBitCount; /* Post Viterbi Total Bits Count */
449 u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
450 u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
451 u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
452 u32 TotalTSPackets; /* Total number of transport-stream packets */
453 u32 TILdepthI; /* Time interleaver depth I parameter,
454 * 255 means layer does not exist */
455 u32 NumberOfSegments; /* Number of segments in layer A,
456 * 255 means layer does not exist */
457 u32 TMCCErrors; /* TMCC errors */
458};
459
460struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
461 u32 StatisticsType; /* Enumerator identifying the type of the
462 * structure. Values are the same as
463 * SMSHOSTLIB_DEVICE_MODES_E
464 *
465 * This field MUST always be first in any
466 * statistics structure */
467
468 u32 FullSize; /* Total size of the structure returned by the modem.
469 * If the size requested by the host is smaller than
470 * FullSize, the struct will be truncated */
471
472 /* Common parameters */
473 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
474 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
475 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
476
477 /* Reception quality */
478 s32 SNR; /* dB */
479 s32 RSSI; /* dBm */
480 s32 InBandPwr; /* In band power in dBM */
481 s32 CarrierOffset; /* Carrier Offset in Hz */
482
483 /* Transmission parameters */
484 u32 Frequency; /* Frequency in Hz */
485 u32 Bandwidth; /* Bandwidth in MHz */
486 u32 TransmissionMode; /* ISDB-T transmission mode */
487 u32 ModemState; /* 0 - Acquisition, 1 - Locked */
488 u32 GuardInterval; /* Guard Interval, 1 divided by value */
489 u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
490 u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
491 u32 NumOfLayers; /* Number of ISDB-T layers in the network */
492
493 /* Per-layer information */
494 /* Layers A, B and C */
495 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3];
496 /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
497
498 /* Interface information */
499 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
500};
501
427struct PID_STATISTICS_DATA_S { 502struct PID_STATISTICS_DATA_S {
428 struct PID_BURST_S { 503 struct PID_BURST_S {
429 u32 size; 504 u32 size;
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 68bf9fbd8fed..5f3939821ca3 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -116,6 +116,118 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client,
116 } 116 }
117} 117}
118 118
119
120static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
121 struct SMSHOSTLIB_STATISTICS_ST *p)
122{
123 if (sms_dbg & 2) {
124 printk(KERN_DEBUG "Reserved = %d", p->Reserved);
125 printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
126 printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
127 printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
128 printk(KERN_DEBUG "SNR = %d", p->SNR);
129 printk(KERN_DEBUG "BER = %d", p->BER);
130 printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
131 printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
132 printk(KERN_DEBUG "MFER = %d", p->MFER);
133 printk(KERN_DEBUG "RSSI = %d", p->RSSI);
134 printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
135 printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
136 printk(KERN_DEBUG "Frequency = %d", p->Frequency);
137 printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
138 printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
139 printk(KERN_DEBUG "ModemState = %d", p->ModemState);
140 printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
141 printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
142 printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
143 printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
144 printk(KERN_DEBUG "Constellation = %d", p->Constellation);
145 printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
146 printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
147 printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
148 printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
149 printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
150 printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
151 printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
152 printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
153 printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
154 printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
155 printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
156 printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
157 printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
158 printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
159 printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
160 printk(KERN_DEBUG "PreBER = %d", p->PreBER);
161 printk(KERN_DEBUG "CellId = %d", p->CellId);
162 printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
163 printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
164 printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
165 }
166
167 pReceptionData->IsDemodLocked = p->IsDemodLocked;
168
169 pReceptionData->SNR = p->SNR;
170 pReceptionData->BER = p->BER;
171 pReceptionData->BERErrorCount = p->BERErrorCount;
172 pReceptionData->InBandPwr = p->InBandPwr;
173 pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
174};
175
176
177static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
178 struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
179{
180 int i;
181
182 if (sms_dbg & 2) {
183 printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
184 printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
185 printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
186 printk(KERN_DEBUG "SNR = %d", p->SNR);
187 printk(KERN_DEBUG "RSSI = %d", p->RSSI);
188 printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
189 printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
190 printk(KERN_DEBUG "Frequency = %d", p->Frequency);
191 printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
192 printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
193 printk(KERN_DEBUG "ModemState = %d", p->ModemState);
194 printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
195 printk(KERN_DEBUG "SystemType = %d", p->SystemType);
196 printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
197 printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
198 printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
199
200 for (i = 0; i < 3; i++) {
201 printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
202 printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
203 printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
204 printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
205 printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
206 printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
207 printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
208 printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
209 printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
210 printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
211 printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
212 printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
213 }
214 }
215
216 pReceptionData->IsDemodLocked = p->IsDemodLocked;
217
218 pReceptionData->SNR = p->SNR;
219 pReceptionData->InBandPwr = p->InBandPwr;
220
221 pReceptionData->ErrorTSPackets = 0;
222 pReceptionData->BER = 0;
223 pReceptionData->BERErrorCount = 0;
224 for (i = 0; i < 3; i++) {
225 pReceptionData->BER += p->LayerInfo[i].BER;
226 pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
227 pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
228 }
229}
230
119static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) 231static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
120{ 232{
121 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; 233 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -134,6 +246,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
134 break; 246 break;
135 247
136 case MSG_SMS_RF_TUNE_RES: 248 case MSG_SMS_RF_TUNE_RES:
249 case MSG_SMS_ISDBT_TUNE_RES:
137 complete(&client->tune_done); 250 complete(&client->tune_done);
138 break; 251 break;
139 252
@@ -217,6 +330,40 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
217 is_status_update = true; 330 is_status_update = true;
218 break; 331 break;
219 } 332 }
333 case MSG_SMS_GET_STATISTICS_RES: {
334 union {
335 struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt;
336 struct SmsMsgStatisticsInfo_ST dvb;
337 } *p = (void *) (phdr + 1);
338 struct RECEPTION_STATISTICS_S *pReceptionData =
339 &client->sms_stat_dvb.ReceptionData;
340
341 sms_info("MSG_SMS_GET_STATISTICS_RES");
342
343 is_status_update = true;
344
345 switch (smscore_get_device_mode(client->coredev)) {
346 case DEVICE_MODE_ISDBT:
347 case DEVICE_MODE_ISDBT_BDA:
348 smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
349 break;
350 default:
351 smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
352 }
353 if (!pReceptionData->IsDemodLocked) {
354 pReceptionData->SNR = 0;
355 pReceptionData->BER = 0;
356 pReceptionData->BERErrorCount = 0;
357 pReceptionData->InBandPwr = 0;
358 pReceptionData->ErrorTSPackets = 0;
359 }
360
361 complete(&client->tune_done);
362 break;
363 }
364 default:
365 sms_info("Unhandled message %d", phdr->msgType);
366
220 } 367 }
221 smscore_putbuffer(client->coredev, cb); 368 smscore_putbuffer(client->coredev, cb);
222 369
@@ -233,10 +380,10 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
233 DVB3_EVENT_UNC_ERR); 380 DVB3_EVENT_UNC_ERR);
234 381
235 } else { 382 } else {
236 /*client->fe_status = 383 if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
237 (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ? 384 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
238 0 : FE_HAS_SIGNAL;*/ 385 else
239 client->fe_status = 0; 386 client->fe_status = 0;
240 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); 387 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
241 } 388 }
242 } 389 }
@@ -325,6 +472,20 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
325 0 : -ETIME; 472 0 : -ETIME;
326} 473}
327 474
475static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
476{
477 int rc;
478 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
479 DVBT_BDA_CONTROL_MSG_ID,
480 HIF_TASK,
481 sizeof(struct SmsMsgHdr_ST), 0 };
482
483 rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
484 &client->tune_done);
485
486 return rc;
487}
488
328static inline int led_feedback(struct smsdvb_client_t *client) 489static inline int led_feedback(struct smsdvb_client_t *client)
329{ 490{
330 if (client->fe_status & FE_HAS_LOCK) 491 if (client->fe_status & FE_HAS_LOCK)
@@ -337,33 +498,43 @@ static inline int led_feedback(struct smsdvb_client_t *client)
337 498
338static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) 499static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
339{ 500{
501 int rc;
340 struct smsdvb_client_t *client; 502 struct smsdvb_client_t *client;
341 client = container_of(fe, struct smsdvb_client_t, frontend); 503 client = container_of(fe, struct smsdvb_client_t, frontend);
342 504
505 rc = smsdvb_send_statistics_request(client);
506
343 *stat = client->fe_status; 507 *stat = client->fe_status;
344 508
345 led_feedback(client); 509 led_feedback(client);
346 510
347 return 0; 511 return rc;
348} 512}
349 513
350static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) 514static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
351{ 515{
516 int rc;
352 struct smsdvb_client_t *client; 517 struct smsdvb_client_t *client;
353 client = container_of(fe, struct smsdvb_client_t, frontend); 518 client = container_of(fe, struct smsdvb_client_t, frontend);
354 519
520 rc = smsdvb_send_statistics_request(client);
521
355 *ber = client->sms_stat_dvb.ReceptionData.BER; 522 *ber = client->sms_stat_dvb.ReceptionData.BER;
356 523
357 led_feedback(client); 524 led_feedback(client);
358 525
359 return 0; 526 return rc;
360} 527}
361 528
362static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 529static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
363{ 530{
531 int rc;
532
364 struct smsdvb_client_t *client; 533 struct smsdvb_client_t *client;
365 client = container_of(fe, struct smsdvb_client_t, frontend); 534 client = container_of(fe, struct smsdvb_client_t, frontend);
366 535
536 rc = smsdvb_send_statistics_request(client);
537
367 if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) 538 if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
368 *strength = 0; 539 *strength = 0;
369 else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) 540 else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
@@ -375,31 +546,37 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
375 546
376 led_feedback(client); 547 led_feedback(client);
377 548
378 return 0; 549 return rc;
379} 550}
380 551
381static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) 552static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
382{ 553{
554 int rc;
383 struct smsdvb_client_t *client; 555 struct smsdvb_client_t *client;
384 client = container_of(fe, struct smsdvb_client_t, frontend); 556 client = container_of(fe, struct smsdvb_client_t, frontend);
385 557
558 rc = smsdvb_send_statistics_request(client);
559
386 *snr = client->sms_stat_dvb.ReceptionData.SNR; 560 *snr = client->sms_stat_dvb.ReceptionData.SNR;
387 561
388 led_feedback(client); 562 led_feedback(client);
389 563
390 return 0; 564 return rc;
391} 565}
392 566
393static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 567static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
394{ 568{
569 int rc;
395 struct smsdvb_client_t *client; 570 struct smsdvb_client_t *client;
396 client = container_of(fe, struct smsdvb_client_t, frontend); 571 client = container_of(fe, struct smsdvb_client_t, frontend);
397 572
573 rc = smsdvb_send_statistics_request(client);
574
398 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; 575 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
399 576
400 led_feedback(client); 577 led_feedback(client);
401 578
402 return 0; 579 return rc;
403} 580}
404 581
405static int smsdvb_get_tune_settings(struct dvb_frontend *fe, 582static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
@@ -413,9 +590,10 @@ static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
413 return 0; 590 return 0;
414} 591}
415 592
416static int smsdvb_set_frontend(struct dvb_frontend *fe, 593static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe,
417 struct dvb_frontend_parameters *fep) 594 struct dvb_frontend_parameters *p)
418{ 595{
596 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
419 struct smsdvb_client_t *client = 597 struct smsdvb_client_t *client =
420 container_of(fe, struct smsdvb_client_t, frontend); 598 container_of(fe, struct smsdvb_client_t, frontend);
421 599
@@ -429,24 +607,33 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
429 client->fe_status = FE_HAS_SIGNAL; 607 client->fe_status = FE_HAS_SIGNAL;
430 client->event_fe_state = -1; 608 client->event_fe_state = -1;
431 client->event_unc_state = -1; 609 client->event_unc_state = -1;
610 fe->dtv_property_cache.delivery_system = SYS_DVBT;
432 611
433 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 612 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
434 Msg.Msg.msgDstId = HIF_TASK; 613 Msg.Msg.msgDstId = HIF_TASK;
435 Msg.Msg.msgFlags = 0; 614 Msg.Msg.msgFlags = 0;
436 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; 615 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
437 Msg.Msg.msgLength = sizeof(Msg); 616 Msg.Msg.msgLength = sizeof(Msg);
438 Msg.Data[0] = fep->frequency; 617 Msg.Data[0] = c->frequency;
439 Msg.Data[2] = 12000000; 618 Msg.Data[2] = 12000000;
440 619
441 sms_debug("freq %d band %d", 620 sms_info("%s: freq %d band %d", __func__, c->frequency,
442 fep->frequency, fep->u.ofdm.bandwidth); 621 c->bandwidth_hz);
443 622
444 switch (fep->u.ofdm.bandwidth) { 623 switch (c->bandwidth_hz / 1000000) {
445 case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; 624 case 8:
446 case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; 625 Msg.Data[1] = BW_8_MHZ;
447 case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; 626 break;
448 case BANDWIDTH_AUTO: return -EOPNOTSUPP; 627 case 7:
449 default: return -EINVAL; 628 Msg.Data[1] = BW_7_MHZ;
629 break;
630 case 6:
631 Msg.Data[1] = BW_6_MHZ;
632 break;
633 case 0:
634 return -EOPNOTSUPP;
635 default:
636 return -EINVAL;
450 } 637 }
451 /* Disable LNA, if any. An error is returned if no LNA is present */ 638 /* Disable LNA, if any. An error is returned if no LNA is present */
452 ret = sms_board_lna_control(client->coredev, 0); 639 ret = sms_board_lna_control(client->coredev, 0);
@@ -470,6 +657,90 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
470 &client->tune_done); 657 &client->tune_done);
471} 658}
472 659
660static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe,
661 struct dvb_frontend_parameters *p)
662{
663 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
664 struct smsdvb_client_t *client =
665 container_of(fe, struct smsdvb_client_t, frontend);
666
667 struct {
668 struct SmsMsgHdr_ST Msg;
669 u32 Data[4];
670 } Msg;
671
672 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
673
674 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
675 Msg.Msg.msgDstId = HIF_TASK;
676 Msg.Msg.msgFlags = 0;
677 Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ;
678 Msg.Msg.msgLength = sizeof(Msg);
679
680 if (c->isdbt_sb_segment_idx == -1)
681 c->isdbt_sb_segment_idx = 0;
682
683 switch (c->isdbt_sb_segment_count) {
684 case 3:
685 Msg.Data[1] = BW_ISDBT_3SEG;
686 break;
687 case 1:
688 Msg.Data[1] = BW_ISDBT_1SEG;
689 break;
690 case 0: /* AUTO */
691 switch (c->bandwidth_hz / 1000000) {
692 case 8:
693 case 7:
694 c->isdbt_sb_segment_count = 3;
695 Msg.Data[1] = BW_ISDBT_3SEG;
696 break;
697 case 6:
698 c->isdbt_sb_segment_count = 1;
699 Msg.Data[1] = BW_ISDBT_1SEG;
700 break;
701 default: /* Assumes 6 MHZ bw */
702 c->isdbt_sb_segment_count = 1;
703 c->bandwidth_hz = 6000;
704 Msg.Data[1] = BW_ISDBT_1SEG;
705 break;
706 }
707 break;
708 default:
709 sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
710 return -EINVAL;
711 }
712
713 Msg.Data[0] = c->frequency;
714 Msg.Data[2] = 12000000;
715 Msg.Data[3] = c->isdbt_sb_segment_idx;
716
717 sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
718 c->frequency, c->isdbt_sb_segment_count,
719 c->isdbt_sb_segment_idx);
720
721 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
722 &client->tune_done);
723}
724
725static int smsdvb_set_frontend(struct dvb_frontend *fe,
726 struct dvb_frontend_parameters *fep)
727{
728 struct smsdvb_client_t *client =
729 container_of(fe, struct smsdvb_client_t, frontend);
730 struct smscore_device_t *coredev = client->coredev;
731
732 switch (smscore_get_device_mode(coredev)) {
733 case DEVICE_MODE_DVBT:
734 case DEVICE_MODE_DVBT_BDA:
735 return smsdvb_dvbt_set_frontend(fe, fep);
736 case DEVICE_MODE_ISDBT:
737 case DEVICE_MODE_ISDBT_BDA:
738 return smsdvb_isdbt_set_frontend(fe, fep);
739 default:
740 return -EINVAL;
741 }
742}
743
473static int smsdvb_get_frontend(struct dvb_frontend *fe, 744static int smsdvb_get_frontend(struct dvb_frontend *fe,
474 struct dvb_frontend_parameters *fep) 745 struct dvb_frontend_parameters *fep)
475{ 746{
@@ -557,13 +828,6 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
557 /* device removal handled by onremove callback */ 828 /* device removal handled by onremove callback */
558 if (!arrival) 829 if (!arrival)
559 return 0; 830 return 0;
560
561 if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) {
562 sms_err("SMS Device mode is not set for "
563 "DVB operation.");
564 return 0;
565 }
566
567 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); 831 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
568 if (!client) { 832 if (!client) {
569 sms_err("kmalloc() failed"); 833 sms_err("kmalloc() failed");
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
index e3d776feeaca..a56eac76e0f0 100644
--- a/drivers/media/dvb/siano/smsir.c
+++ b/drivers/media/dvb/siano/smsir.c
@@ -85,9 +85,9 @@ static struct keyboard_layout_map_t keyboard_layout_maps[] = {
85 { } /* Terminating entry */ 85 { } /* Terminating entry */
86}; 86};
87 87
88u32 ir_pos; 88static u32 ir_pos;
89u32 ir_word; 89static u32 ir_word;
90u32 ir_toggle; 90static u32 ir_toggle;
91 91
92#define RC5_PUSH_BIT(dst, bit, pos) \ 92#define RC5_PUSH_BIT(dst, bit, pos) \
93 { dst <<= 1; dst |= bit; pos++; } 93 { dst <<= 1; dst |= bit; pos++; }
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 23a1c6380d3f..b070e88d8c6b 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -268,8 +268,8 @@ int av7110_check_ir_config(struct av7110 *av7110, int force)
268 268
269 269
270/* /proc/av7110_ir interface */ 270/* /proc/av7110_ir interface */
271static int av7110_ir_write_proc(struct file *file, const char __user *buffer, 271static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer,
272 unsigned long count, void *data) 272 size_t count, loff_t *pos)
273{ 273{
274 char *page; 274 char *page;
275 u32 ir_config; 275 u32 ir_config;
@@ -309,6 +309,10 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
309 return count; 309 return count;
310} 310}
311 311
312static const struct file_operations av7110_ir_proc_fops = {
313 .owner = THIS_MODULE,
314 .write = av7110_ir_proc_write,
315};
312 316
313/* interrupt handler */ 317/* interrupt handler */
314static void ir_handler(struct av7110 *av7110, u32 ircom) 318static void ir_handler(struct av7110 *av7110, u32 ircom)
@@ -368,11 +372,9 @@ int __devinit av7110_ir_init(struct av7110 *av7110)
368 input_dev->timer.data = (unsigned long) &av7110->ir; 372 input_dev->timer.data = (unsigned long) &av7110->ir;
369 373
370 if (av_cnt == 1) { 374 if (av_cnt == 1) {
371 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); 375 e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
372 if (e) { 376 if (e)
373 e->write_proc = av7110_ir_write_proc;
374 e->size = 4 + 256 * sizeof(u16); 377 e->size = 4 + 256 * sizeof(u16);
375 }
376 } 378 }
377 379
378 tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); 380 tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 9782e0593733..49c2a817a06f 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -254,7 +254,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
254 budget_ci->ir.timer_keyup.function = msp430_ir_keyup; 254 budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
255 budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; 255 budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
256 budget_ci->ir.last_raw = 0xffff; /* An impossible value */ 256 budget_ci->ir.last_raw = 0xffff; /* An impossible value */
257 error = ir_input_register(input_dev, ir_codes); 257 error = ir_input_register(input_dev, ir_codes, NULL);
258 if (error) { 258 if (error) {
259 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); 259 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
260 return error; 260 return error;
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index e48380c48990..9fdf26cc6998 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -433,9 +433,8 @@ static struct stv090x_config tt1600_stv090x_config = {
433 .demod_mode = STV090x_SINGLE, 433 .demod_mode = STV090x_SINGLE,
434 .clk_mode = STV090x_CLK_EXT, 434 .clk_mode = STV090x_CLK_EXT,
435 435
436 .xtal = 27000000, 436 .xtal = 13500000,
437 .address = 0x68, 437 .address = 0x68,
438 .ref_clk = 27000000,
439 438
440 .ts1_mode = STV090x_TSMODE_DVBCI, 439 .ts1_mode = STV090x_TSMODE_DVBCI,
441 .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, 440 .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS,
@@ -457,6 +456,7 @@ static struct stv090x_config tt1600_stv090x_config = {
457static struct stv6110x_config tt1600_stv6110x_config = { 456static struct stv6110x_config tt1600_stv6110x_config = {
458 .addr = 0x60, 457 .addr = 0x60,
459 .refclk = 27000000, 458 .refclk = 27000000,
459 .clk_div = 2,
460}; 460};
461 461
462static struct isl6423_config tt1600_isl6423_config = { 462static struct isl6423_config tt1600_isl6423_config = {
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 3f40f375981b..83567b898d09 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -417,6 +417,18 @@ config RADIO_TEA5764_XTAL
417 Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N 417 Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
418 here if TEA5764 reference frequency is connected in FREQIN. 418 here if TEA5764 reference frequency is connected in FREQIN.
419 419
420config RADIO_SAA7706H
421 tristate "SAA7706H Car Radio DSP"
422 depends on I2C && VIDEO_V4L2
423 ---help---
424 Say Y here if you want to use the SAA7706H Car radio Digital
425 Signal Processor, found for instance on the Russellville development
426 board. On the russellville the device is connected to internal
427 timberdale I2C bus.
428
429 To compile this driver as a module, choose M here: the
430 module will be called SAA7706H.
431
420config RADIO_TEF6862 432config RADIO_TEF6862
421 tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" 433 tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
422 depends on I2C && VIDEO_V4L2 434 depends on I2C && VIDEO_V4L2
@@ -429,4 +441,15 @@ config RADIO_TEF6862
429 To compile this driver as a module, choose M here: the 441 To compile this driver as a module, choose M here: the
430 module will be called TEF6862. 442 module will be called TEF6862.
431 443
444config RADIO_TIMBERDALE
445 tristate "Enable the Timberdale radio driver"
446 depends on MFD_TIMBERDALE && VIDEO_V4L2
447 depends on I2C # for RADIO_SAA7706H
448 select RADIO_TEF6862
449 select RADIO_SAA7706H
450 ---help---
451 This is a kind of umbrella driver for the Radio Tuner and DSP
452 found behind the Timberdale FPGA on the Russellville board.
453 Enabling this driver will automatically select the DSP and tuner.
454
432endif # RADIO_ADAPTERS 455endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 01922ada6914..f615583b4837 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -23,6 +23,8 @@ obj-$(CONFIG_USB_DSBR) += dsbr100.o
23obj-$(CONFIG_RADIO_SI470X) += si470x/ 23obj-$(CONFIG_RADIO_SI470X) += si470x/
24obj-$(CONFIG_USB_MR800) += radio-mr800.o 24obj-$(CONFIG_USB_MR800) += radio-mr800.o
25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o 25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
26obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
26obj-$(CONFIG_RADIO_TEF6862) += tef6862.o 27obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
28obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
27 29
28EXTRA_CFLAGS += -Isound 30EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
new file mode 100644
index 000000000000..0de457f6e6eb
--- /dev/null
+++ b/drivers/media/radio/radio-timb.c
@@ -0,0 +1,244 @@
1/*
2 * radio-timb.c Timberdale FPGA Radio driver
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/version.h>
20#include <linux/io.h>
21#include <media/v4l2-ioctl.h>
22#include <media/v4l2-device.h>
23#include <linux/platform_device.h>
24#include <linux/interrupt.h>
25#include <linux/i2c.h>
26#include <media/timb_radio.h>
27
28#define DRIVER_NAME "timb-radio"
29
30struct timbradio {
31 struct timb_radio_platform_data pdata;
32 struct v4l2_subdev *sd_tuner;
33 struct v4l2_subdev *sd_dsp;
34 struct video_device video_dev;
35 struct v4l2_device v4l2_dev;
36};
37
38
39static int timbradio_vidioc_querycap(struct file *file, void *priv,
40 struct v4l2_capability *v)
41{
42 strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
43 strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
44 snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
45 v->version = KERNEL_VERSION(0, 0, 1);
46 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
47 return 0;
48}
49
50static int timbradio_vidioc_g_tuner(struct file *file, void *priv,
51 struct v4l2_tuner *v)
52{
53 struct timbradio *tr = video_drvdata(file);
54 return v4l2_subdev_call(tr->sd_tuner, tuner, g_tuner, v);
55}
56
57static int timbradio_vidioc_s_tuner(struct file *file, void *priv,
58 struct v4l2_tuner *v)
59{
60 struct timbradio *tr = video_drvdata(file);
61 return v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
62}
63
64static int timbradio_vidioc_g_input(struct file *filp, void *priv,
65 unsigned int *i)
66{
67 *i = 0;
68 return 0;
69}
70
71static int timbradio_vidioc_s_input(struct file *filp, void *priv,
72 unsigned int i)
73{
74 return i ? -EINVAL : 0;
75}
76
77static int timbradio_vidioc_g_audio(struct file *file, void *priv,
78 struct v4l2_audio *a)
79{
80 a->index = 0;
81 strlcpy(a->name, "Radio", sizeof(a->name));
82 a->capability = V4L2_AUDCAP_STEREO;
83 return 0;
84}
85
86static int timbradio_vidioc_s_audio(struct file *file, void *priv,
87 struct v4l2_audio *a)
88{
89 return a->index ? -EINVAL : 0;
90}
91
92static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
93 struct v4l2_frequency *f)
94{
95 struct timbradio *tr = video_drvdata(file);
96 return v4l2_subdev_call(tr->sd_tuner, tuner, s_frequency, f);
97}
98
99static int timbradio_vidioc_g_frequency(struct file *file, void *priv,
100 struct v4l2_frequency *f)
101{
102 struct timbradio *tr = video_drvdata(file);
103 return v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
104}
105
106static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
107 struct v4l2_queryctrl *qc)
108{
109 struct timbradio *tr = video_drvdata(file);
110 return v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
111}
112
113static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
114 struct v4l2_control *ctrl)
115{
116 struct timbradio *tr = video_drvdata(file);
117 return v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
118}
119
120static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
121 struct v4l2_control *ctrl)
122{
123 struct timbradio *tr = video_drvdata(file);
124 return v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
125}
126
127static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
128 .vidioc_querycap = timbradio_vidioc_querycap,
129 .vidioc_g_tuner = timbradio_vidioc_g_tuner,
130 .vidioc_s_tuner = timbradio_vidioc_s_tuner,
131 .vidioc_g_frequency = timbradio_vidioc_g_frequency,
132 .vidioc_s_frequency = timbradio_vidioc_s_frequency,
133 .vidioc_g_input = timbradio_vidioc_g_input,
134 .vidioc_s_input = timbradio_vidioc_s_input,
135 .vidioc_g_audio = timbradio_vidioc_g_audio,
136 .vidioc_s_audio = timbradio_vidioc_s_audio,
137 .vidioc_queryctrl = timbradio_vidioc_queryctrl,
138 .vidioc_g_ctrl = timbradio_vidioc_g_ctrl,
139 .vidioc_s_ctrl = timbradio_vidioc_s_ctrl
140};
141
142static const struct v4l2_file_operations timbradio_fops = {
143 .owner = THIS_MODULE,
144 .ioctl = video_ioctl2,
145};
146
147static int __devinit timbradio_probe(struct platform_device *pdev)
148{
149 struct timb_radio_platform_data *pdata = pdev->dev.platform_data;
150 struct timbradio *tr;
151 int err;
152
153 if (!pdata) {
154 dev_err(&pdev->dev, "Platform data missing\n");
155 err = -EINVAL;
156 goto err;
157 }
158
159 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
160 if (!tr) {
161 err = -ENOMEM;
162 goto err;
163 }
164
165 tr->pdata = *pdata;
166
167 strlcpy(tr->video_dev.name, "Timberdale Radio",
168 sizeof(tr->video_dev.name));
169 tr->video_dev.fops = &timbradio_fops;
170 tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
171 tr->video_dev.release = video_device_release_empty;
172 tr->video_dev.minor = -1;
173
174 strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
175 err = v4l2_device_register(NULL, &tr->v4l2_dev);
176 if (err)
177 goto err_v4l2_dev;
178
179 tr->video_dev.v4l2_dev = &tr->v4l2_dev;
180
181 err = video_register_device(&tr->video_dev, VFL_TYPE_RADIO, -1);
182 if (err) {
183 dev_err(&pdev->dev, "Error reg video\n");
184 goto err_video_req;
185 }
186
187 video_set_drvdata(&tr->video_dev, tr);
188
189 platform_set_drvdata(pdev, tr);
190 return 0;
191
192err_video_req:
193 video_device_release_empty(&tr->video_dev);
194 v4l2_device_unregister(&tr->v4l2_dev);
195err_v4l2_dev:
196 kfree(tr);
197err:
198 dev_err(&pdev->dev, "Failed to register: %d\n", err);
199
200 return err;
201}
202
203static int __devexit timbradio_remove(struct platform_device *pdev)
204{
205 struct timbradio *tr = platform_get_drvdata(pdev);
206
207 video_unregister_device(&tr->video_dev);
208 video_device_release_empty(&tr->video_dev);
209
210 v4l2_device_unregister(&tr->v4l2_dev);
211
212 kfree(tr);
213
214 return 0;
215}
216
217static struct platform_driver timbradio_platform_driver = {
218 .driver = {
219 .name = DRIVER_NAME,
220 .owner = THIS_MODULE,
221 },
222 .probe = timbradio_probe,
223 .remove = timbradio_remove,
224};
225
226/*--------------------------------------------------------------------------*/
227
228static int __init timbradio_init(void)
229{
230 return platform_driver_register(&timbradio_platform_driver);
231}
232
233static void __exit timbradio_exit(void)
234{
235 platform_driver_unregister(&timbradio_platform_driver);
236}
237
238module_init(timbradio_init);
239module_exit(timbradio_exit);
240
241MODULE_DESCRIPTION("Timberdale Radio driver");
242MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
243MODULE_LICENSE("GPL v2");
244MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
new file mode 100644
index 000000000000..5db5528a8b25
--- /dev/null
+++ b/drivers/media/radio/saa7706h.c
@@ -0,0 +1,451 @@
1/*
2 * saa7706.c Philips SAA7706H Car Radio DSP driver
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/kernel.h>
24#include <linux/interrupt.h>
25#include <linux/i2c.h>
26#include <media/v4l2-device.h>
27#include <media/v4l2-chip-ident.h>
28
29#define DRIVER_NAME "saa7706h"
30
31/* the I2C memory map looks like this
32
33 $1C00 - $FFFF Not Used
34 $2200 - $3FFF Reserved YRAM (DSP2) space
35 $2000 - $21FF YRAM (DSP2)
36 $1FF0 - $1FFF Hardware Registers
37 $1280 - $1FEF Reserved XRAM (DSP2) space
38 $1000 - $127F XRAM (DSP2)
39 $0FFF DSP CONTROL
40 $0A00 - $0FFE Reserved
41 $0980 - $09FF Reserved YRAM (DSP1) space
42 $0800 - $097F YRAM (DSP1)
43 $0200 - $07FF Not Used
44 $0180 - $01FF Reserved XRAM (DSP1) space
45 $0000 - $017F XRAM (DSP1)
46*/
47
48#define SAA7706H_REG_CTRL 0x0fff
49#define SAA7706H_CTRL_BYP_PLL 0x0001
50#define SAA7706H_CTRL_PLL_DIV_MASK 0x003e
51#define SAA7706H_CTRL_PLL3_62975MHZ 0x003e
52#define SAA7706H_CTRL_DSP_TURBO 0x0040
53#define SAA7706H_CTRL_PC_RESET_DSP1 0x0080
54#define SAA7706H_CTRL_PC_RESET_DSP2 0x0100
55#define SAA7706H_CTRL_DSP1_ROM_EN_MASK 0x0600
56#define SAA7706H_CTRL_DSP1_FUNC_PROM 0x0000
57#define SAA7706H_CTRL_DSP2_ROM_EN_MASK 0x1800
58#define SAA7706H_CTRL_DSP2_FUNC_PROM 0x0000
59#define SAA7706H_CTRL_DIG_SIL_INTERPOL 0x8000
60
61#define SAA7706H_REG_EVALUATION 0x1ff0
62#define SAA7706H_EVAL_DISABLE_CHARGE_PUMP 0x000001
63#define SAA7706H_EVAL_DCS_CLOCK 0x000002
64#define SAA7706H_EVAL_GNDRC1_ENABLE 0x000004
65#define SAA7706H_EVAL_GNDRC2_ENABLE 0x000008
66
67#define SAA7706H_REG_CL_GEN1 0x1ff3
68#define SAA7706H_CL_GEN1_MIN_LOOPGAIN_MASK 0x00000f
69#define SAA7706H_CL_GEN1_LOOPGAIN_MASK 0x0000f0
70#define SAA7706H_CL_GEN1_COARSE_RATION 0xffff00
71
72#define SAA7706H_REG_CL_GEN2 0x1ff4
73#define SAA7706H_CL_GEN2_WSEDGE_FALLING 0x000001
74#define SAA7706H_CL_GEN2_STOP_VCO 0x000002
75#define SAA7706H_CL_GEN2_FRERUN 0x000004
76#define SAA7706H_CL_GEN2_ADAPTIVE 0x000008
77#define SAA7706H_CL_GEN2_FINE_RATIO_MASK 0x0ffff0
78
79#define SAA7706H_REG_CL_GEN4 0x1ff6
80#define SAA7706H_CL_GEN4_BYPASS_PLL1 0x001000
81#define SAA7706H_CL_GEN4_PLL1_DIV_MASK 0x03e000
82#define SAA7706H_CL_GEN4_DSP1_TURBO 0x040000
83
84#define SAA7706H_REG_SEL 0x1ff7
85#define SAA7706H_SEL_DSP2_SRCA_MASK 0x000007
86#define SAA7706H_SEL_DSP2_FMTA_MASK 0x000031
87#define SAA7706H_SEL_DSP2_SRCB_MASK 0x0001c0
88#define SAA7706H_SEL_DSP2_FMTB_MASK 0x000e00
89#define SAA7706H_SEL_DSP1_SRC_MASK 0x003000
90#define SAA7706H_SEL_DSP1_FMT_MASK 0x01c003
91#define SAA7706H_SEL_SPDIF2 0x020000
92#define SAA7706H_SEL_HOST_IO_FMT_MASK 0x1c0000
93#define SAA7706H_SEL_EN_HOST_IO 0x200000
94
95#define SAA7706H_REG_IAC 0x1ff8
96#define SAA7706H_REG_CLK_SET 0x1ff9
97#define SAA7706H_REG_CLK_COEFF 0x1ffa
98#define SAA7706H_REG_INPUT_SENS 0x1ffb
99#define SAA7706H_INPUT_SENS_RDS_VOL_MASK 0x0003f
100#define SAA7706H_INPUT_SENS_FM_VOL_MASK 0x00fc0
101#define SAA7706H_INPUT_SENS_FM_MPX 0x01000
102#define SAA7706H_INPUT_SENS_OFF_FILTER_A_EN 0x02000
103#define SAA7706H_INPUT_SENS_OFF_FILTER_B_EN 0x04000
104#define SAA7706H_REG_PHONE_NAV_AUDIO 0x1ffc
105#define SAA7706H_REG_IO_CONF_DSP2 0x1ffd
106#define SAA7706H_REG_STATUS_DSP2 0x1ffe
107#define SAA7706H_REG_PC_DSP2 0x1fff
108
109#define SAA7706H_DSP1_MOD0 0x0800
110#define SAA7706H_DSP1_ROM_VER 0x097f
111#define SAA7706H_DSP2_MPTR0 0x1000
112
113#define SAA7706H_DSP1_MODPNTR 0x0000
114
115#define SAA7706H_DSP2_XMEM_CONTLLCW 0x113e
116#define SAA7706H_DSP2_XMEM_BUSAMP 0x114a
117#define SAA7706H_DSP2_XMEM_FDACPNTR 0x11f9
118#define SAA7706H_DSP2_XMEM_IIS1PNTR 0x11fb
119
120#define SAA7706H_DSP2_YMEM_PVGA 0x212a
121#define SAA7706H_DSP2_YMEM_PVAT1 0x212b
122#define SAA7706H_DSP2_YMEM_PVAT 0x212c
123#define SAA7706H_DSP2_YMEM_ROM_VER 0x21ff
124
125#define SUPPORTED_DSP1_ROM_VER 0x667
126
127struct saa7706h_state {
128 struct v4l2_subdev sd;
129 unsigned muted;
130};
131
132static inline struct saa7706h_state *to_state(struct v4l2_subdev *sd)
133{
134 return container_of(sd, struct saa7706h_state, sd);
135}
136
137static int saa7706h_i2c_send(struct i2c_client *client, const u8 *data, int len)
138{
139 int err = i2c_master_send(client, data, len);
140 if (err == len)
141 return 0;
142 return err > 0 ? -EIO : err;
143}
144
145static int saa7706h_i2c_transfer(struct i2c_client *client,
146 struct i2c_msg *msgs, int num)
147{
148 int err = i2c_transfer(client->adapter, msgs, num);
149 if (err == num)
150 return 0;
151 return err > 0 ? -EIO : err;
152}
153
154static int saa7706h_set_reg24(struct v4l2_subdev *sd, u16 reg, u32 val)
155{
156 struct i2c_client *client = v4l2_get_subdevdata(sd);
157 u8 buf[5];
158 int pos = 0;
159
160 buf[pos++] = reg >> 8;
161 buf[pos++] = reg;
162 buf[pos++] = val >> 16;
163 buf[pos++] = val >> 8;
164 buf[pos++] = val;
165
166 return saa7706h_i2c_send(client, buf, pos);
167}
168
169static int saa7706h_set_reg24_err(struct v4l2_subdev *sd, u16 reg, u32 val,
170 int *err)
171{
172 return *err ? *err : saa7706h_set_reg24(sd, reg, val);
173}
174
175static int saa7706h_set_reg16(struct v4l2_subdev *sd, u16 reg, u16 val)
176{
177 struct i2c_client *client = v4l2_get_subdevdata(sd);
178 u8 buf[4];
179 int pos = 0;
180
181 buf[pos++] = reg >> 8;
182 buf[pos++] = reg;
183 buf[pos++] = val >> 8;
184 buf[pos++] = val;
185
186 return saa7706h_i2c_send(client, buf, pos);
187}
188
189static int saa7706h_set_reg16_err(struct v4l2_subdev *sd, u16 reg, u16 val,
190 int *err)
191{
192 return *err ? *err : saa7706h_set_reg16(sd, reg, val);
193}
194
195static int saa7706h_get_reg16(struct v4l2_subdev *sd, u16 reg)
196{
197 struct i2c_client *client = v4l2_get_subdevdata(sd);
198 u8 buf[2];
199 int err;
200 u8 regaddr[] = {reg >> 8, reg};
201 struct i2c_msg msg[] = { {client->addr, 0, sizeof(regaddr), regaddr},
202 {client->addr, I2C_M_RD, sizeof(buf), buf} };
203
204 err = saa7706h_i2c_transfer(client, msg, ARRAY_SIZE(msg));
205 if (err)
206 return err;
207
208 return buf[0] << 8 | buf[1];
209}
210
211static int saa7706h_unmute(struct v4l2_subdev *sd)
212{
213 struct saa7706h_state *state = to_state(sd);
214 int err = 0;
215
216 err = saa7706h_set_reg16_err(sd, SAA7706H_REG_CTRL,
217 SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
218 SAA7706H_CTRL_PC_RESET_DSP2, &err);
219
220 /* newer versions of the chip requires a small sleep after reset */
221 msleep(1);
222
223 err = saa7706h_set_reg16_err(sd, SAA7706H_REG_CTRL,
224 SAA7706H_CTRL_PLL3_62975MHZ, &err);
225
226 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_EVALUATION, 0, &err);
227
228 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN1, 0x040022, &err);
229
230 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN2,
231 SAA7706H_CL_GEN2_WSEDGE_FALLING, &err);
232
233 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CL_GEN4, 0x024080, &err);
234
235 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_SEL, 0x200080, &err);
236
237 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_IAC, 0xf4caed, &err);
238
239 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CLK_SET, 0x124334, &err);
240
241 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_CLK_COEFF, 0x004a1a,
242 &err);
243
244 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_INPUT_SENS, 0x0071c7,
245 &err);
246
247 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_PHONE_NAV_AUDIO,
248 0x0e22ff, &err);
249
250 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_IO_CONF_DSP2, 0x001ff8,
251 &err);
252
253 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_STATUS_DSP2, 0x080003,
254 &err);
255
256 err = saa7706h_set_reg24_err(sd, SAA7706H_REG_PC_DSP2, 0x000004, &err);
257
258 err = saa7706h_set_reg16_err(sd, SAA7706H_DSP1_MOD0, 0x0c6c, &err);
259
260 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_MPTR0, 0x000b4b, &err);
261
262 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP1_MODPNTR, 0x000600, &err);
263
264 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP1_MODPNTR, 0x0000c0, &err);
265
266 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000819,
267 &err);
268
269 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x00085a,
270 &err);
271
272 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_BUSAMP, 0x7fffff,
273 &err);
274
275 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_FDACPNTR, 0x2000cb,
276 &err);
277
278 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_IIS1PNTR, 0x2000cb,
279 &err);
280
281 err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVGA, 0x0f80, &err);
282
283 err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVAT1, 0x0800,
284 &err);
285
286 err = saa7706h_set_reg16_err(sd, SAA7706H_DSP2_YMEM_PVAT, 0x0800, &err);
287
288 err = saa7706h_set_reg24_err(sd, SAA7706H_DSP2_XMEM_CONTLLCW, 0x000905,
289 &err);
290 if (!err)
291 state->muted = 0;
292 return err;
293}
294
295static int saa7706h_mute(struct v4l2_subdev *sd)
296{
297 struct saa7706h_state *state = to_state(sd);
298 int err;
299
300 err = saa7706h_set_reg16(sd, SAA7706H_REG_CTRL,
301 SAA7706H_CTRL_PLL3_62975MHZ | SAA7706H_CTRL_PC_RESET_DSP1 |
302 SAA7706H_CTRL_PC_RESET_DSP2);
303 if (!err)
304 state->muted = 1;
305 return err;
306}
307
308static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
309{
310 switch (qc->id) {
311 case V4L2_CID_AUDIO_MUTE:
312 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
313 }
314 return -EINVAL;
315}
316
317static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
318{
319 struct saa7706h_state *state = to_state(sd);
320
321 switch (ctrl->id) {
322 case V4L2_CID_AUDIO_MUTE:
323 ctrl->value = state->muted;
324 return 0;
325 }
326 return -EINVAL;
327}
328
329static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
330{
331 switch (ctrl->id) {
332 case V4L2_CID_AUDIO_MUTE:
333 if (ctrl->value)
334 return saa7706h_mute(sd);
335 return saa7706h_unmute(sd);
336 }
337 return -EINVAL;
338}
339
340static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
341 struct v4l2_dbg_chip_ident *chip)
342{
343 struct i2c_client *client = v4l2_get_subdevdata(sd);
344
345 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
346}
347
348static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
349 .g_chip_ident = saa7706h_g_chip_ident,
350 .queryctrl = saa7706h_queryctrl,
351 .g_ctrl = saa7706h_g_ctrl,
352 .s_ctrl = saa7706h_s_ctrl,
353};
354
355static const struct v4l2_subdev_ops saa7706h_ops = {
356 .core = &saa7706h_core_ops,
357};
358
359/*
360 * Generic i2c probe
361 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
362 */
363
364static int __devinit saa7706h_probe(struct i2c_client *client,
365 const struct i2c_device_id *id)
366{
367 struct saa7706h_state *state;
368 struct v4l2_subdev *sd;
369 int err;
370
371 /* Check if the adapter supports the needed features */
372 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
373 return -EIO;
374
375 v4l_info(client, "chip found @ 0x%02x (%s)\n",
376 client->addr << 1, client->adapter->name);
377
378 state = kmalloc(sizeof(struct saa7706h_state), GFP_KERNEL);
379 if (state == NULL)
380 return -ENOMEM;
381 sd = &state->sd;
382 v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
383
384 /* check the rom versions */
385 err = saa7706h_get_reg16(sd, SAA7706H_DSP1_ROM_VER);
386 if (err < 0)
387 goto err;
388 if (err != SUPPORTED_DSP1_ROM_VER)
389 v4l2_warn(sd, "Unknown DSP1 ROM code version: 0x%x\n", err);
390
391 state->muted = 1;
392
393 /* startup in a muted state */
394 err = saa7706h_mute(sd);
395 if (err)
396 goto err;
397
398 return 0;
399
400err:
401 v4l2_device_unregister_subdev(sd);
402 kfree(to_state(sd));
403
404 printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
405
406 return err;
407}
408
409static int __devexit saa7706h_remove(struct i2c_client *client)
410{
411 struct v4l2_subdev *sd = i2c_get_clientdata(client);
412
413 saa7706h_mute(sd);
414 v4l2_device_unregister_subdev(sd);
415 kfree(to_state(sd));
416 return 0;
417}
418
419static const struct i2c_device_id saa7706h_id[] = {
420 {DRIVER_NAME, 0},
421 {},
422};
423
424MODULE_DEVICE_TABLE(i2c, saa7706h_id);
425
426static struct i2c_driver saa7706h_driver = {
427 .driver = {
428 .owner = THIS_MODULE,
429 .name = DRIVER_NAME,
430 },
431 .probe = saa7706h_probe,
432 .remove = saa7706h_remove,
433 .id_table = saa7706h_id,
434};
435
436static __init int saa7706h_init(void)
437{
438 return i2c_add_driver(&saa7706h_driver);
439}
440
441static __exit void saa7706h_exit(void)
442{
443 i2c_del_driver(&saa7706h_driver);
444}
445
446module_init(saa7706h_init);
447module_exit(saa7706h_exit);
448
449MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver");
450MODULE_AUTHOR("Mocean Laboratories");
451MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 4da0f150c6e2..47075fc71f11 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -724,7 +724,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
724 tuner->audmode = V4L2_TUNER_MODE_MONO; 724 tuner->audmode = V4L2_TUNER_MODE_MONO;
725 725
726 /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ 726 /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
727 /* measured in units of db쨉V in 1 db increments (max at ~75 db쨉V) */ 727 /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */
728 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); 728 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
729 /* the ideal factor is 0xffff/75 = 873,8 */ 729 /* the ideal factor is 0xffff/75 = 873,8 */
730 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); 730 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index a96e1b9dd646..6f60841828da 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -590,8 +590,9 @@ int si470x_fops_release(struct file *file)
590 video_unregister_device(radio->videodev); 590 video_unregister_device(radio->videodev);
591 kfree(radio->int_in_buffer); 591 kfree(radio->int_in_buffer);
592 kfree(radio->buffer); 592 kfree(radio->buffer);
593 mutex_unlock(&radio->disconnect_lock);
593 kfree(radio); 594 kfree(radio);
594 goto unlock; 595 goto done;
595 } 596 }
596 597
597 /* cancel read processes */ 598 /* cancel read processes */
@@ -601,7 +602,6 @@ int si470x_fops_release(struct file *file)
601 retval = si470x_stop(radio); 602 retval = si470x_stop(radio);
602 usb_autopm_put_interface(radio->intf); 603 usb_autopm_put_interface(radio->intf);
603 } 604 }
604unlock:
605 mutex_unlock(&radio->disconnect_lock); 605 mutex_unlock(&radio->disconnect_lock);
606done: 606done:
607 return retval; 607 return retval;
@@ -842,9 +842,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
842 kfree(radio->int_in_buffer); 842 kfree(radio->int_in_buffer);
843 video_unregister_device(radio->videodev); 843 video_unregister_device(radio->videodev);
844 kfree(radio->buffer); 844 kfree(radio->buffer);
845 mutex_unlock(&radio->disconnect_lock);
845 kfree(radio); 846 kfree(radio);
847 } else {
848 mutex_unlock(&radio->disconnect_lock);
846 } 849 }
847 mutex_unlock(&radio->disconnect_lock);
848} 850}
849 851
850 852
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 2f83be766d9f..f8fc8654693d 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -388,6 +388,15 @@ config VIDEO_TVP5150
388 To compile this driver as a module, choose M here: the 388 To compile this driver as a module, choose M here: the
389 module will be called tvp5150. 389 module will be called tvp5150.
390 390
391config VIDEO_TVP7002
392 tristate "Texas Instruments TVP7002 video decoder"
393 depends on VIDEO_V4L2 && I2C
394 ---help---
395 Support for the Texas Instruments TVP7002 video decoder.
396
397 To compile this driver as a module, choose M here: the
398 module will be called tvp7002.
399
391config VIDEO_VPX3220 400config VIDEO_VPX3220
392 tristate "vpx3220a, vpx3216b & vpx3214c video decoders" 401 tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
393 depends on VIDEO_V4L2 && I2C 402 depends on VIDEO_V4L2 && I2C
@@ -548,7 +557,6 @@ config VIDEO_VPSS_SYSTEM
548 depends on ARCH_DAVINCI 557 depends on ARCH_DAVINCI
549 help 558 help
550 Support for vpss system module for video driver 559 Support for vpss system module for video driver
551 default y
552 560
553config VIDEO_VPFE_CAPTURE 561config VIDEO_VPFE_CAPTURE
554 tristate "VPFE Video Capture Driver" 562 tristate "VPFE Video Capture Driver"
@@ -592,6 +600,19 @@ config VIDEO_DM355_CCDC
592 To compile this driver as a module, choose M here: the 600 To compile this driver as a module, choose M here: the
593 module will be called vpfe. 601 module will be called vpfe.
594 602
603config VIDEO_ISIF
604 tristate "ISIF HW module"
605 depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
606 select VIDEO_VPSS_SYSTEM
607 default y
608 help
609 Enables ISIF hw module. This is the hardware module for
610 configuring ISIF in VPFE to capture Raw Bayer RGB data from
611 a image sensor or YUV data from a YUV source.
612
613 To compile this driver as a module, choose M here: the
614 module will be called vpfe.
615
595source "drivers/media/video/bt8xx/Kconfig" 616source "drivers/media/video/bt8xx/Kconfig"
596 617
597config VIDEO_PMS 618config VIDEO_PMS
@@ -638,9 +659,14 @@ config VIDEO_W9966
638 information. 659 information.
639 660
640config VIDEO_CPIA 661config VIDEO_CPIA
641 tristate "CPiA Video For Linux" 662 tristate "CPiA Video For Linux (DEPRECATED)"
642 depends on VIDEO_V4L1 663 depends on VIDEO_V4L1
664 default n
643 ---help--- 665 ---help---
666 This driver is DEPRECATED please use the gspca cpia1 module
667 instead. Note that you need atleast version 0.6.4 of libv4l for
668 the cpia1 gspca module.
669
644 This is the video4linux driver for cameras based on Vision's CPiA 670 This is the video4linux driver for cameras based on Vision's CPiA
645 (Colour Processor Interface ASIC), such as the Creative Labs Video 671 (Colour Processor Interface ASIC), such as the Creative Labs Video
646 Blaster Webcam II. If you have one of these cameras, say Y here 672 Blaster Webcam II. If you have one of these cameras, say Y here
@@ -944,6 +970,8 @@ source "drivers/media/video/hdpvr/Kconfig"
944 970
945source "drivers/media/video/em28xx/Kconfig" 971source "drivers/media/video/em28xx/Kconfig"
946 972
973source "drivers/media/video/tlg2300/Kconfig"
974
947source "drivers/media/video/cx231xx/Kconfig" 975source "drivers/media/video/cx231xx/Kconfig"
948 976
949source "drivers/media/video/usbvision/Kconfig" 977source "drivers/media/video/usbvision/Kconfig"
@@ -955,6 +983,7 @@ source "drivers/media/video/et61x251/Kconfig"
955config VIDEO_OVCAMCHIP 983config VIDEO_OVCAMCHIP
956 tristate "OmniVision Camera Chip support (DEPRECATED)" 984 tristate "OmniVision Camera Chip support (DEPRECATED)"
957 depends on I2C && VIDEO_V4L1 985 depends on I2C && VIDEO_V4L1
986 default n
958 ---help--- 987 ---help---
959 This driver is DEPRECATED please use the gspca ov519 module 988 This driver is DEPRECATED please use the gspca ov519 module
960 instead. Note that for the ov511 / ov518 support of the gspca module 989 instead. Note that for the ov511 / ov518 support of the gspca module
@@ -971,6 +1000,7 @@ config VIDEO_OVCAMCHIP
971config USB_W9968CF 1000config USB_W9968CF
972 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)" 1001 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
973 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP 1002 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
1003 default n
974 ---help--- 1004 ---help---
975 This driver is DEPRECATED please use the gspca ov519 module 1005 This driver is DEPRECATED please use the gspca ov519 module
976 instead. Note that for the w9968cf support of the gspca module 1006 instead. Note that for the w9968cf support of the gspca module
@@ -992,6 +1022,7 @@ config USB_W9968CF
992config USB_OV511 1022config USB_OV511
993 tristate "USB OV511 Camera support (DEPRECATED)" 1023 tristate "USB OV511 Camera support (DEPRECATED)"
994 depends on VIDEO_V4L1 1024 depends on VIDEO_V4L1
1025 default n
995 ---help--- 1026 ---help---
996 This driver is DEPRECATED please use the gspca ov519 module 1027 This driver is DEPRECATED please use the gspca ov519 module
997 instead. Note that for the ov511 / ov518 support of the gspca module 1028 instead. Note that for the ov511 / ov518 support of the gspca module
@@ -1020,6 +1051,7 @@ source "drivers/media/video/sn9c102/Kconfig"
1020config USB_STV680 1051config USB_STV680
1021 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)" 1052 tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
1022 depends on VIDEO_V4L1 1053 depends on VIDEO_V4L1
1054 default n
1023 ---help--- 1055 ---help---
1024 This driver is DEPRECATED please use the gspca stv0680 module 1056 This driver is DEPRECATED please use the gspca stv0680 module
1025 instead. Note that for the gspca stv0680 module you need 1057 instead. Note that for the gspca stv0680 module you need
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 2af68ee84122..b88b6174a331 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
56obj-$(CONFIG_VIDEO_VINO) += indycam.o 56obj-$(CONFIG_VIDEO_VINO) += indycam.o
57obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o 57obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
58obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o 58obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
59obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
59obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o 60obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
60obj-$(CONFIG_VIDEO_CS5345) += cs5345.o 61obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
61obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o 62obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
@@ -99,6 +100,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
99obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 100obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
100obj-$(CONFIG_VIDEO_CX88) += cx88/ 101obj-$(CONFIG_VIDEO_CX88) += cx88/
101obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 102obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
103obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
102obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ 104obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
103obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 105obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
104obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 106obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 5bb0f9e71583..547e1a93c421 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -254,7 +254,7 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
254 v4l2_err(sd, "no notify found!\n"); 254 v4l2_err(sd, "no notify found!\n");
255 255
256 if (std & V4L2_STD_NTSC) { 256 if (std & V4L2_STD_NTSC) {
257 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); 257 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
258 bt819_setbit(decoder, 0x01, 0, 1); 258 bt819_setbit(decoder, 0x01, 0, 1);
259 bt819_setbit(decoder, 0x01, 1, 0); 259 bt819_setbit(decoder, 0x01, 1, 0);
260 bt819_setbit(decoder, 0x01, 5, 0); 260 bt819_setbit(decoder, 0x01, 5, 0);
@@ -263,7 +263,7 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
263 /* bt819_setbit(decoder, 0x1a, 5, 1); */ 263 /* bt819_setbit(decoder, 0x1a, 5, 1); */
264 timing = &timing_data[1]; 264 timing = &timing_data[1];
265 } else if (std & V4L2_STD_PAL) { 265 } else if (std & V4L2_STD_PAL) {
266 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); 266 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
267 bt819_setbit(decoder, 0x01, 0, 1); 267 bt819_setbit(decoder, 0x01, 0, 1);
268 bt819_setbit(decoder, 0x01, 1, 1); 268 bt819_setbit(decoder, 0x01, 1, 1);
269 bt819_setbit(decoder, 0x01, 5, 1); 269 bt819_setbit(decoder, 0x01, 5, 1);
@@ -288,7 +288,7 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
288 bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff); 288 bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
289 bt819_write(decoder, 0x09, timing->hscale & 0xff); 289 bt819_write(decoder, 0x09, timing->hscale & 0xff);
290 decoder->norm = std; 290 decoder->norm = std;
291 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0); 291 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
292 return 0; 292 return 0;
293} 293}
294 294
@@ -306,7 +306,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd,
306 v4l2_err(sd, "no notify found!\n"); 306 v4l2_err(sd, "no notify found!\n");
307 307
308 if (decoder->input != input) { 308 if (decoder->input != input) {
309 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); 309 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
310 decoder->input = input; 310 decoder->input = input;
311 /* select mode */ 311 /* select mode */
312 if (decoder->input == 0) { 312 if (decoder->input == 0) {
@@ -316,7 +316,7 @@ static int bt819_s_routing(struct v4l2_subdev *sd,
316 bt819_setbit(decoder, 0x0b, 6, 1); 316 bt819_setbit(decoder, 0x0b, 6, 1);
317 bt819_setbit(decoder, 0x1a, 1, 0); 317 bt819_setbit(decoder, 0x1a, 1, 0);
318 } 318 }
319 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0); 319 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
320 } 320 }
321 return 0; 321 return 0;
322} 322}
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index ae08b077fd04..cb46e8fa8aaa 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -81,6 +81,7 @@ static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
81static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; 81static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
82static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 }; 82static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };
83static int debug_latency; 83static int debug_latency;
84static int disable_ir;
84 85
85static unsigned int fdsr; 86static unsigned int fdsr;
86 87
@@ -107,6 +108,7 @@ module_param(bttv_gpio, int, 0644);
107module_param(bttv_debug, int, 0644); 108module_param(bttv_debug, int, 0644);
108module_param(irq_debug, int, 0644); 109module_param(irq_debug, int, 0644);
109module_param(debug_latency, int, 0644); 110module_param(debug_latency, int, 0644);
111module_param(disable_ir, int, 0444);
110 112
111module_param(fdsr, int, 0444); 113module_param(fdsr, int, 0444);
112module_param(gbuffers, int, 0444); 114module_param(gbuffers, int, 0444);
@@ -139,6 +141,7 @@ MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
139MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)"); 141MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
140MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)"); 142MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
141MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)"); 143MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
144MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
142MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8"); 145MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
143MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000"); 146MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
144MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default " 147MODULE_PARM_DESC(reset_crop,"reset cropping parameters at open(), default "
@@ -4461,8 +4464,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4461 request_modules(btv); 4464 request_modules(btv);
4462 } 4465 }
4463 4466
4464 init_bttv_i2c_ir(btv); 4467 if (!disable_ir) {
4465 bttv_input_init(btv); 4468 init_bttv_i2c_ir(btv);
4469 bttv_input_init(btv);
4470 }
4466 4471
4467 /* everything is fine */ 4472 /* everything is fine */
4468 bttv_num++; 4473 bttv_num++;
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 277a092e1214..b320dbd635aa 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -247,7 +247,7 @@ int bttv_input_init(struct bttv *btv)
247 struct card_ir *ir; 247 struct card_ir *ir;
248 struct ir_scancode_table *ir_codes = NULL; 248 struct ir_scancode_table *ir_codes = NULL;
249 struct input_dev *input_dev; 249 struct input_dev *input_dev;
250 int ir_type = IR_TYPE_OTHER; 250 u64 ir_type = IR_TYPE_OTHER;
251 int err = -ENOMEM; 251 int err = -ENOMEM;
252 252
253 if (!btv->has_remote) 253 if (!btv->has_remote)
@@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv)
389 bttv_ir_start(btv, ir); 389 bttv_ir_start(btv, ir);
390 390
391 /* all done */ 391 /* all done */
392 err = ir_input_register(btv->remote->dev, ir_codes); 392 err = ir_input_register(btv->remote->dev, ir_codes, NULL);
393 if (err) 393 if (err)
394 goto err_out_stop; 394 goto err_out_stop;
395 395
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 7bb9c1ec7819..cbbf7e80d2cf 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1907,7 +1907,6 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1907 goto out_free; 1907 goto out_free;
1908 1908
1909 mutex_init(&cam->s_mutex); 1909 mutex_init(&cam->s_mutex);
1910 mutex_lock(&cam->s_mutex);
1911 spin_lock_init(&cam->dev_lock); 1910 spin_lock_init(&cam->dev_lock);
1912 cam->state = S_NOTREADY; 1911 cam->state = S_NOTREADY;
1913 cafe_set_config_needed(cam, 1); 1912 cafe_set_config_needed(cam, 1);
@@ -1947,7 +1946,6 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1947 * because the sensor could attach in this call chain, leading to 1946 * because the sensor could attach in this call chain, leading to
1948 * unsightly deadlocks. 1947 * unsightly deadlocks.
1949 */ 1948 */
1950 mutex_unlock(&cam->s_mutex); /* attach can deadlock */
1951 ret = cafe_smbus_setup(cam); 1949 ret = cafe_smbus_setup(cam);
1952 if (ret) 1950 if (ret)
1953 goto out_freeirq; 1951 goto out_freeirq;
@@ -1973,7 +1971,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1973 cam->vdev.v4l2_dev = &cam->v4l2_dev; 1971 cam->vdev.v4l2_dev = &cam->v4l2_dev;
1974 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); 1972 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
1975 if (ret) 1973 if (ret)
1976 goto out_smbus; 1974 goto out_unlock;
1977 video_set_drvdata(&cam->vdev, cam); 1975 video_set_drvdata(&cam->vdev, cam);
1978 1976
1979 /* 1977 /*
@@ -1988,6 +1986,8 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1988 mutex_unlock(&cam->s_mutex); 1986 mutex_unlock(&cam->s_mutex);
1989 return 0; 1987 return 0;
1990 1988
1989out_unlock:
1990 mutex_unlock(&cam->s_mutex);
1991out_smbus: 1991out_smbus:
1992 cafe_smbus_shutdown(cam); 1992 cafe_smbus_shutdown(cam);
1993out_freeirq: 1993out_freeirq:
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 551ddf216a4b..933ae4c8cb9a 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3737,9 +3737,6 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
3737 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE) 3737 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
3738 return -EINVAL; 3738 return -EINVAL;
3739 3739
3740 if (!cam || !cam->ops)
3741 return -ENODEV;
3742
3743 /* make this _really_ smp-safe */ 3740 /* make this _really_ smp-safe */
3744 if (mutex_lock_interruptible(&cam->busy_lock)) 3741 if (mutex_lock_interruptible(&cam->busy_lock))
3745 return -EINTR; 3742 return -EINTR;
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index e8a50a611ebc..baf7e91ee0f5 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -19,3 +19,14 @@ config VIDEO_CX18
19 19
20 To compile this driver as a module, choose M here: the 20 To compile this driver as a module, choose M here: the
21 module will be called cx18. 21 module will be called cx18.
22
23config VIDEO_CX18_ALSA
24 tristate "Conexant 23418 DMA audio support"
25 depends on VIDEO_CX18 && SND && EXPERIMENTAL
26 select SND_PCM
27 ---help---
28 This is a video4linux driver for direct (DMA) audio on
29 Conexant 23418 based TV cards using ALSA.
30
31 To compile this driver as a module, choose M here: the
32 module will be called cx18-alsa.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
index f7bf0edf93f9..2fadd9ded340 100644
--- a/drivers/media/video/cx18/Makefile
+++ b/drivers/media/video/cx18/Makefile
@@ -3,8 +3,10 @@ cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \ 3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \ 4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o cx18-io.o 5 cx18-dvb.o cx18-io.o
6cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
6 7
7obj-$(CONFIG_VIDEO_CX18) += cx18.o 8obj-$(CONFIG_VIDEO_CX18) += cx18.o
9obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
8 10
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
new file mode 100644
index 000000000000..eb41d7ec65b9
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -0,0 +1,293 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
5 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
6 *
7 * Portions of this work were sponsored by ONELAN Limited.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 * 02111-1307 USA
23 */
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/device.h>
29#include <linux/spinlock.h>
30
31#include <media/v4l2-device.h>
32
33#include <sound/core.h>
34#include <sound/initval.h>
35
36#include "cx18-driver.h"
37#include "cx18-version.h"
38#include "cx18-alsa.h"
39#include "cx18-alsa-mixer.h"
40#include "cx18-alsa-pcm.h"
41
42int cx18_alsa_debug;
43
44#define CX18_DEBUG_ALSA_INFO(fmt, arg...) \
45 do { \
46 if (cx18_alsa_debug & 2) \
47 printk(KERN_INFO "%s: " fmt, "cx18-alsa", ## arg); \
48 } while (0);
49
50module_param_named(debug, cx18_alsa_debug, int, 0644);
51MODULE_PARM_DESC(debug,
52 "Debug level (bitmask). Default: 0\n"
53 "\t\t\t 1/0x0001: warning\n"
54 "\t\t\t 2/0x0002: info\n");
55
56MODULE_AUTHOR("Andy Walls");
57MODULE_DESCRIPTION("CX23418 ALSA Interface");
58MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
59MODULE_LICENSE("GPL");
60
61MODULE_VERSION(CX18_VERSION);
62
63static inline
64struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
65{
66 return to_cx18(v4l2_dev)->alsa;
67}
68
69static inline
70struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
71{
72 return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
73}
74
75static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
76{
77 if (cxsc == NULL)
78 return;
79
80 if (cxsc->v4l2_dev != NULL)
81 to_cx18(cxsc->v4l2_dev)->alsa = NULL;
82
83 /* FIXME - take any other stopping actions needed */
84
85 kfree(cxsc);
86}
87
88static void snd_cx18_card_private_free(struct snd_card *sc)
89{
90 if (sc == NULL)
91 return;
92 snd_cx18_card_free(sc->private_data);
93 sc->private_data = NULL;
94 sc->private_free = NULL;
95}
96
97static int snd_cx18_card_create(struct v4l2_device *v4l2_dev,
98 struct snd_card *sc,
99 struct snd_cx18_card **cxsc)
100{
101 *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL);
102 if (*cxsc == NULL)
103 return -ENOMEM;
104
105 (*cxsc)->v4l2_dev = v4l2_dev;
106 (*cxsc)->sc = sc;
107
108 sc->private_data = *cxsc;
109 sc->private_free = snd_cx18_card_private_free;
110
111 return 0;
112}
113
114static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
115{
116 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
117 struct snd_card *sc = cxsc->sc;
118
119 /* sc->driver is used by alsa-lib's configurator: simple, unique */
120 strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
121
122 /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
123 snprintf(sc->shortname, sizeof(sc->shortname), "CX18-%d",
124 cx->instance);
125
126 /* sc->longname is read from /proc/asound/cards */
127 snprintf(sc->longname, sizeof(sc->longname),
128 "CX23418 #%d %s TV/FM Radio/Line-In Capture",
129 cx->instance, cx->card_name);
130
131 return 0;
132}
133
134static int snd_cx18_init(struct v4l2_device *v4l2_dev)
135{
136 struct cx18 *cx = to_cx18(v4l2_dev);
137 struct snd_card *sc = NULL;
138 struct snd_cx18_card *cxsc;
139 int ret;
140
141 /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
142
143 /* (1) Check and increment the device index */
144 /* This is a no-op for us. We'll use the cx->instance */
145
146 /* (2) Create a card instance */
147 ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
148 SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
149 THIS_MODULE, 0, &sc);
150 if (ret) {
151 CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
152 __func__, ret);
153 goto err_exit;
154 }
155
156 /* (3) Create a main component */
157 ret = snd_cx18_card_create(v4l2_dev, sc, &cxsc);
158 if (ret) {
159 CX18_ALSA_ERR("%s: snd_cx18_card_create() failed with err %d\n",
160 __func__, ret);
161 goto err_exit_free;
162 }
163
164 /* (4) Set the driver ID and name strings */
165 snd_cx18_card_set_names(cxsc);
166
167
168 ret = snd_cx18_pcm_create(cxsc);
169 if (ret) {
170 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
171 __func__, ret);
172 goto err_exit_free;
173 }
174 /* FIXME - proc files */
175
176 /* (7) Set the driver data and return 0 */
177 /* We do this out of normal order for PCI drivers to avoid races */
178 cx->alsa = cxsc;
179
180 /* (6) Register the card instance */
181 ret = snd_card_register(sc);
182 if (ret) {
183 cx->alsa = NULL;
184 CX18_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
185 __func__, ret);
186 goto err_exit_free;
187 }
188
189 return 0;
190
191err_exit_free:
192 if (sc != NULL)
193 snd_card_free(sc);
194err_exit:
195 return ret;
196}
197
198int cx18_alsa_load(struct cx18 *cx)
199{
200 struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
201 struct cx18_stream *s;
202
203 if (v4l2_dev == NULL) {
204 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
205 __func__);
206 return 0;
207 }
208
209 cx = to_cx18(v4l2_dev);
210 if (cx == NULL) {
211 printk(KERN_ERR "cx18-alsa cx is NULL\n");
212 return 0;
213 }
214
215 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
216 if (s->video_dev == NULL) {
217 CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
218 "skipping\n", __func__);
219 return 0;
220 }
221
222 if (cx->alsa != NULL) {
223 CX18_ALSA_ERR("%s: struct snd_cx18_card * already exists\n",
224 __func__);
225 return 0;
226 }
227
228 if (snd_cx18_init(v4l2_dev)) {
229 CX18_ALSA_ERR("%s: failed to create struct snd_cx18_card\n",
230 __func__);
231 } else {
232 CX18_DEBUG_ALSA_INFO("%s: created cx18 ALSA interface instance "
233 "\n", __func__);
234 }
235 return 0;
236}
237
238static int __init cx18_alsa_init(void)
239{
240 printk(KERN_INFO "cx18-alsa: module loading...\n");
241 cx18_ext_init = &cx18_alsa_load;
242 return 0;
243}
244
245static void __exit snd_cx18_exit(struct snd_cx18_card *cxsc)
246{
247 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
248
249 /* FIXME - pointer checks & shutdown cxsc */
250
251 snd_card_free(cxsc->sc);
252 cx->alsa = NULL;
253}
254
255static int __exit cx18_alsa_exit_callback(struct device *dev, void *data)
256{
257 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
258 struct snd_cx18_card *cxsc;
259
260 if (v4l2_dev == NULL) {
261 printk(KERN_ERR "cx18-alsa: %s: struct v4l2_device * is NULL\n",
262 __func__);
263 return 0;
264 }
265
266 cxsc = to_snd_cx18_card(v4l2_dev);
267 if (cxsc == NULL) {
268 CX18_ALSA_WARN("%s: struct snd_cx18_card * is NULL\n",
269 __func__);
270 return 0;
271 }
272
273 snd_cx18_exit(cxsc);
274 return 0;
275}
276
277static void __exit cx18_alsa_exit(void)
278{
279 struct device_driver *drv;
280 int ret;
281
282 printk(KERN_INFO "cx18-alsa: module unloading...\n");
283
284 drv = driver_find("cx18", &pci_bus_type);
285 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
286 put_driver(drv);
287
288 cx18_ext_init = NULL;
289 printk(KERN_INFO "cx18-alsa: module unload complete\n");
290}
291
292module_init(cx18_alsa_init);
293module_exit(cx18_alsa_exit);
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c
new file mode 100644
index 000000000000..ef21114309fe
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.c
@@ -0,0 +1,175 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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
20 * 02111-1307 USA
21 */
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/device.h>
26#include <linux/spinlock.h>
27#include <linux/videodev2.h>
28
29#include <media/v4l2-device.h>
30
31#include <sound/core.h>
32#include <sound/control.h>
33#include <sound/tlv.h>
34
35#include "cx18-alsa.h"
36#include "cx18-driver.h"
37
38/*
39 * Note the cx18-av-core volume scale is funny, due to the alignment of the
40 * scale with another chip's range:
41 *
42 * v4l2_control value /512 indicated dB actual dB reg 0x8d4
43 * 0x0000 - 0x01ff 0 -119 -96 228
44 * 0x0200 - 0x02ff 1 -118 -96 228
45 * ...
46 * 0x2c00 - 0x2dff 22 -97 -96 228
47 * 0x2e00 - 0x2fff 23 -96 -96 228
48 * 0x3000 - 0x31ff 24 -95 -95 226
49 * ...
50 * 0xee00 - 0xefff 119 0 0 36
51 * ...
52 * 0xfe00 - 0xffff 127 +8 +8 20
53 */
54static inline int dB_to_cx18_av_vol(int dB)
55{
56 if (dB < -96)
57 dB = -96;
58 else if (dB > 8)
59 dB = 8;
60 return (dB + 119) << 9;
61}
62
63static inline int cx18_av_vol_to_dB(int v)
64{
65 if (v < (23 << 9))
66 v = (23 << 9);
67 else if (v > (127 << 9))
68 v = (127 << 9);
69 return (v >> 9) - 119;
70}
71
72static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_info *uinfo)
74{
75 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
76 uinfo->count = 1;
77 /* We're already translating values, just keep this control in dB */
78 uinfo->value.integer.min = -96;
79 uinfo->value.integer.max = 8;
80 uinfo->value.integer.step = 1;
81 return 0;
82}
83
84static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl,
85 struct snd_ctl_elem_value *uctl)
86{
87 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
88 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
89 struct v4l2_control vctrl;
90 int ret;
91
92 vctrl.id = V4L2_CID_AUDIO_VOLUME;
93 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
94
95 snd_cx18_lock(cxsc);
96 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
97 snd_cx18_unlock(cxsc);
98
99 if (!ret)
100 uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value);
101 return ret;
102}
103
104static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl,
105 struct snd_ctl_elem_value *uctl)
106{
107 struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl);
108 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
109 struct v4l2_control vctrl;
110 int ret;
111
112 vctrl.id = V4L2_CID_AUDIO_VOLUME;
113 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
114
115 snd_cx18_lock(cxsc);
116
117 /* Fetch current state */
118 ret = v4l2_subdev_call(cx->sd_av, core, g_ctrl, &vctrl);
119
120 if (ret ||
121 (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
122
123 /* Set, if needed */
124 vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]);
125 ret = v4l2_subdev_call(cx->sd_av, core, s_ctrl, &vctrl);
126 if (!ret)
127 ret = 1; /* Indicate control was changed w/o error */
128 }
129 snd_cx18_unlock(cxsc);
130
131 return ret;
132}
133
134
135/* This is a bit of overkill, the slider is already in dB internally */
136static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0);
137
138static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = {
139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
140 .name = "Analog TV Capture Volume",
141 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
142 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
143 .info = snd_cx18_mixer_tv_volume_info,
144 .get = snd_cx18_mixer_tv_volume_get,
145 .put = snd_cx18_mixer_tv_volume_put,
146 .tlv.p = snd_cx18_mixer_tv_vol_db_scale
147};
148
149/* FIXME - add mute switch and balance, bass, treble sliders:
150 V4L2_CID_AUDIO_MUTE
151
152 V4L2_CID_AUDIO_BALANCE
153
154 V4L2_CID_AUDIO_BASS
155 V4L2_CID_AUDIO_TREBLE
156*/
157
158/* FIXME - add stereo, lang1, lang2, mono menu */
159/* FIXME - add CS5345 I2S volume for HVR-1600 */
160
161int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc)
162{
163 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
164 struct snd_card *sc = cxsc->sc;
165 int ret;
166
167 strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername));
168
169 ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc));
170 if (ret) {
171 CX18_ALSA_WARN("%s: failed to add %s control, err %d\n",
172 __func__, snd_cx18_mixer_tv_vol.name, ret);
173 }
174 return ret;
175}
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h
new file mode 100644
index 000000000000..2d418db000fe
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-mixer.h
@@ -0,0 +1,23 @@
1/*
2 * ALSA mixer controls for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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
20 * 02111-1307 USA
21 */
22
23int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
new file mode 100644
index 000000000000..2bd312daeb1e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -0,0 +1,354 @@
1/*
2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
6 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 *
8 * Portions of this work were sponsored by ONELAN Limited.
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 * (at your option) 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
23 * 02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/vmalloc.h>
29
30#include <media/v4l2-device.h>
31
32#include <sound/core.h>
33#include <sound/pcm.h>
34
35#include "cx18-driver.h"
36#include "cx18-queue.h"
37#include "cx18-streams.h"
38#include "cx18-fileops.h"
39#include "cx18-alsa.h"
40
41static unsigned int pcm_debug;
42module_param(pcm_debug, int, 0644);
43MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
44
45#define dprintk(fmt, arg...) do { \
46 if (pcm_debug) \
47 printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \
48 __func__, ##arg); \
49 } while (0)
50
51static struct snd_pcm_hardware snd_cx18_hw_capture = {
52 .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
53 SNDRV_PCM_INFO_MMAP |
54 SNDRV_PCM_INFO_INTERLEAVED |
55 SNDRV_PCM_INFO_MMAP_VALID,
56
57 .formats = SNDRV_PCM_FMTBIT_S16_LE,
58
59 .rates = SNDRV_PCM_RATE_48000,
60
61 .rate_min = 48000,
62 .rate_max = 48000,
63 .channels_min = 2,
64 .channels_max = 2,
65 .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
66 .period_bytes_min = 64, /* 12544/2, */
67 .period_bytes_max = 12544,
68 .periods_min = 2,
69 .periods_max = 98, /* 12544, */
70};
71
72void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
73 size_t num_bytes)
74{
75 struct snd_pcm_substream *substream;
76 struct snd_pcm_runtime *runtime;
77 unsigned int oldptr;
78 unsigned int stride;
79 int period_elapsed = 0;
80 int length;
81
82 dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
83 pcm_data, num_bytes);
84
85 substream = cxsc->capture_pcm_substream;
86 if (substream == NULL) {
87 dprintk("substream was NULL\n");
88 return;
89 }
90
91 runtime = substream->runtime;
92 if (runtime == NULL) {
93 dprintk("runtime was NULL\n");
94 return;
95 }
96
97 stride = runtime->frame_bits >> 3;
98 if (stride == 0) {
99 dprintk("stride is zero\n");
100 return;
101 }
102
103 length = num_bytes / stride;
104 if (length == 0) {
105 dprintk("%s: length was zero\n", __func__);
106 return;
107 }
108
109 if (runtime->dma_area == NULL) {
110 dprintk("dma area was NULL - ignoring\n");
111 return;
112 }
113
114 oldptr = cxsc->hwptr_done_capture;
115 if (oldptr + length >= runtime->buffer_size) {
116 unsigned int cnt =
117 runtime->buffer_size - oldptr;
118 memcpy(runtime->dma_area + oldptr * stride, pcm_data,
119 cnt * stride);
120 memcpy(runtime->dma_area, pcm_data + cnt * stride,
121 length * stride - cnt * stride);
122 } else {
123 memcpy(runtime->dma_area + oldptr * stride, pcm_data,
124 length * stride);
125 }
126 snd_pcm_stream_lock(substream);
127
128 cxsc->hwptr_done_capture += length;
129 if (cxsc->hwptr_done_capture >=
130 runtime->buffer_size)
131 cxsc->hwptr_done_capture -=
132 runtime->buffer_size;
133
134 cxsc->capture_transfer_done += length;
135 if (cxsc->capture_transfer_done >=
136 runtime->period_size) {
137 cxsc->capture_transfer_done -=
138 runtime->period_size;
139 period_elapsed = 1;
140 }
141
142 snd_pcm_stream_unlock(substream);
143
144 if (period_elapsed)
145 snd_pcm_period_elapsed(substream);
146}
147
148static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
149{
150 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
151 struct snd_pcm_runtime *runtime = substream->runtime;
152 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
153 struct cx18 *cx = to_cx18(v4l2_dev);
154 struct cx18_stream *s;
155 struct cx18_open_id item;
156 int ret;
157
158 /* Instruct the cx18 to start sending packets */
159 snd_cx18_lock(cxsc);
160 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
161
162 item.cx = cx;
163 item.type = s->type;
164 item.open_id = cx->open_id++;
165
166 /* See if the stream is available */
167 if (cx18_claim_stream(&item, item.type)) {
168 /* No, it's already in use */
169 snd_cx18_unlock(cxsc);
170 return -EBUSY;
171 }
172
173 if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
174 test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
175 /* We're already streaming. No additional action required */
176 snd_cx18_unlock(cxsc);
177 return 0;
178 }
179
180
181 runtime->hw = snd_cx18_hw_capture;
182 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
183 cxsc->capture_pcm_substream = substream;
184 runtime->private_data = cx;
185
186 cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;
187
188 /* Not currently streaming, so start it up */
189 set_bit(CX18_F_S_STREAMING, &s->s_flags);
190 ret = cx18_start_v4l2_encode_stream(s);
191 snd_cx18_unlock(cxsc);
192
193 return 0;
194}
195
196static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
197{
198 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
199 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
200 struct cx18 *cx = to_cx18(v4l2_dev);
201 struct cx18_stream *s;
202 int ret;
203
204 /* Instruct the cx18 to stop sending packets */
205 snd_cx18_lock(cxsc);
206 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
207 ret = cx18_stop_v4l2_encode_stream(s, 0);
208 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
209
210 cx18_release_stream(s);
211
212 cx->pcm_announce_callback = NULL;
213 snd_cx18_unlock(cxsc);
214
215 return 0;
216}
217
218static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
219 unsigned int cmd, void *arg)
220{
221 return snd_pcm_lib_ioctl(substream, cmd, arg);
222}
223
224
225static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
226 size_t size)
227{
228 struct snd_pcm_runtime *runtime = subs->runtime;
229
230 dprintk("Allocating vbuffer\n");
231 if (runtime->dma_area) {
232 if (runtime->dma_bytes > size)
233 return 0;
234
235 vfree(runtime->dma_area);
236 }
237 runtime->dma_area = vmalloc(size);
238 if (!runtime->dma_area)
239 return -ENOMEM;
240
241 runtime->dma_bytes = size;
242
243 return 0;
244}
245
246static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
247 struct snd_pcm_hw_params *params)
248{
249 int ret;
250
251 dprintk("%s called\n", __func__);
252
253 ret = snd_pcm_alloc_vmalloc_buffer(substream,
254 params_buffer_bytes(params));
255 return 0;
256}
257
258static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
259{
260 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
261 unsigned long flags;
262
263 spin_lock_irqsave(&cxsc->slock, flags);
264 if (substream->runtime->dma_area) {
265 dprintk("freeing pcm capture region\n");
266 vfree(substream->runtime->dma_area);
267 substream->runtime->dma_area = NULL;
268 }
269 spin_unlock_irqrestore(&cxsc->slock, flags);
270
271 return 0;
272}
273
274static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
275{
276 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
277
278 cxsc->hwptr_done_capture = 0;
279 cxsc->capture_transfer_done = 0;
280
281 return 0;
282}
283
284static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
285{
286 return 0;
287}
288
289static
290snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
291{
292 unsigned long flags;
293 snd_pcm_uframes_t hwptr_done;
294 struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
295
296 spin_lock_irqsave(&cxsc->slock, flags);
297 hwptr_done = cxsc->hwptr_done_capture;
298 spin_unlock_irqrestore(&cxsc->slock, flags);
299
300 return hwptr_done;
301}
302
303static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
304 unsigned long offset)
305{
306 void *pageptr = subs->runtime->dma_area + offset;
307
308 return vmalloc_to_page(pageptr);
309}
310
311static struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
312 .open = snd_cx18_pcm_capture_open,
313 .close = snd_cx18_pcm_capture_close,
314 .ioctl = snd_cx18_pcm_ioctl,
315 .hw_params = snd_cx18_pcm_hw_params,
316 .hw_free = snd_cx18_pcm_hw_free,
317 .prepare = snd_cx18_pcm_prepare,
318 .trigger = snd_cx18_pcm_trigger,
319 .pointer = snd_cx18_pcm_pointer,
320 .page = snd_pcm_get_vmalloc_page,
321};
322
323int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
324{
325 struct snd_pcm *sp;
326 struct snd_card *sc = cxsc->sc;
327 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
328 struct cx18 *cx = to_cx18(v4l2_dev);
329 int ret;
330
331 ret = snd_pcm_new(sc, "CX23418 PCM",
332 0, /* PCM device 0, the only one for this card */
333 0, /* 0 playback substreams */
334 1, /* 1 capture substream */
335 &sp);
336 if (ret) {
337 CX18_ALSA_ERR("%s: snd_cx18_pcm_create() failed with err %d\n",
338 __func__, ret);
339 goto err_exit;
340 }
341
342 spin_lock_init(&cxsc->slock);
343
344 snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
345 &snd_cx18_pcm_capture_ops);
346 sp->info_flags = 0;
347 sp->private_data = cxsc;
348 strlcpy(sp->name, cx->card_name, sizeof(sp->name));
349
350 return 0;
351
352err_exit:
353 return ret;
354}
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h
new file mode 100644
index 000000000000..325662c647a0
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.h
@@ -0,0 +1,27 @@
1/*
2 * ALSA PCM device for the
3 * ALSA interface to cx18 PCM capture streams
4 *
5 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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
20 * 02111-1307 USA
21 */
22
23int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
24
25/* Used by cx18-mailbox to announce the PCM data to the module */
26void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
27 size_t num_bytes);
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h
new file mode 100644
index 000000000000..88a1cde7540b
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-alsa.h
@@ -0,0 +1,75 @@
1/*
2 * ALSA interface to cx18 PCM capture streams
3 *
4 * Copyright (C) 2009 Andy Walls <awalls@radix.net>
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
19 * 02111-1307 USA
20 */
21
22struct snd_card;
23
24struct snd_cx18_card {
25 struct v4l2_device *v4l2_dev;
26 struct snd_card *sc;
27 unsigned int capture_transfer_done;
28 unsigned int hwptr_done_capture;
29 struct snd_pcm_substream *capture_pcm_substream;
30 spinlock_t slock;
31};
32
33extern int cx18_alsa_debug;
34
35/*
36 * File operations that manipulate the encoder or video or audio subdevices
37 * need to be serialized. Use the same lock we use for v4l2 file ops.
38 */
39static inline void snd_cx18_lock(struct snd_cx18_card *cxsc)
40{
41 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
42 mutex_lock(&cx->serialize_lock);
43}
44
45static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
46{
47 struct cx18 *cx = to_cx18(cxsc->v4l2_dev);
48 mutex_unlock(&cx->serialize_lock);
49}
50
51#define CX18_ALSA_DBGFLG_WARN (1 << 0)
52#define CX18_ALSA_DBGFLG_WARN (1 << 0)
53#define CX18_ALSA_DBGFLG_INFO (1 << 1)
54
55#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
56 do { \
57 if ((x) & cx18_alsa_debug) \
58 printk(KERN_INFO "%s-alsa: " type ": " fmt, \
59 v4l2_dev->name , ## args); \
60 } while (0)
61
62#define CX18_ALSA_DEBUG_WARN(fmt, args...) \
63 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
64
65#define CX18_ALSA_DEBUG_INFO(fmt, args...) \
66 CX18_ALSA_DEBUG(CX18_ALSA_DBGFLG_INFO, "info", fmt , ## args)
67
68#define CX18_ALSA_ERR(fmt, args...) \
69 printk(KERN_ERR "%s-alsa: " fmt, v4l2_dev->name , ## args)
70
71#define CX18_ALSA_WARN(fmt, args...) \
72 printk(KERN_WARNING "%s-alsa: " fmt, v4l2_dev->name , ## args)
73
74#define CX18_ALSA_INFO(fmt, args...) \
75 printk(KERN_INFO "%s-alsa: " fmt, v4l2_dev->name , ## args)
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index f11e47a58286..f808fb6fc1c1 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -393,7 +393,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
393 .gpio_init.direction = 0x7, 393 .gpio_init.direction = 0x7,
394 .gpio_audio_input = { .mask = 0x7, 394 .gpio_audio_input = { .mask = 0x7,
395 .tuner = 0x6, .linein = 0x2, .radio = 0x2 }, 395 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
396 .xceive_pin = 15, 396 .xceive_pin = 1,
397 .pci_list = cx18_pci_leadtek_pvr2100, 397 .pci_list = cx18_pci_leadtek_pvr2100,
398 .i2c = &cx18_i2c_std, 398 .i2c = &cx18_i2c_std,
399}; 399};
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 7f65a47f12e1..c95a86ba33b0 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -47,6 +47,10 @@
47 setting this to 1 you ensure that radio0 is now also radio1. */ 47 setting this to 1 you ensure that radio0 is now also radio1. */
48int cx18_first_minor; 48int cx18_first_minor;
49 49
50/* Callback for registering extensions */
51int (*cx18_ext_init)(struct cx18 *);
52EXPORT_SYMBOL(cx18_ext_init);
53
50/* add your revision and whatnot here */ 54/* add your revision and whatnot here */
51static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 55static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
52 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 56 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -91,7 +95,7 @@ static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
91 95
92static int enc_ts_bufs = -1; 96static int enc_ts_bufs = -1;
93static int enc_mpg_bufs = -1; 97static int enc_mpg_bufs = -1;
94static int enc_idx_bufs = -1; 98static int enc_idx_bufs = CX18_MAX_FW_MDLS_PER_STREAM;
95static int enc_yuv_bufs = -1; 99static int enc_yuv_bufs = -1;
96static int enc_vbi_bufs = -1; 100static int enc_vbi_bufs = -1;
97static int enc_pcm_bufs = -1; 101static int enc_pcm_bufs = -1;
@@ -196,14 +200,17 @@ MODULE_PARM_DESC(enc_mpg_bufs,
196 "Number of encoder MPG buffers\n" 200 "Number of encoder MPG buffers\n"
197 "\t\t\tDefault is computed from other enc_mpg_* parameters"); 201 "\t\t\tDefault is computed from other enc_mpg_* parameters");
198MODULE_PARM_DESC(enc_idx_buffers, 202MODULE_PARM_DESC(enc_idx_buffers,
199 "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n" 203 "(Deprecated) Encoder IDX buffer memory (MB)\n"
200 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS)); 204 "\t\t\tIgnored, except 0 disables IDX buffer allocations\n"
205 "\t\t\tDefault: 1 [Enabled]");
201MODULE_PARM_DESC(enc_idx_bufsize, 206MODULE_PARM_DESC(enc_idx_bufsize,
202 "Size of an encoder IDX buffer (kB)\n" 207 "Size of an encoder IDX buffer (kB)\n"
203 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE)); 208 "\t\t\tAllowed values are multiples of 1.5 kB rounded up\n"
209 "\t\t\t(multiples of size required for 64 index entries)\n"
210 "\t\t\tDefault: 2");
204MODULE_PARM_DESC(enc_idx_bufs, 211MODULE_PARM_DESC(enc_idx_bufs,
205 "Number of encoder IDX buffers\n" 212 "Number of encoder IDX buffers\n"
206 "\t\t\tDefault is computed from other enc_idx_* parameters"); 213 "\t\t\tDefault: " __stringify(CX18_MAX_FW_MDLS_PER_STREAM));
207MODULE_PARM_DESC(enc_yuv_buffers, 214MODULE_PARM_DESC(enc_yuv_buffers,
208 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n" 215 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
209 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 216 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
@@ -231,7 +238,8 @@ MODULE_PARM_DESC(enc_pcm_bufs,
231 "Number of encoder PCM buffers\n" 238 "Number of encoder PCM buffers\n"
232 "\t\t\tDefault is computed from other enc_pcm_* parameters"); 239 "\t\t\tDefault is computed from other enc_pcm_* parameters");
233 240
234MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card"); 241MODULE_PARM_DESC(cx18_first_minor,
242 "Set device node number assigned to first card");
235 243
236MODULE_AUTHOR("Hans Verkuil"); 244MODULE_AUTHOR("Hans Verkuil");
237MODULE_DESCRIPTION("CX23418 driver"); 245MODULE_DESCRIPTION("CX23418 driver");
@@ -240,6 +248,28 @@ MODULE_LICENSE("GPL");
240 248
241MODULE_VERSION(CX18_VERSION); 249MODULE_VERSION(CX18_VERSION);
242 250
251#if defined(CONFIG_MODULES) && defined(MODULE)
252static void request_module_async(struct work_struct *work)
253{
254 struct cx18 *dev = container_of(work, struct cx18, request_module_wk);
255
256 /* Make sure cx18-alsa module is loaded */
257 request_module("cx18-alsa");
258
259 /* Initialize cx18-alsa for this instance of the cx18 device */
260 if (cx18_ext_init != NULL)
261 cx18_ext_init(dev);
262}
263
264static void request_modules(struct cx18 *dev)
265{
266 INIT_WORK(&dev->request_module_wk, request_module_async);
267 schedule_work(&dev->request_module_wk);
268}
269#else
270#define request_modules(dev)
271#endif /* CONFIG_MODULES */
272
243/* Generic utility functions */ 273/* Generic utility functions */
244int cx18_msleep_timeout(unsigned int msecs, int intr) 274int cx18_msleep_timeout(unsigned int msecs, int intr)
245{ 275{
@@ -501,7 +531,12 @@ static void cx18_process_options(struct cx18 *cx)
501 /* 531 /*
502 * YUV is a special case where the stream_buf_size needs to be 532 * YUV is a special case where the stream_buf_size needs to be
503 * an integral multiple of 33.75 kB (storage for 32 screens 533 * an integral multiple of 33.75 kB (storage for 32 screens
504 * lines to maintain alignment in case of lost buffers 534 * lines to maintain alignment in case of lost buffers).
535 *
536 * IDX is a special case where the stream_buf_size should be
537 * an integral multiple of 1.5 kB (storage for 64 index entries
538 * to maintain alignment in case of lost buffers).
539 *
505 */ 540 */
506 if (i == CX18_ENC_STREAM_TYPE_YUV) { 541 if (i == CX18_ENC_STREAM_TYPE_YUV) {
507 cx->stream_buf_size[i] *= 1024; 542 cx->stream_buf_size[i] *= 1024;
@@ -511,15 +546,24 @@ static void cx18_process_options(struct cx18 *cx)
511 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE) 546 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
512 cx->stream_buf_size[i] = 547 cx->stream_buf_size[i] =
513 CX18_UNIT_ENC_YUV_BUFSIZE; 548 CX18_UNIT_ENC_YUV_BUFSIZE;
549 } else if (i == CX18_ENC_STREAM_TYPE_IDX) {
550 cx->stream_buf_size[i] *= 1024;
551 cx->stream_buf_size[i] -=
552 (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE);
553
554 if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE)
555 cx->stream_buf_size[i] =
556 CX18_UNIT_ENC_IDX_BUFSIZE;
514 } 557 }
515 /* 558 /*
516 * YUV is a special case where the stream_buf_size is 559 * YUV and IDX are special cases where the stream_buf_size is
517 * now in bytes. 560 * now in bytes.
518 * VBI is a special case where the stream_buf_size is fixed 561 * VBI is a special case where the stream_buf_size is fixed
519 * and already in bytes 562 * and already in bytes
520 */ 563 */
521 if (i == CX18_ENC_STREAM_TYPE_VBI || 564 if (i == CX18_ENC_STREAM_TYPE_VBI ||
522 i == CX18_ENC_STREAM_TYPE_YUV) { 565 i == CX18_ENC_STREAM_TYPE_YUV ||
566 i == CX18_ENC_STREAM_TYPE_IDX) {
523 if (cx->stream_buffers[i] < 0) { 567 if (cx->stream_buffers[i] < 0) {
524 cx->stream_buffers[i] = 568 cx->stream_buffers[i] =
525 cx->options.megabytes[i] * 1024 * 1024 569 cx->options.megabytes[i] * 1024 * 1024
@@ -1032,6 +1076,10 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1032 } 1076 }
1033 1077
1034 CX18_INFO("Initialized card: %s\n", cx->card_name); 1078 CX18_INFO("Initialized card: %s\n", cx->card_name);
1079
1080 /* Load cx18 submodules (cx18-alsa) */
1081 request_modules(cx);
1082
1035 return 0; 1083 return 0;
1036 1084
1037free_streams: 1085free_streams:
@@ -1220,6 +1268,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
1220 kfree(cx); 1268 kfree(cx);
1221} 1269}
1222 1270
1271
1223/* define a pci_driver for card detection */ 1272/* define a pci_driver for card detection */
1224static struct pci_driver cx18_pci_driver = { 1273static struct pci_driver cx18_pci_driver = {
1225 .name = "cx18", 1274 .name = "cx18",
@@ -1230,7 +1279,8 @@ static struct pci_driver cx18_pci_driver = {
1230 1279
1231static int __init module_start(void) 1280static int __init module_start(void)
1232{ 1281{
1233 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); 1282 printk(KERN_INFO "cx18: Start initialization, version %s\n",
1283 CX18_VERSION);
1234 1284
1235 /* Validate parameters */ 1285 /* Validate parameters */
1236 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { 1286 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index e3f7911a7385..23ad6d548dc5 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -126,10 +126,22 @@
126#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32) 126#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
127#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32) 127#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
128 128
129/* IDX buffer size should be a multiple of the index entry size from the chip */
130struct cx18_enc_idx_entry {
131 __le32 length;
132 __le32 offset_low;
133 __le32 offset_high;
134 __le32 flags;
135 __le32 pts_low;
136 __le32 pts_high;
137} __attribute__ ((packed));
138#define CX18_UNIT_ENC_IDX_BUFSIZE \
139 (sizeof(struct cx18_enc_idx_entry) * V4L2_ENC_IDX_ENTRIES)
140
129/* DMA buffer, default size in kB allocated */ 141/* DMA buffer, default size in kB allocated */
130#define CX18_DEFAULT_ENC_TS_BUFSIZE 32 142#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
131#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 143#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
132#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 144#define CX18_DEFAULT_ENC_IDX_BUFSIZE (CX18_UNIT_ENC_IDX_BUFSIZE * 1 / 1024 + 1)
133#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1) 145#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
134#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 146#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
135 147
@@ -234,16 +246,8 @@
234#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args) 246#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
235#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args) 247#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
236 248
237/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
238#define MPEG_FRAME_TYPE_IFRAME 1
239#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
240#define MPEG_FRAME_TYPE_ALL 7
241
242#define CX18_MAX_PGM_INDEX (400)
243
244extern int cx18_debug; 249extern int cx18_debug;
245 250
246
247struct cx18_options { 251struct cx18_options {
248 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */ 252 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
249 int cardtype; /* force card type on load */ 253 int cardtype; /* force card type on load */
@@ -276,6 +280,18 @@ struct cx18_options {
276#define CX18_SLICED_TYPE_WSS_625 (5) 280#define CX18_SLICED_TYPE_WSS_625 (5)
277#define CX18_SLICED_TYPE_VPS (7) 281#define CX18_SLICED_TYPE_VPS (7)
278 282
283/**
284 * list_entry_is_past_end - check if a previous loop cursor is off list end
285 * @pos: the type * previously used as a loop cursor.
286 * @head: the head for your list.
287 * @member: the name of the list_struct within the struct.
288 *
289 * Check if the entry's list_head is the head of the list, thus it's not a
290 * real entry but was the loop cursor that walked past the end
291 */
292#define list_entry_is_past_end(pos, head, member) \
293 (&pos->member == (head))
294
279struct cx18_buffer { 295struct cx18_buffer {
280 struct list_head list; 296 struct list_head list;
281 dma_addr_t dma_handle; 297 dma_addr_t dma_handle;
@@ -558,6 +574,10 @@ struct cx18 {
558 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */ 574 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
559 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 575 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
560 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 576 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
577 struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
578 void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
579 size_t num_bytes);
580
561 unsigned long i_flags; /* global cx18 flags */ 581 unsigned long i_flags; /* global cx18 flags */
562 atomic_t ana_capturing; /* count number of active analog capture streams */ 582 atomic_t ana_capturing; /* count number of active analog capture streams */
563 atomic_t tot_capturing; /* total count number of active capture streams */ 583 atomic_t tot_capturing; /* total count number of active capture streams */
@@ -575,12 +595,6 @@ struct cx18 {
575 595
576 struct vbi_info vbi; 596 struct vbi_info vbi;
577 597
578 u32 pgm_info_offset;
579 u32 pgm_info_num;
580 u32 pgm_info_write_idx;
581 u32 pgm_info_read_idx;
582 struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX];
583
584 u64 mpg_data_received; 598 u64 mpg_data_received;
585 u64 vbi_data_inserted; 599 u64 vbi_data_inserted;
586 600
@@ -623,6 +637,9 @@ struct cx18 {
623 u32 active_input; 637 u32 active_input;
624 v4l2_std_id std; 638 v4l2_std_id std;
625 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ 639 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
640
641 /* Used for cx18-alsa module loading */
642 struct work_struct request_module_wk;
626}; 643};
627 644
628static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) 645static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
@@ -630,6 +647,9 @@ static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
630 return container_of(v4l2_dev, struct cx18, v4l2_dev); 647 return container_of(v4l2_dev, struct cx18, v4l2_dev);
631} 648}
632 649
650/* cx18 extensions to be loaded */
651extern int (*cx18_ext_init)(struct cx18 *);
652
633/* Globals */ 653/* Globals */
634extern int cx18_first_minor; 654extern int cx18_first_minor;
635 655
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 71ad2d1b4c2c..0ae2c2e1eab5 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -213,10 +213,14 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
213{ 213{
214 struct dvb_demux *demux = feed->demux; 214 struct dvb_demux *demux = feed->demux;
215 struct cx18_stream *stream = (struct cx18_stream *) demux->priv; 215 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
216 struct cx18 *cx = stream->cx; 216 struct cx18 *cx;
217 int ret; 217 int ret;
218 u32 v; 218 u32 v;
219 219
220 if (!stream)
221 return -EINVAL;
222
223 cx = stream->cx;
220 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", 224 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
221 feed->pid, feed->index); 225 feed->pid, feed->index);
222 226
@@ -253,12 +257,10 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
253 if (!demux->dmx.frontend) 257 if (!demux->dmx.frontend)
254 return -EINVAL; 258 return -EINVAL;
255 259
256 if (!stream)
257 return -EINVAL;
258
259 mutex_lock(&stream->dvb.feedlock); 260 mutex_lock(&stream->dvb.feedlock);
260 if (stream->dvb.feeding++ == 0) { 261 if (stream->dvb.feeding++ == 0) {
261 CX18_DEBUG_INFO("Starting Transport DMA\n"); 262 CX18_DEBUG_INFO("Starting Transport DMA\n");
263 mutex_lock(&cx->serialize_lock);
262 set_bit(CX18_F_S_STREAMING, &stream->s_flags); 264 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
263 ret = cx18_start_v4l2_encode_stream(stream); 265 ret = cx18_start_v4l2_encode_stream(stream);
264 if (ret < 0) { 266 if (ret < 0) {
@@ -267,6 +269,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
267 if (stream->dvb.feeding == 0) 269 if (stream->dvb.feeding == 0)
268 clear_bit(CX18_F_S_STREAMING, &stream->s_flags); 270 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
269 } 271 }
272 mutex_unlock(&cx->serialize_lock);
270 } else 273 } else
271 ret = 0; 274 ret = 0;
272 mutex_unlock(&stream->dvb.feedlock); 275 mutex_unlock(&stream->dvb.feedlock);
@@ -279,17 +282,20 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
279{ 282{
280 struct dvb_demux *demux = feed->demux; 283 struct dvb_demux *demux = feed->demux;
281 struct cx18_stream *stream = (struct cx18_stream *)demux->priv; 284 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
282 struct cx18 *cx = stream->cx; 285 struct cx18 *cx;
283 int ret = -EINVAL; 286 int ret = -EINVAL;
284 287
285 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
286 feed->pid, feed->index);
287
288 if (stream) { 288 if (stream) {
289 cx = stream->cx;
290 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
291 feed->pid, feed->index);
292
289 mutex_lock(&stream->dvb.feedlock); 293 mutex_lock(&stream->dvb.feedlock);
290 if (--stream->dvb.feeding == 0) { 294 if (--stream->dvb.feeding == 0) {
291 CX18_DEBUG_INFO("Stopping Transport DMA\n"); 295 CX18_DEBUG_INFO("Stopping Transport DMA\n");
296 mutex_lock(&cx->serialize_lock);
292 ret = cx18_stop_v4l2_encode_stream(stream, 0); 297 ret = cx18_stop_v4l2_encode_stream(stream, 0);
298 mutex_unlock(&cx->serialize_lock);
293 } else 299 } else
294 ret = 0; 300 ret = 0;
295 mutex_unlock(&stream->dvb.feedlock); 301 mutex_unlock(&stream->dvb.feedlock);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index c0885c69fd89..863ce7758239 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -37,15 +37,21 @@
37 37
38/* This function tries to claim the stream for a specific file descriptor. 38/* This function tries to claim the stream for a specific file descriptor.
39 If no one else is using this stream then the stream is claimed and 39 If no one else is using this stream then the stream is claimed and
40 associated VBI streams are also automatically claimed. 40 associated VBI and IDX streams are also automatically claimed.
41 Possible error returns: -EBUSY if someone else has claimed 41 Possible error returns: -EBUSY if someone else has claimed
42 the stream or 0 on success. */ 42 the stream or 0 on success. */
43static int cx18_claim_stream(struct cx18_open_id *id, int type) 43int cx18_claim_stream(struct cx18_open_id *id, int type)
44{ 44{
45 struct cx18 *cx = id->cx; 45 struct cx18 *cx = id->cx;
46 struct cx18_stream *s = &cx->streams[type]; 46 struct cx18_stream *s = &cx->streams[type];
47 struct cx18_stream *s_vbi; 47 struct cx18_stream *s_assoc;
48 int vbi_type; 48
49 /* Nothing should ever try to directly claim the IDX stream */
50 if (type == CX18_ENC_STREAM_TYPE_IDX) {
51 CX18_WARN("MPEG Index stream cannot be claimed "
52 "directly, but something tried.\n");
53 return -EINVAL;
54 }
49 55
50 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) { 56 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
51 /* someone already claimed this stream */ 57 /* someone already claimed this stream */
@@ -67,32 +73,47 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type)
67 } 73 }
68 s->id = id->open_id; 74 s->id = id->open_id;
69 75
70 /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI 76 /*
71 (provided VBI insertion is on and sliced VBI is selected), for all 77 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
72 other streams we're done */ 78 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
73 if (type == CX18_ENC_STREAM_TYPE_MPG && 79 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
74 cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) { 80 * (We don't yet fix up MPEG Index entries for our inserted packets).
75 vbi_type = CX18_ENC_STREAM_TYPE_VBI; 81 *
76 } else { 82 * For all other streams we're done.
83 */
84 if (type != CX18_ENC_STREAM_TYPE_MPG)
77 return 0; 85 return 0;
78 }
79 s_vbi = &cx->streams[vbi_type];
80 86
81 set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags); 87 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
88 if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
89 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
90 else if (!cx18_stream_enabled(s_assoc))
91 return 0;
92
93 set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
82 94
83 /* mark that it is used internally */ 95 /* mark that it is used internally */
84 set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags); 96 set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
85 return 0; 97 return 0;
86} 98}
99EXPORT_SYMBOL(cx18_claim_stream);
87 100
88/* This function releases a previously claimed stream. It will take into 101/* This function releases a previously claimed stream. It will take into
89 account associated VBI streams. */ 102 account associated VBI streams. */
90static void cx18_release_stream(struct cx18_stream *s) 103void cx18_release_stream(struct cx18_stream *s)
91{ 104{
92 struct cx18 *cx = s->cx; 105 struct cx18 *cx = s->cx;
93 struct cx18_stream *s_vbi; 106 struct cx18_stream *s_assoc;
94 107
95 s->id = -1; 108 s->id = -1;
109 if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
110 /*
111 * The IDX stream is only used internally, and can
112 * only be indirectly unclaimed by unclaiming the MPG stream.
113 */
114 return;
115 }
116
96 if (s->type == CX18_ENC_STREAM_TYPE_VBI && 117 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
97 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) { 118 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
98 /* this stream is still in use internally */ 119 /* this stream is still in use internally */
@@ -105,25 +126,36 @@ static void cx18_release_stream(struct cx18_stream *s)
105 126
106 cx18_flush_queues(s); 127 cx18_flush_queues(s);
107 128
108 /* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI, 129 /*
109 for all other streams we're done */ 130 * CX18_ENC_STREAM_TYPE_MPG needs to release the
110 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 131 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
111 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; 132 *
112 else 133 * For all other streams we're done.
134 */
135 if (s->type != CX18_ENC_STREAM_TYPE_MPG)
113 return; 136 return;
114 137
115 /* clear internal use flag */ 138 /* Unclaim the associated MPEG Index stream */
116 if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) { 139 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
117 /* was already cleared */ 140 if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
118 return; 141 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
142 cx18_flush_queues(s_assoc);
119 } 143 }
120 if (s_vbi->id != -1) { 144
121 /* VBI stream still claimed by a file descriptor */ 145 /* Unclaim the associated VBI stream */
122 return; 146 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
147 if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
148 if (s_assoc->id == -1) {
149 /*
150 * The VBI stream is not still claimed by a file
151 * descriptor, so completely unclaim it.
152 */
153 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
154 cx18_flush_queues(s_assoc);
155 }
123 } 156 }
124 clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
125 cx18_flush_queues(s_vbi);
126} 157}
158EXPORT_SYMBOL(cx18_release_stream);
127 159
128static void cx18_dualwatch(struct cx18 *cx) 160static void cx18_dualwatch(struct cx18 *cx)
129{ 161{
@@ -177,9 +209,7 @@ static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
177 *err = 0; 209 *err = 0;
178 while (1) { 210 while (1) {
179 if (s->type == CX18_ENC_STREAM_TYPE_MPG) { 211 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
180 /* Process pending program info updates and pending 212 /* Process pending program updates and VBI data */
181 VBI data */
182
183 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) { 213 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
184 cx->dualwatch_jiffies = jiffies; 214 cx->dualwatch_jiffies = jiffies;
185 cx18_dualwatch(cx); 215 cx18_dualwatch(cx);
@@ -362,18 +392,6 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
362 return len; 392 return len;
363} 393}
364 394
365/**
366 * list_entry_is_past_end - check if a previous loop cursor is off list end
367 * @pos: the type * previously used as a loop cursor.
368 * @head: the head for your list.
369 * @member: the name of the list_struct within the struct.
370 *
371 * Check if the entry's list_head is the head of the list, thus it's not a
372 * real entry but was the loop cursor that walked past the end
373 */
374#define list_entry_is_past_end(pos, head, member) \
375 (&pos->member == (head))
376
377static size_t cx18_copy_mdl_to_user(struct cx18_stream *s, 395static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
378 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount) 396 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
379{ 397{
@@ -498,6 +516,7 @@ int cx18_start_capture(struct cx18_open_id *id)
498 struct cx18 *cx = id->cx; 516 struct cx18 *cx = id->cx;
499 struct cx18_stream *s = &cx->streams[id->type]; 517 struct cx18_stream *s = &cx->streams[id->type];
500 struct cx18_stream *s_vbi; 518 struct cx18_stream *s_vbi;
519 struct cx18_stream *s_idx;
501 520
502 if (s->type == CX18_ENC_STREAM_TYPE_RAD) { 521 if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
503 /* you cannot read from these stream types. */ 522 /* you cannot read from these stream types. */
@@ -516,25 +535,33 @@ int cx18_start_capture(struct cx18_open_id *id)
516 return 0; 535 return 0;
517 } 536 }
518 537
519 /* Start VBI capture if required */ 538 /* Start associated VBI or IDX stream capture if required */
520 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; 539 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
521 if (s->type == CX18_ENC_STREAM_TYPE_MPG && 540 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
522 test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && 541 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
523 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { 542 /*
524 /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed 543 * The VBI and IDX streams should have been claimed
525 automatically when the MPG stream is claimed. 544 * automatically, if for internal use, when the MPG stream was
526 We only need to start the VBI capturing. */ 545 * claimed. We only need to start these streams capturing.
527 if (cx18_start_v4l2_encode_stream(s_vbi)) { 546 */
528 CX18_DEBUG_WARN("VBI capture start failed\n"); 547 if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
529 548 !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
530 /* Failure, clean up and return an error */ 549 if (cx18_start_v4l2_encode_stream(s_idx)) {
531 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); 550 CX18_DEBUG_WARN("IDX capture start failed\n");
532 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 551 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
533 /* also releases the associated VBI stream */ 552 goto start_failed;
534 cx18_release_stream(s); 553 }
535 return -EIO; 554 CX18_DEBUG_INFO("IDX capture started\n");
555 }
556 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
557 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
558 if (cx18_start_v4l2_encode_stream(s_vbi)) {
559 CX18_DEBUG_WARN("VBI capture start failed\n");
560 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
561 goto start_failed;
562 }
563 CX18_DEBUG_INFO("VBI insertion started\n");
536 } 564 }
537 CX18_DEBUG_INFO("VBI insertion started\n");
538 } 565 }
539 566
540 /* Tell the card to start capturing */ 567 /* Tell the card to start capturing */
@@ -547,19 +574,29 @@ int cx18_start_capture(struct cx18_open_id *id)
547 return 0; 574 return 0;
548 } 575 }
549 576
550 /* failure, clean up */ 577start_failed:
551 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name); 578 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
552 579
553 /* Note: the CX18_ENC_STREAM_TYPE_VBI is released 580 /*
554 automatically when the MPG stream is released. 581 * The associated VBI and IDX streams for internal use are released
555 We only need to stop the VBI capturing. */ 582 * automatically when the MPG stream is released. We only need to stop
556 if (s->type == CX18_ENC_STREAM_TYPE_MPG && 583 * the associated stream.
557 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { 584 */
558 cx18_stop_v4l2_encode_stream(s_vbi, 0); 585 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
559 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); 586 /* Stop the IDX stream which is always for internal use */
587 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
588 cx18_stop_v4l2_encode_stream(s_idx, 0);
589 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
590 }
591 /* Stop the VBI stream, if only running for internal use */
592 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
593 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
594 cx18_stop_v4l2_encode_stream(s_vbi, 0);
595 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
596 }
560 } 597 }
561 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 598 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
562 cx18_release_stream(s); 599 cx18_release_stream(s); /* Also releases associated streams */
563 return -EIO; 600 return -EIO;
564} 601}
565 602
@@ -618,6 +655,8 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
618{ 655{
619 struct cx18 *cx = id->cx; 656 struct cx18 *cx = id->cx;
620 struct cx18_stream *s = &cx->streams[id->type]; 657 struct cx18_stream *s = &cx->streams[id->type];
658 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
659 struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
621 660
622 CX18_DEBUG_IOCTL("close() of %s\n", s->name); 661 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
623 662
@@ -625,17 +664,19 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
625 664
626 /* Stop capturing */ 665 /* Stop capturing */
627 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) { 666 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
628 struct cx18_stream *s_vbi =
629 &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
630
631 CX18_DEBUG_INFO("close stopping capture\n"); 667 CX18_DEBUG_INFO("close stopping capture\n");
632 /* Special case: a running VBI capture for VBI insertion 668 if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
633 in the mpeg stream. Need to stop that too. */ 669 /* Stop internal use associated VBI and IDX streams */
634 if (id->type == CX18_ENC_STREAM_TYPE_MPG && 670 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
635 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) && 671 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
636 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { 672 CX18_DEBUG_INFO("close stopping embedded VBI "
637 CX18_DEBUG_INFO("close stopping embedded VBI capture\n"); 673 "capture\n");
638 cx18_stop_v4l2_encode_stream(s_vbi, 0); 674 cx18_stop_v4l2_encode_stream(s_vbi, 0);
675 }
676 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
677 CX18_DEBUG_INFO("close stopping IDX capture\n");
678 cx18_stop_v4l2_encode_stream(s_idx, 0);
679 }
639 } 680 }
640 if (id->type == CX18_ENC_STREAM_TYPE_VBI && 681 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
641 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) 682 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 92e2d5dab936..5c8fcb884f0a 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -34,3 +34,6 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx); 34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx); 35void cx18_unmute(struct cx18 *cx);
36 36
37/* Shared with cx18-alsa module */
38int cx18_claim_stream(struct cx18_open_id *id, int type);
39void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 3e4fc192fdec..b81dd0ea8eb9 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -775,10 +775,143 @@ static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
775 return 0; 775 return 0;
776} 776}
777 777
778static int _cx18_process_idx_data(struct cx18_buffer *buf,
779 struct v4l2_enc_idx *idx)
780{
781 int consumed, remaining;
782 struct v4l2_enc_idx_entry *e_idx;
783 struct cx18_enc_idx_entry *e_buf;
784
785 /* Frame type lookup: 1=I, 2=P, 4=B */
786 const int mapping[8] = {
787 -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
788 -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
789 };
790
791 /*
792 * Assumption here is that a buf holds an integral number of
793 * struct cx18_enc_idx_entry objects and is properly aligned.
794 * This is enforced by the module options on IDX buffer sizes.
795 */
796 remaining = buf->bytesused - buf->readpos;
797 consumed = 0;
798 e_idx = &idx->entry[idx->entries];
799 e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
800
801 while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
802 idx->entries < V4L2_ENC_IDX_ENTRIES) {
803
804 e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
805 | le32_to_cpu(e_buf->offset_low);
806
807 e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
808 | le32_to_cpu(e_buf->pts_low);
809
810 e_idx->length = le32_to_cpu(e_buf->length);
811
812 e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
813
814 e_idx->reserved[0] = 0;
815 e_idx->reserved[1] = 0;
816
817 idx->entries++;
818 e_idx = &idx->entry[idx->entries];
819 e_buf++;
820
821 remaining -= sizeof(struct cx18_enc_idx_entry);
822 consumed += sizeof(struct cx18_enc_idx_entry);
823 }
824
825 /* Swallow any partial entries at the end, if there are any */
826 if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
827 consumed += remaining;
828
829 buf->readpos += consumed;
830 return consumed;
831}
832
833static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
834 struct v4l2_enc_idx *idx)
835{
836 if (s->type != CX18_ENC_STREAM_TYPE_IDX)
837 return -EINVAL;
838
839 if (mdl->curr_buf == NULL)
840 mdl->curr_buf = list_first_entry(&mdl->buf_list,
841 struct cx18_buffer, list);
842
843 if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
844 /*
845 * For some reason we've exhausted the buffers, but the MDL
846 * object still said some data was unread.
847 * Fix that and bail out.
848 */
849 mdl->readpos = mdl->bytesused;
850 return 0;
851 }
852
853 list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
854
855 /* Skip any empty buffers in the MDL */
856 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
857 continue;
858
859 mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
860
861 /* exit when MDL drained or request satisfied */
862 if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
863 mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
864 mdl->readpos >= mdl->bytesused)
865 break;
866 }
867 return 0;
868}
869
778static int cx18_g_enc_index(struct file *file, void *fh, 870static int cx18_g_enc_index(struct file *file, void *fh,
779 struct v4l2_enc_idx *idx) 871 struct v4l2_enc_idx *idx)
780{ 872{
781 return -EINVAL; 873 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
874 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
875 s32 tmp;
876 struct cx18_mdl *mdl;
877
878 if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
879 return -EINVAL;
880
881 /* Compute the best case number of entries we can buffer */
882 tmp = s->buffers -
883 s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
884 if (tmp <= 0)
885 tmp = 1;
886 tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
887
888 /* Fill out the header of the return structure */
889 idx->entries = 0;
890 idx->entries_cap = tmp;
891 memset(idx->reserved, 0, sizeof(idx->reserved));
892
893 /* Pull IDX MDLs and buffers from q_full and populate the entries */
894 do {
895 mdl = cx18_dequeue(s, &s->q_full);
896 if (mdl == NULL) /* No more IDX data right now */
897 break;
898
899 /* Extract the Index entry data from the MDL and buffers */
900 cx18_process_idx_data(s, mdl, idx);
901 if (mdl->readpos < mdl->bytesused) {
902 /* We finished with data remaining, push the MDL back */
903 cx18_push(s, mdl, &s->q_full);
904 break;
905 }
906
907 /* We drained this MDL, schedule it to go to the firmware */
908 cx18_enqueue(s, mdl, &s->q_free);
909
910 } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
911
912 /* Tell the work handler to send free IDX MDLs to the firmware */
913 cx18_stream_load_fw_queue(s);
914 return 0;
782} 915}
783 916
784static int cx18_encoder_cmd(struct file *file, void *fh, 917static int cx18_encoder_cmd(struct file *file, void *fh,
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index f231dd09c720..6dcce297752f 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -29,6 +29,7 @@
29#include "cx18-mailbox.h" 29#include "cx18-mailbox.h"
30#include "cx18-queue.h" 30#include "cx18-queue.h"
31#include "cx18-streams.h" 31#include "cx18-streams.h"
32#include "cx18-alsa-pcm.h" /* FIXME make configurable */
32 33
33static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" }; 34static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" };
34 35
@@ -157,6 +158,34 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
157 } 158 }
158} 159}
159 160
161
162static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
163 struct cx18_mdl *mdl)
164{
165 struct cx18_buffer *buf;
166
167 if (mdl->bytesused == 0)
168 return;
169
170 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
171
172 /* The likely case */
173 if (list_is_singular(&mdl->buf_list)) {
174 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
175 list);
176 if (buf->bytesused)
177 cx->pcm_announce_callback(cx->alsa, buf->buf,
178 buf->bytesused);
179 return;
180 }
181
182 list_for_each_entry(buf, &mdl->buf_list, list) {
183 if (buf->bytesused == 0)
184 break;
185 cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused);
186 }
187}
188
160static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) 189static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
161{ 190{
162 u32 handle, mdl_ack_count, id; 191 u32 handle, mdl_ack_count, id;
@@ -223,11 +252,21 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", 252 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
224 s->name, mdl->bytesused); 253 s->name, mdl->bytesused);
225 254
226 if (s->type != CX18_ENC_STREAM_TYPE_TS) 255 if (s->type == CX18_ENC_STREAM_TYPE_TS) {
227 cx18_enqueue(s, mdl, &s->q_full);
228 else {
229 cx18_mdl_send_to_dvb(s, mdl); 256 cx18_mdl_send_to_dvb(s, mdl);
230 cx18_enqueue(s, mdl, &s->q_free); 257 cx18_enqueue(s, mdl, &s->q_free);
258 } else if (s->type == CX18_ENC_STREAM_TYPE_PCM) {
259 /* Pass the data to cx18-alsa */
260 if (cx->pcm_announce_callback != NULL) {
261 cx18_mdl_send_to_alsa(cx, s, mdl);
262 cx18_enqueue(s, mdl, &s->q_free);
263 } else {
264 cx18_enqueue(s, mdl, &s->q_full);
265 }
266 } else {
267 cx18_enqueue(s, mdl, &s->q_full);
268 if (s->type == CX18_ENC_STREAM_TYPE_IDX)
269 cx18_stream_rotate_idx_mdls(cx);
231 } 270 }
232 } 271 }
233 /* Put as many MDLs as possible back into fw use */ 272 /* Put as many MDLs as possible back into fw use */
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 63304823cef5..aefc8c8cf3c1 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -419,6 +419,9 @@ void cx18_stream_free(struct cx18_stream *s)
419{ 419{
420 struct cx18_mdl *mdl; 420 struct cx18_mdl *mdl;
421 struct cx18_buffer *buf; 421 struct cx18_buffer *buf;
422 struct cx18 *cx = s->cx;
423
424 CX18_DEBUG_INFO("Deallocating buffers for %s stream\n", s->name);
422 425
423 /* move all buffers to buf_pool and all MDLs to q_idle */ 426 /* move all buffers to buf_pool and all MDLs to q_idle */
424 cx18_unload_queues(s); 427 cx18_unload_queues(s);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 987a9308d938..054450f65a60 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -319,11 +319,27 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
319 319
320 /* Teardown all streams */ 320 /* Teardown all streams */
321 for (type = 0; type < CX18_MAX_STREAMS; type++) { 321 for (type = 0; type < CX18_MAX_STREAMS; type++) {
322 if (cx->streams[type].dvb.enabled) { 322
323 cx18_dvb_unregister(&cx->streams[type]); 323 /* No struct video_device, but can have buffers allocated */
324 cx->streams[type].dvb.enabled = false; 324 if (type == CX18_ENC_STREAM_TYPE_TS) {
325 if (cx->streams[type].dvb.enabled) {
326 cx18_dvb_unregister(&cx->streams[type]);
327 cx->streams[type].dvb.enabled = false;
328 cx18_stream_free(&cx->streams[type]);
329 }
330 continue;
331 }
332
333 /* No struct video_device, but can have buffers allocated */
334 if (type == CX18_ENC_STREAM_TYPE_IDX) {
335 if (cx->stream_buffers[type] != 0) {
336 cx->stream_buffers[type] = 0;
337 cx18_stream_free(&cx->streams[type]);
338 }
339 continue;
325 } 340 }
326 341
342 /* If struct video_device exists, can have buffers allocated */
327 vdev = cx->streams[type].video_dev; 343 vdev = cx->streams[type].video_dev;
328 344
329 cx->streams[type].video_dev = NULL; 345 cx->streams[type].video_dev = NULL;
@@ -447,6 +463,32 @@ static void cx18_vbi_setup(struct cx18_stream *s)
447 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 463 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
448} 464}
449 465
466void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
467{
468 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
469 struct cx18_mdl *mdl;
470
471 if (!cx18_stream_enabled(s))
472 return;
473
474 /* Return if the firmware is not running low on MDLs */
475 if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
476 CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
477 return;
478
479 /* Return if there are no MDLs to rotate back to the firmware */
480 if (atomic_read(&s->q_full.depth) < 2)
481 return;
482
483 /*
484 * Take the oldest IDX MDL still holding data, and discard its index
485 * entries by scheduling the MDL to go back to the firmware
486 */
487 mdl = cx18_dequeue(s, &s->q_full);
488 if (mdl != NULL)
489 cx18_enqueue(s, mdl, &s->q_free);
490}
491
450static 492static
451struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s, 493struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
452 struct cx18_mdl *mdl) 494 struct cx18_mdl *mdl)
@@ -546,8 +588,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
546 struct cx18 *cx = s->cx; 588 struct cx18 *cx = s->cx;
547 int captype = 0; 589 int captype = 0;
548 struct cx18_api_func_private priv; 590 struct cx18_api_func_private priv;
591 struct cx18_stream *s_idx;
549 592
550 if (s->video_dev == NULL && s->dvb.enabled == 0) 593 if (!cx18_stream_enabled(s))
551 return -EINVAL; 594 return -EINVAL;
552 595
553 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); 596 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -561,6 +604,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
561 cx->search_pack_header = 0; 604 cx->search_pack_header = 0;
562 break; 605 break;
563 606
607 case CX18_ENC_STREAM_TYPE_IDX:
608 captype = CAPTURE_CHANNEL_TYPE_INDEX;
609 break;
564 case CX18_ENC_STREAM_TYPE_TS: 610 case CX18_ENC_STREAM_TYPE_TS:
565 captype = CAPTURE_CHANNEL_TYPE_TS; 611 captype = CAPTURE_CHANNEL_TYPE_TS;
566 break; 612 break;
@@ -635,11 +681,13 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
635 cx18_vbi_setup(s); 681 cx18_vbi_setup(s);
636 682
637 /* 683 /*
638 * assign program index info. 684 * Select to receive I, P, and B frame index entries, if the
639 * Mask 7: select I/P/B, Num_req: 400 max 685 * index stream is enabled. Otherwise disable index entry
640 * FIXME - currently we have this hardcoded as disabled 686 * generation.
641 */ 687 */
642 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); 688 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
689 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
690 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
643 691
644 /* Call out to the common CX2341x API setup for user controls */ 692 /* Call out to the common CX2341x API setup for user controls */
645 priv.cx = cx; 693 priv.cx = cx;
@@ -697,6 +745,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
697 atomic_inc(&cx->tot_capturing); 745 atomic_inc(&cx->tot_capturing);
698 return 0; 746 return 0;
699} 747}
748EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
700 749
701void cx18_stop_all_captures(struct cx18 *cx) 750void cx18_stop_all_captures(struct cx18 *cx)
702{ 751{
@@ -705,7 +754,7 @@ void cx18_stop_all_captures(struct cx18 *cx)
705 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { 754 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
706 struct cx18_stream *s = &cx->streams[i]; 755 struct cx18_stream *s = &cx->streams[i];
707 756
708 if (s->video_dev == NULL && s->dvb.enabled == 0) 757 if (!cx18_stream_enabled(s))
709 continue; 758 continue;
710 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) 759 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
711 cx18_stop_v4l2_encode_stream(s, 0); 760 cx18_stop_v4l2_encode_stream(s, 0);
@@ -717,7 +766,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
717 struct cx18 *cx = s->cx; 766 struct cx18 *cx = s->cx;
718 unsigned long then; 767 unsigned long then;
719 768
720 if (s->video_dev == NULL && s->dvb.enabled == 0) 769 if (!cx18_stream_enabled(s))
721 return -EINVAL; 770 return -EINVAL;
722 771
723 /* This function assumes that you are allowed to stop the capture 772 /* This function assumes that you are allowed to stop the capture
@@ -762,6 +811,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
762 811
763 return 0; 812 return 0;
764} 813}
814EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
765 815
766u32 cx18_find_handle(struct cx18 *cx) 816u32 cx18_find_handle(struct cx18 *cx)
767{ 817{
@@ -789,7 +839,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
789 s = &cx->streams[i]; 839 s = &cx->streams[i];
790 if (s->handle != handle) 840 if (s->handle != handle)
791 continue; 841 continue;
792 if (s->video_dev || s->dvb.enabled) 842 if (cx18_stream_enabled(s))
793 return s; 843 return s;
794 } 844 }
795 return NULL; 845 return NULL;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 4a01db5e5a35..0bff0fa29763 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,6 +28,16 @@ int cx18_streams_setup(struct cx18 *cx);
28int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30 30
31#define CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN (3)
32void cx18_stream_rotate_idx_mdls(struct cx18 *cx);
33
34static inline bool cx18_stream_enabled(struct cx18_stream *s)
35{
36 return s->video_dev || s->dvb.enabled ||
37 (s->type == CX18_ENC_STREAM_TYPE_IDX &&
38 s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
39}
40
31/* Related to submission of mdls to firmware */ 41/* Related to submission of mdls to firmware */
32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) 42static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
33{ 43{
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 9c0b5bb1b019..3e1aec4bcfde 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
24 24
25#define CX18_DRIVER_NAME "cx18" 25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1 26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 3 27#define CX18_DRIVER_VERSION_MINOR 4
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0 28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29 29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) 30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 868806effdcf..2c00980acfcb 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -191,7 +191,8 @@
191#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E) 191#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
192 192
193/* Description: This command set the picture type mask for index file 193/* Description: This command set the picture type mask for index file
194 IN[0] - 0 = disable index file output 194 IN[0] - Task handle (ignored by firmware)
195 IN[1] - 0 = disable index file output
195 1 = output I picture 196 1 = output I picture
196 2 = P picture 197 2 = P picture
197 4 = B picture 198 4 = B picture
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index c5082a4e8ced..64e025e2bdf1 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -464,9 +464,9 @@ static int dvb_init(struct cx231xx *dev)
464 /* define general-purpose callback pointer */ 464 /* define general-purpose callback pointer */
465 dvb->frontend->callback = cx231xx_tuner_callback; 465 dvb->frontend->callback = cx231xx_tuner_callback;
466 466
467 if (dvb_attach(xc5000_attach, dev->dvb->frontend, 467 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
468 &dev->i2c_bus[1].i2c_adap, 468 &dev->i2c_bus[1].i2c_adap,
469 &cnxt_rde250_tunerconfig) < 0) { 469 &cnxt_rde250_tunerconfig)) {
470 result = -EINVAL; 470 result = -EINVAL;
471 goto out_free; 471 goto out_free;
472 } 472 }
@@ -486,9 +486,9 @@ static int dvb_init(struct cx231xx *dev)
486 /* define general-purpose callback pointer */ 486 /* define general-purpose callback pointer */
487 dvb->frontend->callback = cx231xx_tuner_callback; 487 dvb->frontend->callback = cx231xx_tuner_callback;
488 488
489 if (dvb_attach(xc5000_attach, dev->dvb->frontend, 489 if (!dvb_attach(xc5000_attach, dev->dvb->frontend,
490 &dev->i2c_bus[1].i2c_adap, 490 &dev->i2c_bus[1].i2c_adap,
491 &cnxt_rde250_tunerconfig) < 0) { 491 &cnxt_rde250_tunerconfig)) {
492 result = -EINVAL; 492 result = -EINVAL;
493 goto out_free; 493 goto out_free;
494 } 494 }
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 15826f98b688..c5771db3bfce 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -216,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
216 cx231xx_ir_start(ir); 216 cx231xx_ir_start(ir);
217 217
218 /* all done */ 218 /* all done */
219 err = ir_input_register(ir->input, dev->board.ir_codes); 219 err = ir_input_register(ir->input, dev->board.ir_codes, NULL);
220 if (err) 220 if (err)
221 goto err_out_stop; 221 goto err_out_stop;
222 222
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 88c0d2481118..2ab97ad7b6fb 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -681,7 +681,7 @@ static char *cmd_to_str(int cmd)
681 case CX2341X_ENC_SET_VIDEO_ID: 681 case CX2341X_ENC_SET_VIDEO_ID:
682 return "SET_VIDEO_ID"; 682 return "SET_VIDEO_ID";
683 case CX2341X_ENC_SET_PCR_ID: 683 case CX2341X_ENC_SET_PCR_ID:
684 return "SET_PCR_PID"; 684 return "SET_PCR_ID";
685 case CX2341X_ENC_SET_FRAME_RATE: 685 case CX2341X_ENC_SET_FRAME_RATE:
686 return "SET_FRAME_RATE"; 686 return "SET_FRAME_RATE";
687 case CX2341X_ENC_SET_FRAME_SIZE: 687 case CX2341X_ENC_SET_FRAME_SIZE:
@@ -693,7 +693,7 @@ static char *cmd_to_str(int cmd)
693 case CX2341X_ENC_SET_ASPECT_RATIO: 693 case CX2341X_ENC_SET_ASPECT_RATIO:
694 return "SET_ASPECT_RATIO"; 694 return "SET_ASPECT_RATIO";
695 case CX2341X_ENC_SET_DNR_FILTER_MODE: 695 case CX2341X_ENC_SET_DNR_FILTER_MODE:
696 return "SET_DNR_FILTER_PROPS"; 696 return "SET_DNR_FILTER_MODE";
697 case CX2341X_ENC_SET_DNR_FILTER_PROPS: 697 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
698 return "SET_DNR_FILTER_PROPS"; 698 return "SET_DNR_FILTER_PROPS";
699 case CX2341X_ENC_SET_CORING_LEVELS: 699 case CX2341X_ENC_SET_CORING_LEVELS:
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 1ec48169277d..d639186f645d 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -274,6 +274,31 @@ struct cx23885_board cx23885_boards[] = {
274 .portb = CX23885_MPEG_DVB, 274 .portb = CX23885_MPEG_DVB,
275 .portc = CX23885_MPEG_DVB, 275 .portc = CX23885_MPEG_DVB,
276 }, 276 },
277 [CX23885_BOARD_LEADTEK_WINFAST_PXTV1200] = {
278 .name = "LEADTEK WinFast PxTV1200",
279 .porta = CX23885_ANALOG_VIDEO,
280 .tuner_type = TUNER_XC2028,
281 .tuner_addr = 0x61,
282 .input = {{
283 .type = CX23885_VMUX_TELEVISION,
284 .vmux = CX25840_VIN2_CH1 |
285 CX25840_VIN5_CH2 |
286 CX25840_NONE0_CH3,
287 }, {
288 .type = CX23885_VMUX_COMPOSITE1,
289 .vmux = CX25840_COMPOSITE1,
290 }, {
291 .type = CX23885_VMUX_SVIDEO,
292 .vmux = CX25840_SVIDEO_LUMA3 |
293 CX25840_SVIDEO_CHROMA4,
294 }, {
295 .type = CX23885_VMUX_COMPONENT,
296 .vmux = CX25840_VIN7_CH1 |
297 CX25840_VIN6_CH2 |
298 CX25840_VIN8_CH3 |
299 CX25840_COMPONENT_ON,
300 } },
301 },
277}; 302};
278const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 303const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
279 304
@@ -417,6 +442,10 @@ struct cx23885_subid cx23885_subids[] = {
417 .subvendor = 0x14f1, 442 .subvendor = 0x14f1,
418 .subdevice = 0x8578, 443 .subdevice = 0x8578,
419 .card = CX23885_BOARD_MYGICA_X8558PRO, 444 .card = CX23885_BOARD_MYGICA_X8558PRO,
445 }, {
446 .subvendor = 0x107d,
447 .subdevice = 0x6f22,
448 .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200,
420 }, 449 },
421}; 450};
422const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 451const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -617,6 +646,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
617 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 646 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
618 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 647 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
619 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 648 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
649 case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
620 /* Tuner Reset Command */ 650 /* Tuner Reset Command */
621 bitmask = 0x04; 651 bitmask = 0x04;
622 break; 652 break;
@@ -769,6 +799,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
769 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 799 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
770 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 800 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
771 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 801 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
802 case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
772 /* GPIO-2 xc3028 tuner reset */ 803 /* GPIO-2 xc3028 tuner reset */
773 804
774 /* The following GPIO's are on the internal AVCore (cx25840) */ 805 /* The following GPIO's are on the internal AVCore (cx25840) */
@@ -1076,6 +1107,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1076 case CX23885_BOARD_MYGICA_X8506: 1107 case CX23885_BOARD_MYGICA_X8506:
1077 case CX23885_BOARD_MAGICPRO_PROHDTVE2: 1108 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
1078 case CX23885_BOARD_HAUPPAUGE_HVR1290: 1109 case CX23885_BOARD_HAUPPAUGE_HVR1290:
1110 case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
1079 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1111 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1080 &dev->i2c_bus[2].i2c_adap, 1112 &dev->i2c_bus[2].i2c_adap,
1081 "cx25840", "cx25840", 0x88 >> 1, NULL); 1113 "cx25840", "cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index e45d2df08138..939079d7bbb9 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -542,6 +542,9 @@ static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = {
542 .osc_clk_freq = 30400, /* in kHz */ 542 .osc_clk_freq = 30400, /* in kHz */
543 .if_freq = 0, /* zero IF */ 543 .if_freq = 0, /* zero IF */
544 .zif_swap_iq = 1, 544 .zif_swap_iq = 1,
545 .agc_min = 0x2E,
546 .agc_max = 0xFF,
547 .agc_hold_loop = 0,
545}; 548};
546 549
547static struct max2165_config mygic_x8558pro_max2165_cfg1 = { 550static struct max2165_config mygic_x8558pro_max2165_cfg1 = {
@@ -558,6 +561,9 @@ static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = {
558 .osc_clk_freq = 30400, /* in kHz */ 561 .osc_clk_freq = 30400, /* in kHz */
559 .if_freq = 0, /* zero IF */ 562 .if_freq = 0, /* zero IF */
560 .zif_swap_iq = 1, 563 .zif_swap_iq = 1,
564 .agc_min = 0x2E,
565 .agc_max = 0xFF,
566 .agc_hold_loop = 0,
561}; 567};
562 568
563static struct max2165_config mygic_x8558pro_max2165_cfg2 = { 569static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
@@ -994,15 +1000,8 @@ static int dvb_register(struct cx23885_tsport *port)
994 netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); 1000 netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
995 memcpy(port->frontends.adapter.proposed_mac, 1001 memcpy(port->frontends.adapter.proposed_mac,
996 cinfo.port[port->nr - 1].mac, 6); 1002 cinfo.port[port->nr - 1].mac, 6);
997 printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=" 1003 printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n",
998 "%02X:%02X:%02X:%02X:%02X:%02X\n", 1004 port->nr, port->frontends.adapter.proposed_mac);
999 port->nr,
1000 port->frontends.adapter.proposed_mac[0],
1001 port->frontends.adapter.proposed_mac[1],
1002 port->frontends.adapter.proposed_mac[2],
1003 port->frontends.adapter.proposed_mac[3],
1004 port->frontends.adapter.proposed_mac[4],
1005 port->frontends.adapter.proposed_mac[5]);
1006 1005
1007 netup_ci_init(port); 1006 netup_ci_init(port);
1008 break; 1007 break;
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 768eec92ccf9..9c6620f86dca 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -397,7 +397,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
397 dev->ir_input = ir; 397 dev->ir_input = ir;
398 cx23885_input_ir_start(dev); 398 cx23885_input_ir_start(dev);
399 399
400 ret = ir_input_register(ir->dev, ir_codes); 400 ret = ir_input_register(ir->dev, ir_codes, NULL);
401 if (ret) 401 if (ret)
402 goto err_out_stop; 402 goto err_out_stop;
403 403
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 8934d61cf660..2d3ac8b83dc3 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -36,6 +36,7 @@
36#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include "cx23885-ioctl.h" 38#include "cx23885-ioctl.h"
39#include "tuner-xc2028.h"
39 40
40MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); 41MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
41MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); 42MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -1505,6 +1506,18 @@ int cx23885_video_register(struct cx23885_dev *dev)
1505 tun_setup.tuner_callback = cx23885_tuner_callback; 1506 tun_setup.tuner_callback = cx23885_tuner_callback;
1506 1507
1507 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); 1508 v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
1509
1510 if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) {
1511 struct xc2028_ctrl ctrl = {
1512 .fname = XC2028_DEFAULT_FIRMWARE,
1513 .max_len = 64
1514 };
1515 struct v4l2_priv_tun_config cfg = {
1516 .tuner = dev->tuner_type,
1517 .priv = &ctrl
1518 };
1519 v4l2_subdev_call(sd, tuner, s_config, &cfg);
1520 }
1508 } 1521 }
1509 } 1522 }
1510 1523
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 08b3f6b136a0..0e3a98d243c5 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -81,6 +81,7 @@
81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
82#define CX23885_BOARD_HAUPPAUGE_HVR1290 26 82#define CX23885_BOARD_HAUPPAUGE_HVR1290 26
83#define CX23885_BOARD_MYGICA_X8558PRO 27 83#define CX23885_BOARD_MYGICA_X8558PRO 27
84#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
84 85
85#define GPIO_0 0x00000001 86#define GPIO_0 0x00000001
86#define GPIO_1 0x00000002 87#define GPIO_1 0x00000002
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 385ecd58f1c0..f2461cd3de5a 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -734,10 +734,8 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
734 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n", 734 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
735 vid_input); 735 vid_input);
736 reg = vid_input & 0xff; 736 reg = vid_input & 0xff;
737 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) 737 is_composite = !is_component &&
738 is_composite = 0; 738 ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON);
739 else if ((vid_input & CX25840_COMPONENT_ON) == 0)
740 is_composite = 1;
741 739
742 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", 740 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
743 reg, is_composite); 741 reg, is_composite);
@@ -1347,30 +1345,59 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
1347} 1345}
1348#endif 1346#endif
1349 1347
1348static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)
1349{
1350 struct cx25840_state *state = to_state(sd);
1351 struct i2c_client *client = v4l2_get_subdevdata(sd);
1352 u8 v;
1353
1354 if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))
1355 return 0;
1356
1357 v4l_dbg(1, cx25840_debug, client, "%s audio output\n",
1358 enable ? "enable" : "disable");
1359
1360 if (enable) {
1361 v = cx25840_read(client, 0x115) | 0x80;
1362 cx25840_write(client, 0x115, v);
1363 v = cx25840_read(client, 0x116) | 0x03;
1364 cx25840_write(client, 0x116, v);
1365 } else {
1366 v = cx25840_read(client, 0x115) & ~(0x80);
1367 cx25840_write(client, 0x115, v);
1368 v = cx25840_read(client, 0x116) & ~(0x03);
1369 cx25840_write(client, 0x116, v);
1370 }
1371 return 0;
1372}
1373
1350static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) 1374static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1351{ 1375{
1352 struct cx25840_state *state = to_state(sd); 1376 struct cx25840_state *state = to_state(sd);
1353 struct i2c_client *client = v4l2_get_subdevdata(sd); 1377 struct i2c_client *client = v4l2_get_subdevdata(sd);
1378 u8 v;
1354 1379
1355 v4l_dbg(1, cx25840_debug, client, "%s output\n", 1380 v4l_dbg(1, cx25840_debug, client, "%s video output\n",
1356 enable ? "enable" : "disable"); 1381 enable ? "enable" : "disable");
1357 if (enable) { 1382 if (enable) {
1358 if (is_cx2388x(state) || is_cx231xx(state)) { 1383 if (is_cx2388x(state) || is_cx231xx(state)) {
1359 u8 v = (cx25840_read(client, 0x421) | 0x0b); 1384 v = cx25840_read(client, 0x421) | 0x0b;
1360 cx25840_write(client, 0x421, v); 1385 cx25840_write(client, 0x421, v);
1361 } else { 1386 } else {
1362 cx25840_write(client, 0x115, 1387 v = cx25840_read(client, 0x115) | 0x0c;
1363 is_cx2583x(state) ? 0x0c : 0x8c); 1388 cx25840_write(client, 0x115, v);
1364 cx25840_write(client, 0x116, 1389 v = cx25840_read(client, 0x116) | 0x04;
1365 is_cx2583x(state) ? 0x04 : 0x07); 1390 cx25840_write(client, 0x116, v);
1366 } 1391 }
1367 } else { 1392 } else {
1368 if (is_cx2388x(state) || is_cx231xx(state)) { 1393 if (is_cx2388x(state) || is_cx231xx(state)) {
1369 u8 v = cx25840_read(client, 0x421) & ~(0x0b); 1394 v = cx25840_read(client, 0x421) & ~(0x0b);
1370 cx25840_write(client, 0x421, v); 1395 cx25840_write(client, 0x421, v);
1371 } else { 1396 } else {
1372 cx25840_write(client, 0x115, 0x00); 1397 v = cx25840_read(client, 0x115) & ~(0x0c);
1373 cx25840_write(client, 0x116, 0x00); 1398 cx25840_write(client, 0x115, v);
1399 v = cx25840_read(client, 0x116) & ~(0x04);
1400 cx25840_write(client, 0x116, v);
1374 } 1401 }
1375 } 1402 }
1376 return 0; 1403 return 0;
@@ -1601,6 +1628,7 @@ static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1601static const struct v4l2_subdev_audio_ops cx25840_audio_ops = { 1628static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1602 .s_clock_freq = cx25840_s_clock_freq, 1629 .s_clock_freq = cx25840_s_clock_freq,
1603 .s_routing = cx25840_s_audio_routing, 1630 .s_routing = cx25840_s_audio_routing,
1631 .s_stream = cx25840_s_audio_stream,
1604}; 1632};
1605 1633
1606static const struct v4l2_subdev_video_ops cx25840_video_ops = { 1634static const struct v4l2_subdev_video_ops cx25840_video_ops = {
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 5a67445dd6ed..64b350df78e3 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -583,16 +583,18 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
583{ 583{
584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); 584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
585 struct cx88_core *core=chip->core; 585 struct cx88_core *core=chip->core;
586 int v, b; 586 int left, right, v, b;
587 int changed = 0; 587 int changed = 0;
588 u32 old; 588 u32 old;
589 589
590 b = value->value.integer.value[1] - value->value.integer.value[0]; 590 left = value->value.integer.value[0] & 0x3f;
591 right = value->value.integer.value[1] & 0x3f;
592 b = right - left;
591 if (b < 0) { 593 if (b < 0) {
592 v = 0x3f - value->value.integer.value[0]; 594 v = 0x3f - left;
593 b = (-b) | 0x40; 595 b = (-b) | 0x40;
594 } else { 596 } else {
595 v = 0x3f - value->value.integer.value[1]; 597 v = 0x3f - right;
596 } 598 }
597 /* Do we really know this will always be called with IRQs on? */ 599 /* Do we really know this will always be called with IRQs on? */
598 spin_lock_irq(&chip->reg_lock); 600 spin_lock_irq(&chip->reg_lock);
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index d844f2aaa01d..eaf0ee7de832 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1466,6 +1466,18 @@ static const struct cx88_board cx88_boards[] = {
1466 .audioroute = 8, 1466 .audioroute = 8,
1467 }, 1467 },
1468 }, 1468 },
1469 [CX88_BOARD_SAMSUNG_SMT_7020] = {
1470 .name = "Samsung SMT 7020 DVB-S",
1471 .tuner_type = TUNER_ABSENT,
1472 .radio_type = UNSET,
1473 .tuner_addr = ADDR_UNSET,
1474 .radio_addr = ADDR_UNSET,
1475 .input = { {
1476 .type = CX88_VMUX_DVB,
1477 .vmux = 0,
1478 } },
1479 .mpeg = CX88_MPEG_DVB,
1480 },
1469 [CX88_BOARD_ADSTECH_PTV_390] = { 1481 [CX88_BOARD_ADSTECH_PTV_390] = {
1470 .name = "ADS Tech Instant Video PCI", 1482 .name = "ADS Tech Instant Video PCI",
1471 .tuner_type = TUNER_ABSENT, 1483 .tuner_type = TUNER_ABSENT,
@@ -2355,6 +2367,14 @@ static const struct cx88_subid cx88_subids[] = {
2355 .subvendor = 0x0070, 2367 .subvendor = 0x0070,
2356 .subdevice = 0x1404, 2368 .subdevice = 0x1404,
2357 .card = CX88_BOARD_HAUPPAUGE_HVR3000, 2369 .card = CX88_BOARD_HAUPPAUGE_HVR3000,
2370 }, {
2371 .subvendor = 0x18ac,
2372 .subdevice = 0xdc00,
2373 .card = CX88_BOARD_SAMSUNG_SMT_7020,
2374 }, {
2375 .subvendor = 0x18ac,
2376 .subdevice = 0xdccd,
2377 .card = CX88_BOARD_SAMSUNG_SMT_7020,
2358 },{ 2378 },{
2359 .subvendor = 0x1461, 2379 .subvendor = 0x1461,
2360 .subdevice = 0xc111, /* AverMedia M150-D */ 2380 .subdevice = 0xc111, /* AverMedia M150-D */
@@ -2633,6 +2653,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2633 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */ 2653 case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
2634 /* known */ 2654 /* known */
2635 break; 2655 break;
2656 case CX88_BOARD_SAMSUNG_SMT_7020:
2657 cx_set(MO_GP0_IO, 0x008989FF);
2658 break;
2636 default: 2659 default:
2637 warn_printk(core, "warning: unknown hauppauge model #%d\n", 2660 warn_printk(core, "warning: unknown hauppauge model #%d\n",
2638 tv.model); 2661 tv.model);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index b14296923250..94ab862f0219 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -674,6 +674,194 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev)
674 return 0; 674 return 0;
675} 675}
676 676
677
678
679static u8 samsung_smt_7020_inittab[] = {
680 0x01, 0x15,
681 0x02, 0x00,
682 0x03, 0x00,
683 0x04, 0x7D,
684 0x05, 0x0F,
685 0x06, 0x02,
686 0x07, 0x00,
687 0x08, 0x60,
688
689 0x0A, 0xC2,
690 0x0B, 0x00,
691 0x0C, 0x01,
692 0x0D, 0x81,
693 0x0E, 0x44,
694 0x0F, 0x09,
695 0x10, 0x3C,
696 0x11, 0x84,
697 0x12, 0xDA,
698 0x13, 0x99,
699 0x14, 0x8D,
700 0x15, 0xCE,
701 0x16, 0xE8,
702 0x17, 0x43,
703 0x18, 0x1C,
704 0x19, 0x1B,
705 0x1A, 0x1D,
706
707 0x1C, 0x12,
708 0x1D, 0x00,
709 0x1E, 0x00,
710 0x1F, 0x00,
711 0x20, 0x00,
712 0x21, 0x00,
713 0x22, 0x00,
714 0x23, 0x00,
715
716 0x28, 0x02,
717 0x29, 0x28,
718 0x2A, 0x14,
719 0x2B, 0x0F,
720 0x2C, 0x09,
721 0x2D, 0x05,
722
723 0x31, 0x1F,
724 0x32, 0x19,
725 0x33, 0xFC,
726 0x34, 0x13,
727 0xff, 0xff,
728};
729
730
731static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
732 struct dvb_frontend_parameters *params)
733{
734 struct cx8802_dev *dev = fe->dvb->priv;
735 u8 buf[4];
736 u32 div;
737 struct i2c_msg msg = {
738 .addr = 0x61,
739 .flags = 0,
740 .buf = buf,
741 .len = sizeof(buf) };
742
743 div = params->frequency / 125;
744
745 buf[0] = (div >> 8) & 0x7f;
746 buf[1] = div & 0xff;
747 buf[2] = 0x84; /* 0xC4 */
748 buf[3] = 0x00;
749
750 if (params->frequency < 1500000)
751 buf[3] |= 0x10;
752
753 if (fe->ops.i2c_gate_ctrl)
754 fe->ops.i2c_gate_ctrl(fe, 1);
755
756 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
757 return -EIO;
758
759 return 0;
760}
761
762static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
763 fe_sec_tone_mode_t tone)
764{
765 struct cx8802_dev *dev = fe->dvb->priv;
766 struct cx88_core *core = dev->core;
767
768 cx_set(MO_GP0_IO, 0x0800);
769
770 switch (tone) {
771 case SEC_TONE_ON:
772 cx_set(MO_GP0_IO, 0x08);
773 break;
774 case SEC_TONE_OFF:
775 cx_clear(MO_GP0_IO, 0x08);
776 break;
777 default:
778 return -EINVAL;
779 }
780
781 return 0;
782}
783
784static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
785 fe_sec_voltage_t voltage)
786{
787 struct cx8802_dev *dev = fe->dvb->priv;
788 struct cx88_core *core = dev->core;
789
790 u8 data;
791 struct i2c_msg msg = {
792 .addr = 8,
793 .flags = 0,
794 .buf = &data,
795 .len = sizeof(data) };
796
797 cx_set(MO_GP0_IO, 0x8000);
798
799 switch (voltage) {
800 case SEC_VOLTAGE_OFF:
801 break;
802 case SEC_VOLTAGE_13:
803 data = ISL6421_EN1 | ISL6421_LLC1;
804 cx_clear(MO_GP0_IO, 0x80);
805 break;
806 case SEC_VOLTAGE_18:
807 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
808 cx_clear(MO_GP0_IO, 0x80);
809 break;
810 default:
811 return -EINVAL;
812 };
813
814 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
815}
816
817static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
818 u32 srate, u32 ratio)
819{
820 u8 aclk = 0;
821 u8 bclk = 0;
822
823 if (srate < 1500000) {
824 aclk = 0xb7;
825 bclk = 0x47;
826 } else if (srate < 3000000) {
827 aclk = 0xb7;
828 bclk = 0x4b;
829 } else if (srate < 7000000) {
830 aclk = 0xb7;
831 bclk = 0x4f;
832 } else if (srate < 14000000) {
833 aclk = 0xb7;
834 bclk = 0x53;
835 } else if (srate < 30000000) {
836 aclk = 0xb6;
837 bclk = 0x53;
838 } else if (srate < 45000000) {
839 aclk = 0xb4;
840 bclk = 0x51;
841 }
842
843 stv0299_writereg(fe, 0x13, aclk);
844 stv0299_writereg(fe, 0x14, bclk);
845 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
846 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
847 stv0299_writereg(fe, 0x21, ratio & 0xf0);
848
849 return 0;
850}
851
852
853static struct stv0299_config samsung_stv0299_config = {
854 .demod_address = 0x68,
855 .inittab = samsung_smt_7020_inittab,
856 .mclk = 88000000UL,
857 .invert = 0,
858 .skip_reinit = 0,
859 .lock_output = STV0299_LOCKOUTPUT_LK,
860 .volt13_op0_op1 = STV0299_VOLT13_OP1,
861 .min_delay_ms = 100,
862 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
863};
864
677static int dvb_register(struct cx8802_dev *dev) 865static int dvb_register(struct cx8802_dev *dev)
678{ 866{
679 struct cx88_core *core = dev->core; 867 struct cx88_core *core = dev->core;
@@ -1203,6 +1391,32 @@ static int dvb_register(struct cx8802_dev *dev)
1203 } 1391 }
1204 break; 1392 break;
1205 } 1393 }
1394 case CX88_BOARD_SAMSUNG_SMT_7020:
1395 dev->ts_gen_cntrl = 0x08;
1396
1397 cx_set(MO_GP0_IO, 0x0101);
1398
1399 cx_clear(MO_GP0_IO, 0x01);
1400 mdelay(100);
1401 cx_set(MO_GP0_IO, 0x01);
1402 mdelay(200);
1403
1404 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1405 &samsung_stv0299_config,
1406 &dev->core->i2c_adap);
1407 if (fe0->dvb.frontend) {
1408 fe0->dvb.frontend->ops.tuner_ops.set_params =
1409 samsung_smt_7020_tuner_set_params;
1410 fe0->dvb.frontend->tuner_priv =
1411 &dev->core->i2c_adap;
1412 fe0->dvb.frontend->ops.set_voltage =
1413 samsung_smt_7020_set_voltage;
1414 fe0->dvb.frontend->ops.set_tone =
1415 samsung_smt_7020_set_tone;
1416 }
1417
1418 break;
1419
1206 default: 1420 default:
1207 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1421 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1208 core->name); 1422 core->name);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index f9fda18b410c..de180d4d5a21 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -192,7 +192,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
192 struct cx88_IR *ir; 192 struct cx88_IR *ir;
193 struct input_dev *input_dev; 193 struct input_dev *input_dev;
194 struct ir_scancode_table *ir_codes = NULL; 194 struct ir_scancode_table *ir_codes = NULL;
195 int ir_type = IR_TYPE_OTHER; 195 u64 ir_type = IR_TYPE_OTHER;
196 int err = -ENOMEM; 196 int err = -ENOMEM;
197 197
198 ir = kzalloc(sizeof(*ir), GFP_KERNEL); 198 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
@@ -383,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
383 cx88_ir_start(core, ir); 383 cx88_ir_start(core, ir);
384 384
385 /* all done */ 385 /* all done */
386 err = ir_input_register(ir->input, ir_codes); 386 err = ir_input_register(ir->input, ir_codes, NULL);
387 if (err) 387 if (err)
388 goto err_out_stop; 388 goto err_out_stop;
389 389
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index bb5104893411..338af77f7f01 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -110,6 +110,9 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
110 case CX88_BOARD_PCHDTV_HD5500: 110 case CX88_BOARD_PCHDTV_HD5500:
111 cx_write(TS_SOP_STAT, 1<<13); 111 cx_write(TS_SOP_STAT, 1<<13);
112 break; 112 break;
113 case CX88_BOARD_SAMSUNG_SMT_7020:
114 cx_write(TS_SOP_STAT, 0x00);
115 break;
113 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 116 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
114 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 117 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
115 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ 118 cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index b1499bf604ea..48b6c04fb497 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -239,6 +239,7 @@ extern struct sram_channel cx88_sram_channels[];
239#define CX88_BOARD_WINFAST_DTV1800H 81 239#define CX88_BOARD_WINFAST_DTV1800H 81
240#define CX88_BOARD_WINFAST_DTV2000H_J 82 240#define CX88_BOARD_WINFAST_DTV2000H_J 82
241#define CX88_BOARD_PROF_7301 83 241#define CX88_BOARD_PROF_7301 83
242#define CX88_BOARD_SAMSUNG_SMT_7020 84
242 243
243enum cx88_itype { 244enum cx88_itype {
244 CX88_VMUX_COMPOSITE1 = 1, 245 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index ee43876adb06..9b413a35e048 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -913,6 +913,8 @@ static void __exit dabusb_cleanup (void)
913MODULE_AUTHOR( DRIVER_AUTHOR ); 913MODULE_AUTHOR( DRIVER_AUTHOR );
914MODULE_DESCRIPTION( DRIVER_DESC ); 914MODULE_DESCRIPTION( DRIVER_DESC );
915MODULE_LICENSE("GPL"); 915MODULE_LICENSE("GPL");
916MODULE_FIRMWARE("dabusb/firmware.fw");
917MODULE_FIRMWARE("dabusb/bitstream.bin");
916 918
917module_param(buffers, int, 0); 919module_param(buffers, int, 0);
918MODULE_PARM_DESC (buffers, "Number of buffers (default=256)"); 920MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
index 1a8b8f3f182e..a37955745aaa 100644
--- a/drivers/media/video/davinci/Makefile
+++ b/drivers/media/video/davinci/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o 15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o 16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o 17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
18obj-$(CONFIG_VIDEO_ISIF) += isif.o
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
index 314390016370..c29ac88ffd78 100644
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -37,8 +37,12 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/videodev2.h> 39#include <linux/videodev2.h>
40#include <linux/clk.h>
41#include <linux/err.h>
42
40#include <media/davinci/dm355_ccdc.h> 43#include <media/davinci/dm355_ccdc.h>
41#include <media/davinci/vpss.h> 44#include <media/davinci/vpss.h>
45
42#include "dm355_ccdc_regs.h" 46#include "dm355_ccdc_regs.h"
43#include "ccdc_hw_device.h" 47#include "ccdc_hw_device.h"
44 48
@@ -46,67 +50,75 @@ MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM355"); 50MODULE_DESCRIPTION("CCDC Driver for DM355");
47MODULE_AUTHOR("Texas Instruments"); 51MODULE_AUTHOR("Texas Instruments");
48 52
49static struct device *dev; 53static struct ccdc_oper_config {
50 54 struct device *dev;
51/* Object for CCDC raw mode */ 55 /* CCDC interface type */
52static struct ccdc_params_raw ccdc_hw_params_raw = { 56 enum vpfe_hw_if_type if_type;
53 .pix_fmt = CCDC_PIXFMT_RAW, 57 /* Raw Bayer configuration */
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE, 58 struct ccdc_params_raw bayer;
55 .win = CCDC_WIN_VGA, 59 /* YCbCr configuration */
56 .fid_pol = VPFE_PINPOL_POSITIVE, 60 struct ccdc_params_ycbcr ycbcr;
57 .vd_pol = VPFE_PINPOL_POSITIVE, 61 /* Master clock */
58 .hd_pol = VPFE_PINPOL_POSITIVE, 62 struct clk *mclk;
59 .gain = { 63 /* slave clock */
60 .r_ye = 256, 64 struct clk *sclk;
61 .gb_g = 256, 65 /* ccdc base address */
62 .gr_cy = 256, 66 void __iomem *base_addr;
63 .b_mg = 256 67} ccdc_cfg = {
64 }, 68 /* Raw configurations */
65 .config_params = { 69 .bayer = {
66 .datasft = 2, 70 .pix_fmt = CCDC_PIXFMT_RAW,
67 .data_sz = CCDC_DATA_10BITS, 71 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
68 .mfilt1 = CCDC_NO_MEDIAN_FILTER1, 72 .win = CCDC_WIN_VGA,
69 .mfilt2 = CCDC_NO_MEDIAN_FILTER2, 73 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .alaw = { 74 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .gama_wd = 2, 75 .hd_pol = VPFE_PINPOL_POSITIVE,
76 .gain = {
77 .r_ye = 256,
78 .gb_g = 256,
79 .gr_cy = 256,
80 .b_mg = 256
72 }, 81 },
73 .blk_clamp = { 82 .config_params = {
74 .sample_pixel = 1, 83 .datasft = 2,
75 .dc_sub = 25 84 .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
76 }, 85 .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
77 .col_pat_field0 = { 86 .alaw = {
78 .olop = CCDC_GREEN_BLUE, 87 .gama_wd = 2,
79 .olep = CCDC_BLUE, 88 },
80 .elop = CCDC_RED, 89 .blk_clamp = {
81 .elep = CCDC_GREEN_RED 90 .sample_pixel = 1,
82 }, 91 .dc_sub = 25
83 .col_pat_field1 = { 92 },
84 .olop = CCDC_GREEN_BLUE, 93 .col_pat_field0 = {
85 .olep = CCDC_BLUE, 94 .olop = CCDC_GREEN_BLUE,
86 .elop = CCDC_RED, 95 .olep = CCDC_BLUE,
87 .elep = CCDC_GREEN_RED 96 .elop = CCDC_RED,
97 .elep = CCDC_GREEN_RED
98 },
99 .col_pat_field1 = {
100 .olop = CCDC_GREEN_BLUE,
101 .olep = CCDC_BLUE,
102 .elop = CCDC_RED,
103 .elep = CCDC_GREEN_RED
104 },
88 }, 105 },
89 }, 106 },
107 /* YCbCr configuration */
108 .ycbcr = {
109 .win = CCDC_WIN_PAL,
110 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
111 .frm_fmt = CCDC_FRMFMT_INTERLACED,
112 .fid_pol = VPFE_PINPOL_POSITIVE,
113 .vd_pol = VPFE_PINPOL_POSITIVE,
114 .hd_pol = VPFE_PINPOL_POSITIVE,
115 .bt656_enable = 1,
116 .pix_order = CCDC_PIXORDER_CBYCRY,
117 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
118 },
90}; 119};
91 120
92 121
93/* Object for CCDC ycbcr mode */
94static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
95 .win = CCDC_WIN_PAL,
96 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
97 .frm_fmt = CCDC_FRMFMT_INTERLACED,
98 .fid_pol = VPFE_PINPOL_POSITIVE,
99 .vd_pol = VPFE_PINPOL_POSITIVE,
100 .hd_pol = VPFE_PINPOL_POSITIVE,
101 .bt656_enable = 1,
102 .pix_order = CCDC_PIXORDER_CBYCRY,
103 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
104};
105
106static enum vpfe_hw_if_type ccdc_if_type;
107static void *__iomem ccdc_base_addr;
108static int ccdc_addr_size;
109
110/* Raw Bayer formats */ 122/* Raw Bayer formats */
111static u32 ccdc_raw_bayer_pix_formats[] = 123static u32 ccdc_raw_bayer_pix_formats[] =
112 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16}; 124 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
@@ -118,18 +130,12 @@ static u32 ccdc_raw_yuv_pix_formats[] =
118/* register access routines */ 130/* register access routines */
119static inline u32 regr(u32 offset) 131static inline u32 regr(u32 offset)
120{ 132{
121 return __raw_readl(ccdc_base_addr + offset); 133 return __raw_readl(ccdc_cfg.base_addr + offset);
122} 134}
123 135
124static inline void regw(u32 val, u32 offset) 136static inline void regw(u32 val, u32 offset)
125{ 137{
126 __raw_writel(val, ccdc_base_addr + offset); 138 __raw_writel(val, ccdc_cfg.base_addr + offset);
127}
128
129static void ccdc_set_ccdc_base(void *addr, int size)
130{
131 ccdc_base_addr = addr;
132 ccdc_addr_size = size;
133} 139}
134 140
135static void ccdc_enable(int en) 141static void ccdc_enable(int en)
@@ -153,12 +159,12 @@ static void ccdc_enable_output_to_sdram(int en)
153static void ccdc_config_gain_offset(void) 159static void ccdc_config_gain_offset(void)
154{ 160{
155 /* configure gain */ 161 /* configure gain */
156 regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN); 162 regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
157 regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN); 163 regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
158 regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN); 164 regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
159 regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN); 165 regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
160 /* configure offset */ 166 /* configure offset */
161 regw(ccdc_hw_params_raw.ccdc_offset, OFFSET); 167 regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
162} 168}
163 169
164/* 170/*
@@ -169,7 +175,7 @@ static int ccdc_restore_defaults(void)
169{ 175{
170 int i; 176 int i;
171 177
172 dev_dbg(dev, "\nstarting ccdc_restore_defaults..."); 178 dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
173 /* set all registers to zero */ 179 /* set all registers to zero */
174 for (i = 0; i <= CCDC_REG_LAST; i += 4) 180 for (i = 0; i <= CCDC_REG_LAST; i += 4)
175 regw(0, i); 181 regw(0, i);
@@ -180,30 +186,29 @@ static int ccdc_restore_defaults(void)
180 regw(CULH_DEFAULT, CULH); 186 regw(CULH_DEFAULT, CULH);
181 regw(CULV_DEFAULT, CULV); 187 regw(CULV_DEFAULT, CULV);
182 /* Set default Gain and Offset */ 188 /* Set default Gain and Offset */
183 ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT; 189 ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
184 ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT; 190 ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
185 ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT; 191 ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
186 ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT; 192 ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
187 ccdc_config_gain_offset(); 193 ccdc_config_gain_offset();
188 regw(OUTCLIP_DEFAULT, OUTCLIP); 194 regw(OUTCLIP_DEFAULT, OUTCLIP);
189 regw(LSCCFG2_DEFAULT, LSCCFG2); 195 regw(LSCCFG2_DEFAULT, LSCCFG2);
190 /* select ccdc input */ 196 /* select ccdc input */
191 if (vpss_select_ccdc_source(VPSS_CCDCIN)) { 197 if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
192 dev_dbg(dev, "\ncouldn't select ccdc input source"); 198 dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
193 return -EFAULT; 199 return -EFAULT;
194 } 200 }
195 /* select ccdc clock */ 201 /* select ccdc clock */
196 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) { 202 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
197 dev_dbg(dev, "\ncouldn't enable ccdc clock"); 203 dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
198 return -EFAULT; 204 return -EFAULT;
199 } 205 }
200 dev_dbg(dev, "\nEnd of ccdc_restore_defaults..."); 206 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
201 return 0; 207 return 0;
202} 208}
203 209
204static int ccdc_open(struct device *device) 210static int ccdc_open(struct device *device)
205{ 211{
206 dev = device;
207 return ccdc_restore_defaults(); 212 return ccdc_restore_defaults();
208} 213}
209 214
@@ -226,7 +231,7 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
226 int vert_start, vert_nr_lines; 231 int vert_start, vert_nr_lines;
227 int mid_img = 0; 232 int mid_img = 0;
228 233
229 dev_dbg(dev, "\nStarting ccdc_setwin..."); 234 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
230 235
231 /* 236 /*
232 * ppc - per pixel count. indicates how many pixels per cell 237 * ppc - per pixel count. indicates how many pixels per cell
@@ -260,45 +265,46 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
260 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0); 265 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
261 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1); 266 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
262 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV); 267 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
263 dev_dbg(dev, "\nEnd of ccdc_setwin..."); 268 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
264} 269}
265 270
266static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) 271static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
267{ 272{
268 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT || 273 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
269 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) { 274 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
270 dev_dbg(dev, "Invalid value of data shift\n"); 275 dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
271 return -EINVAL; 276 return -EINVAL;
272 } 277 }
273 278
274 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 || 279 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
275 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) { 280 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
276 dev_dbg(dev, "Invalid value of median filter1\n"); 281 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
277 return -EINVAL; 282 return -EINVAL;
278 } 283 }
279 284
280 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 || 285 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
281 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) { 286 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
282 dev_dbg(dev, "Invalid value of median filter2\n"); 287 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
283 return -EINVAL; 288 return -EINVAL;
284 } 289 }
285 290
286 if ((ccdcparam->med_filt_thres < 0) || 291 if ((ccdcparam->med_filt_thres < 0) ||
287 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) { 292 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
288 dev_dbg(dev, "Invalid value of median filter threshold\n"); 293 dev_dbg(ccdc_cfg.dev,
294 "Invalid value of median filter thresold\n");
289 return -EINVAL; 295 return -EINVAL;
290 } 296 }
291 297
292 if (ccdcparam->data_sz < CCDC_DATA_16BITS || 298 if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
293 ccdcparam->data_sz > CCDC_DATA_8BITS) { 299 ccdcparam->data_sz > CCDC_DATA_8BITS) {
294 dev_dbg(dev, "Invalid value of data size\n"); 300 dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
295 return -EINVAL; 301 return -EINVAL;
296 } 302 }
297 303
298 if (ccdcparam->alaw.enable) { 304 if (ccdcparam->alaw.enable) {
299 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 || 305 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
300 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) { 306 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
301 dev_dbg(dev, "Invalid value of ALAW\n"); 307 dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
302 return -EINVAL; 308 return -EINVAL;
303 } 309 }
304 } 310 }
@@ -306,12 +312,14 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
306 if (ccdcparam->blk_clamp.b_clamp_enable) { 312 if (ccdcparam->blk_clamp.b_clamp_enable) {
307 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS || 313 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
308 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) { 314 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
309 dev_dbg(dev, "Invalid value of sample pixel\n"); 315 dev_dbg(ccdc_cfg.dev,
316 "Invalid value of sample pixel\n");
310 return -EINVAL; 317 return -EINVAL;
311 } 318 }
312 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES || 319 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
313 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) { 320 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
314 dev_dbg(dev, "Invalid value of sample lines\n"); 321 dev_dbg(ccdc_cfg.dev,
322 "Invalid value of sample lines\n");
315 return -EINVAL; 323 return -EINVAL;
316 } 324 }
317 } 325 }
@@ -325,18 +333,18 @@ static int ccdc_set_params(void __user *params)
325 int x; 333 int x;
326 334
327 /* only raw module parameters can be set through the IOCTL */ 335 /* only raw module parameters can be set through the IOCTL */
328 if (ccdc_if_type != VPFE_RAW_BAYER) 336 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
329 return -EINVAL; 337 return -EINVAL;
330 338
331 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); 339 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
332 if (x) { 340 if (x) {
333 dev_dbg(dev, "ccdc_set_params: error in copying ccdc" 341 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
334 "params, %d\n", x); 342 "params, %d\n", x);
335 return -EFAULT; 343 return -EFAULT;
336 } 344 }
337 345
338 if (!validate_ccdc_param(&ccdc_raw_params)) { 346 if (!validate_ccdc_param(&ccdc_raw_params)) {
339 memcpy(&ccdc_hw_params_raw.config_params, 347 memcpy(&ccdc_cfg.bayer.config_params,
340 &ccdc_raw_params, 348 &ccdc_raw_params,
341 sizeof(ccdc_raw_params)); 349 sizeof(ccdc_raw_params));
342 return 0; 350 return 0;
@@ -347,11 +355,11 @@ static int ccdc_set_params(void __user *params)
347/* This function will configure CCDC for YCbCr video capture */ 355/* This function will configure CCDC for YCbCr video capture */
348static void ccdc_config_ycbcr(void) 356static void ccdc_config_ycbcr(void)
349{ 357{
350 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; 358 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
351 u32 temp; 359 u32 temp;
352 360
353 /* first set the CCDC power on defaults values in all registers */ 361 /* first set the CCDC power on defaults values in all registers */
354 dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); 362 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
355 ccdc_restore_defaults(); 363 ccdc_restore_defaults();
356 364
357 /* configure pixel format & video frame format */ 365 /* configure pixel format & video frame format */
@@ -403,7 +411,7 @@ static void ccdc_config_ycbcr(void)
403 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST); 411 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
404 } 412 }
405 413
406 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); 414 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
407} 415}
408 416
409/* 417/*
@@ -483,7 +491,7 @@ int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
483 */ 491 */
484 492
485 if (count) { 493 if (count) {
486 dev_err(dev, "defect table write timeout !!!\n"); 494 dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
487 return -1; 495 return -1;
488 } 496 }
489 return 0; 497 return 0;
@@ -605,12 +613,12 @@ static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
605/* This function will configure CCDC for Raw mode image capture */ 613/* This function will configure CCDC for Raw mode image capture */
606static int ccdc_config_raw(void) 614static int ccdc_config_raw(void)
607{ 615{
608 struct ccdc_params_raw *params = &ccdc_hw_params_raw; 616 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
609 struct ccdc_config_params_raw *config_params = 617 struct ccdc_config_params_raw *config_params =
610 &ccdc_hw_params_raw.config_params; 618 &ccdc_cfg.bayer.config_params;
611 unsigned int val; 619 unsigned int val;
612 620
613 dev_dbg(dev, "\nStarting ccdc_config_raw..."); 621 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
614 622
615 /* restore power on defaults to register */ 623 /* restore power on defaults to register */
616 ccdc_restore_defaults(); 624 ccdc_restore_defaults();
@@ -659,7 +667,7 @@ static int ccdc_config_raw(void)
659 val |= (config_params->datasft & CCDC_DATASFT_MASK) << 667 val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
660 CCDC_DATASFT_SHIFT; 668 CCDC_DATASFT_SHIFT;
661 regw(val , MODESET); 669 regw(val , MODESET);
662 dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val); 670 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
663 671
664 /* Configure the Median Filter threshold */ 672 /* Configure the Median Filter threshold */
665 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT); 673 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
@@ -681,7 +689,7 @@ static int ccdc_config_raw(void)
681 (config_params->mfilt2 << CCDC_MFILT2_SHIFT)); 689 (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
682 690
683 regw(val, GAMMAWD); 691 regw(val, GAMMAWD);
684 dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val); 692 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
685 693
686 /* configure video window */ 694 /* configure video window */
687 ccdc_setwin(&params->win, params->frm_fmt, 1); 695 ccdc_setwin(&params->win, params->frm_fmt, 1);
@@ -706,7 +714,7 @@ static int ccdc_config_raw(void)
706 /* Configure the Gain & offset control */ 714 /* Configure the Gain & offset control */
707 ccdc_config_gain_offset(); 715 ccdc_config_gain_offset();
708 716
709 dev_dbg(dev, "\nWriting %x to COLPTN...\n", val); 717 dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
710 718
711 /* Configure DATAOFST register */ 719 /* Configure DATAOFST register */
712 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) << 720 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
@@ -726,7 +734,7 @@ static int ccdc_config_raw(void)
726 CCDC_HSIZE_VAL_MASK; 734 CCDC_HSIZE_VAL_MASK;
727 735
728 /* adjust to multiple of 32 */ 736 /* adjust to multiple of 32 */
729 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", 737 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
730 (((params->win.width) + 31) >> 5) & 738 (((params->win.width) + 31) >> 5) &
731 CCDC_HSIZE_VAL_MASK); 739 CCDC_HSIZE_VAL_MASK);
732 } else { 740 } else {
@@ -734,7 +742,7 @@ static int ccdc_config_raw(void)
734 val |= (((params->win.width * 2) + 31) >> 5) & 742 val |= (((params->win.width * 2) + 31) >> 5) &
735 CCDC_HSIZE_VAL_MASK; 743 CCDC_HSIZE_VAL_MASK;
736 744
737 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", 745 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
738 (((params->win.width * 2) + 31) >> 5) & 746 (((params->win.width * 2) + 31) >> 5) &
739 CCDC_HSIZE_VAL_MASK); 747 CCDC_HSIZE_VAL_MASK);
740 } 748 }
@@ -745,34 +753,34 @@ static int ccdc_config_raw(void)
745 if (params->image_invert_enable) { 753 if (params->image_invert_enable) {
746 /* For interlace inverse mode */ 754 /* For interlace inverse mode */
747 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST); 755 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
748 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 756 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
749 CCDC_SDOFST_INTERLACE_INVERSE); 757 CCDC_SDOFST_INTERLACE_INVERSE);
750 } else { 758 } else {
751 /* For interlace non inverse mode */ 759 /* For interlace non inverse mode */
752 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST); 760 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
753 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 761 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
754 CCDC_SDOFST_INTERLACE_NORMAL); 762 CCDC_SDOFST_INTERLACE_NORMAL);
755 } 763 }
756 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { 764 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
757 if (params->image_invert_enable) { 765 if (params->image_invert_enable) {
758 /* For progessive inverse mode */ 766 /* For progessive inverse mode */
759 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST); 767 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
760 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 768 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
761 CCDC_SDOFST_PROGRESSIVE_INVERSE); 769 CCDC_SDOFST_PROGRESSIVE_INVERSE);
762 } else { 770 } else {
763 /* For progessive non inverse mode */ 771 /* For progessive non inverse mode */
764 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST); 772 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
765 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 773 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
766 CCDC_SDOFST_PROGRESSIVE_NORMAL); 774 CCDC_SDOFST_PROGRESSIVE_NORMAL);
767 } 775 }
768 } 776 }
769 dev_dbg(dev, "\nend of ccdc_config_raw..."); 777 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
770 return 0; 778 return 0;
771} 779}
772 780
773static int ccdc_configure(void) 781static int ccdc_configure(void)
774{ 782{
775 if (ccdc_if_type == VPFE_RAW_BAYER) 783 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
776 return ccdc_config_raw(); 784 return ccdc_config_raw();
777 else 785 else
778 ccdc_config_ycbcr(); 786 ccdc_config_ycbcr();
@@ -781,23 +789,23 @@ static int ccdc_configure(void)
781 789
782static int ccdc_set_buftype(enum ccdc_buftype buf_type) 790static int ccdc_set_buftype(enum ccdc_buftype buf_type)
783{ 791{
784 if (ccdc_if_type == VPFE_RAW_BAYER) 792 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
785 ccdc_hw_params_raw.buf_type = buf_type; 793 ccdc_cfg.bayer.buf_type = buf_type;
786 else 794 else
787 ccdc_hw_params_ycbcr.buf_type = buf_type; 795 ccdc_cfg.ycbcr.buf_type = buf_type;
788 return 0; 796 return 0;
789} 797}
790static enum ccdc_buftype ccdc_get_buftype(void) 798static enum ccdc_buftype ccdc_get_buftype(void)
791{ 799{
792 if (ccdc_if_type == VPFE_RAW_BAYER) 800 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
793 return ccdc_hw_params_raw.buf_type; 801 return ccdc_cfg.bayer.buf_type;
794 return ccdc_hw_params_ycbcr.buf_type; 802 return ccdc_cfg.ycbcr.buf_type;
795} 803}
796 804
797static int ccdc_enum_pix(u32 *pix, int i) 805static int ccdc_enum_pix(u32 *pix, int i)
798{ 806{
799 int ret = -EINVAL; 807 int ret = -EINVAL;
800 if (ccdc_if_type == VPFE_RAW_BAYER) { 808 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
801 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { 809 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
802 *pix = ccdc_raw_bayer_pix_formats[i]; 810 *pix = ccdc_raw_bayer_pix_formats[i];
803 ret = 0; 811 ret = 0;
@@ -813,20 +821,19 @@ static int ccdc_enum_pix(u32 *pix, int i)
813 821
814static int ccdc_set_pixel_format(u32 pixfmt) 822static int ccdc_set_pixel_format(u32 pixfmt)
815{ 823{
816 struct ccdc_a_law *alaw = 824 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
817 &ccdc_hw_params_raw.config_params.alaw;
818 825
819 if (ccdc_if_type == VPFE_RAW_BAYER) { 826 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
820 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; 827 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
821 if (pixfmt == V4L2_PIX_FMT_SBGGR8) 828 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
822 alaw->enable = 1; 829 alaw->enable = 1;
823 else if (pixfmt != V4L2_PIX_FMT_SBGGR16) 830 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
824 return -EINVAL; 831 return -EINVAL;
825 } else { 832 } else {
826 if (pixfmt == V4L2_PIX_FMT_YUYV) 833 if (pixfmt == V4L2_PIX_FMT_YUYV)
827 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; 834 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
828 else if (pixfmt == V4L2_PIX_FMT_UYVY) 835 else if (pixfmt == V4L2_PIX_FMT_UYVY)
829 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; 836 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
830 else 837 else
831 return -EINVAL; 838 return -EINVAL;
832 } 839 }
@@ -834,17 +841,16 @@ static int ccdc_set_pixel_format(u32 pixfmt)
834} 841}
835static u32 ccdc_get_pixel_format(void) 842static u32 ccdc_get_pixel_format(void)
836{ 843{
837 struct ccdc_a_law *alaw = 844 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
838 &ccdc_hw_params_raw.config_params.alaw;
839 u32 pixfmt; 845 u32 pixfmt;
840 846
841 if (ccdc_if_type == VPFE_RAW_BAYER) 847 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
842 if (alaw->enable) 848 if (alaw->enable)
843 pixfmt = V4L2_PIX_FMT_SBGGR8; 849 pixfmt = V4L2_PIX_FMT_SBGGR8;
844 else 850 else
845 pixfmt = V4L2_PIX_FMT_SBGGR16; 851 pixfmt = V4L2_PIX_FMT_SBGGR16;
846 else { 852 else {
847 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) 853 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
848 pixfmt = V4L2_PIX_FMT_YUYV; 854 pixfmt = V4L2_PIX_FMT_YUYV;
849 else 855 else
850 pixfmt = V4L2_PIX_FMT_UYVY; 856 pixfmt = V4L2_PIX_FMT_UYVY;
@@ -853,53 +859,53 @@ static u32 ccdc_get_pixel_format(void)
853} 859}
854static int ccdc_set_image_window(struct v4l2_rect *win) 860static int ccdc_set_image_window(struct v4l2_rect *win)
855{ 861{
856 if (ccdc_if_type == VPFE_RAW_BAYER) 862 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
857 ccdc_hw_params_raw.win = *win; 863 ccdc_cfg.bayer.win = *win;
858 else 864 else
859 ccdc_hw_params_ycbcr.win = *win; 865 ccdc_cfg.ycbcr.win = *win;
860 return 0; 866 return 0;
861} 867}
862 868
863static void ccdc_get_image_window(struct v4l2_rect *win) 869static void ccdc_get_image_window(struct v4l2_rect *win)
864{ 870{
865 if (ccdc_if_type == VPFE_RAW_BAYER) 871 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
866 *win = ccdc_hw_params_raw.win; 872 *win = ccdc_cfg.bayer.win;
867 else 873 else
868 *win = ccdc_hw_params_ycbcr.win; 874 *win = ccdc_cfg.ycbcr.win;
869} 875}
870 876
871static unsigned int ccdc_get_line_length(void) 877static unsigned int ccdc_get_line_length(void)
872{ 878{
873 struct ccdc_config_params_raw *config_params = 879 struct ccdc_config_params_raw *config_params =
874 &ccdc_hw_params_raw.config_params; 880 &ccdc_cfg.bayer.config_params;
875 unsigned int len; 881 unsigned int len;
876 882
877 if (ccdc_if_type == VPFE_RAW_BAYER) { 883 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
878 if ((config_params->alaw.enable) || 884 if ((config_params->alaw.enable) ||
879 (config_params->data_sz == CCDC_DATA_8BITS)) 885 (config_params->data_sz == CCDC_DATA_8BITS))
880 len = ccdc_hw_params_raw.win.width; 886 len = ccdc_cfg.bayer.win.width;
881 else 887 else
882 len = ccdc_hw_params_raw.win.width * 2; 888 len = ccdc_cfg.bayer.win.width * 2;
883 } else 889 } else
884 len = ccdc_hw_params_ycbcr.win.width * 2; 890 len = ccdc_cfg.ycbcr.win.width * 2;
885 return ALIGN(len, 32); 891 return ALIGN(len, 32);
886} 892}
887 893
888static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) 894static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
889{ 895{
890 if (ccdc_if_type == VPFE_RAW_BAYER) 896 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
891 ccdc_hw_params_raw.frm_fmt = frm_fmt; 897 ccdc_cfg.bayer.frm_fmt = frm_fmt;
892 else 898 else
893 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; 899 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
894 return 0; 900 return 0;
895} 901}
896 902
897static enum ccdc_frmfmt ccdc_get_frame_format(void) 903static enum ccdc_frmfmt ccdc_get_frame_format(void)
898{ 904{
899 if (ccdc_if_type == VPFE_RAW_BAYER) 905 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
900 return ccdc_hw_params_raw.frm_fmt; 906 return ccdc_cfg.bayer.frm_fmt;
901 else 907 else
902 return ccdc_hw_params_ycbcr.frm_fmt; 908 return ccdc_cfg.ycbcr.frm_fmt;
903} 909}
904 910
905static int ccdc_getfid(void) 911static int ccdc_getfid(void)
@@ -916,14 +922,14 @@ static inline void ccdc_setfbaddr(unsigned long addr)
916 922
917static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) 923static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
918{ 924{
919 ccdc_if_type = params->if_type; 925 ccdc_cfg.if_type = params->if_type;
920 926
921 switch (params->if_type) { 927 switch (params->if_type) {
922 case VPFE_BT656: 928 case VPFE_BT656:
923 case VPFE_YCBCR_SYNC_16: 929 case VPFE_YCBCR_SYNC_16:
924 case VPFE_YCBCR_SYNC_8: 930 case VPFE_YCBCR_SYNC_8:
925 ccdc_hw_params_ycbcr.vd_pol = params->vdpol; 931 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
926 ccdc_hw_params_ycbcr.hd_pol = params->hdpol; 932 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
927 break; 933 break;
928 default: 934 default:
929 /* TODO add support for raw bayer here */ 935 /* TODO add support for raw bayer here */
@@ -938,7 +944,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
938 .hw_ops = { 944 .hw_ops = {
939 .open = ccdc_open, 945 .open = ccdc_open,
940 .close = ccdc_close, 946 .close = ccdc_close,
941 .set_ccdc_base = ccdc_set_ccdc_base,
942 .enable = ccdc_enable, 947 .enable = ccdc_enable,
943 .enable_out_to_sdram = ccdc_enable_output_to_sdram, 948 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
944 .set_hw_if_params = ccdc_set_hw_if_params, 949 .set_hw_if_params = ccdc_set_hw_if_params,
@@ -959,19 +964,118 @@ static struct ccdc_hw_device ccdc_hw_dev = {
959 }, 964 },
960}; 965};
961 966
962static int __init dm355_ccdc_init(void) 967static int __init dm355_ccdc_probe(struct platform_device *pdev)
963{ 968{
964 printk(KERN_NOTICE "dm355_ccdc_init\n"); 969 void (*setup_pinmux)(void);
965 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) 970 struct resource *res;
966 return -1; 971 int status = 0;
967 printk(KERN_NOTICE "%s is registered with vpfe.\n", 972
968 ccdc_hw_dev.name); 973 /*
974 * first try to register with vpfe. If not correct platform, then we
975 * don't have to iomap
976 */
977 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
978 if (status < 0)
979 return status;
980
981 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
982 if (!res) {
983 status = -ENODEV;
984 goto fail_nores;
985 }
986
987 res = request_mem_region(res->start, resource_size(res), res->name);
988 if (!res) {
989 status = -EBUSY;
990 goto fail_nores;
991 }
992
993 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
994 if (!ccdc_cfg.base_addr) {
995 status = -ENOMEM;
996 goto fail_nomem;
997 }
998
999 /* Get and enable Master clock */
1000 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
1001 if (IS_ERR(ccdc_cfg.mclk)) {
1002 status = PTR_ERR(ccdc_cfg.mclk);
1003 goto fail_nomap;
1004 }
1005 if (clk_enable(ccdc_cfg.mclk)) {
1006 status = -ENODEV;
1007 goto fail_mclk;
1008 }
1009
1010 /* Get and enable Slave clock */
1011 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
1012 if (IS_ERR(ccdc_cfg.sclk)) {
1013 status = PTR_ERR(ccdc_cfg.sclk);
1014 goto fail_mclk;
1015 }
1016 if (clk_enable(ccdc_cfg.sclk)) {
1017 status = -ENODEV;
1018 goto fail_sclk;
1019 }
1020
1021 /* Platform data holds setup_pinmux function ptr */
1022 if (NULL == pdev->dev.platform_data) {
1023 status = -ENODEV;
1024 goto fail_sclk;
1025 }
1026 setup_pinmux = pdev->dev.platform_data;
1027 /*
1028 * setup Mux configuration for ccdc which may be different for
1029 * different SoCs using this CCDC
1030 */
1031 setup_pinmux();
1032 ccdc_cfg.dev = &pdev->dev;
1033 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
969 return 0; 1034 return 0;
1035fail_sclk:
1036 clk_put(ccdc_cfg.sclk);
1037fail_mclk:
1038 clk_put(ccdc_cfg.mclk);
1039fail_nomap:
1040 iounmap(ccdc_cfg.base_addr);
1041fail_nomem:
1042 release_mem_region(res->start, resource_size(res));
1043fail_nores:
1044 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1045 return status;
970} 1046}
971 1047
972static void __exit dm355_ccdc_exit(void) 1048static int dm355_ccdc_remove(struct platform_device *pdev)
973{ 1049{
1050 struct resource *res;
1051
1052 clk_put(ccdc_cfg.mclk);
1053 clk_put(ccdc_cfg.sclk);
1054 iounmap(ccdc_cfg.base_addr);
1055 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1056 if (res)
1057 release_mem_region(res->start, resource_size(res));
974 vpfe_unregister_ccdc_device(&ccdc_hw_dev); 1058 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1059 return 0;
1060}
1061
1062static struct platform_driver dm355_ccdc_driver = {
1063 .driver = {
1064 .name = "dm355_ccdc",
1065 .owner = THIS_MODULE,
1066 },
1067 .remove = __devexit_p(dm355_ccdc_remove),
1068 .probe = dm355_ccdc_probe,
1069};
1070
1071static int __init dm355_ccdc_init(void)
1072{
1073 return platform_driver_register(&dm355_ccdc_driver);
1074}
1075
1076static void __exit dm355_ccdc_exit(void)
1077{
1078 platform_driver_unregister(&dm355_ccdc_driver);
975} 1079}
976 1080
977module_init(dm355_ccdc_init); 1081module_init(dm355_ccdc_init);
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
index d5fa193f32d2..0c394cade22a 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -37,8 +37,12 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/videodev2.h> 39#include <linux/videodev2.h>
40#include <linux/clk.h>
41#include <linux/err.h>
42
40#include <media/davinci/dm644x_ccdc.h> 43#include <media/davinci/dm644x_ccdc.h>
41#include <media/davinci/vpss.h> 44#include <media/davinci/vpss.h>
45
42#include "dm644x_ccdc_regs.h" 46#include "dm644x_ccdc_regs.h"
43#include "ccdc_hw_device.h" 47#include "ccdc_hw_device.h"
44 48
@@ -46,32 +50,44 @@ MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM6446"); 50MODULE_DESCRIPTION("CCDC Driver for DM6446");
47MODULE_AUTHOR("Texas Instruments"); 51MODULE_AUTHOR("Texas Instruments");
48 52
49static struct device *dev; 53static struct ccdc_oper_config {
50 54 struct device *dev;
51/* Object for CCDC raw mode */ 55 /* CCDC interface type */
52static struct ccdc_params_raw ccdc_hw_params_raw = { 56 enum vpfe_hw_if_type if_type;
53 .pix_fmt = CCDC_PIXFMT_RAW, 57 /* Raw Bayer configuration */
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE, 58 struct ccdc_params_raw bayer;
55 .win = CCDC_WIN_VGA, 59 /* YCbCr configuration */
56 .fid_pol = VPFE_PINPOL_POSITIVE, 60 struct ccdc_params_ycbcr ycbcr;
57 .vd_pol = VPFE_PINPOL_POSITIVE, 61 /* Master clock */
58 .hd_pol = VPFE_PINPOL_POSITIVE, 62 struct clk *mclk;
59 .config_params = { 63 /* slave clock */
60 .data_sz = CCDC_DATA_10BITS, 64 struct clk *sclk;
65 /* ccdc base address */
66 void __iomem *base_addr;
67} ccdc_cfg = {
68 /* Raw configurations */
69 .bayer = {
70 .pix_fmt = CCDC_PIXFMT_RAW,
71 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
72 .win = CCDC_WIN_VGA,
73 .fid_pol = VPFE_PINPOL_POSITIVE,
74 .vd_pol = VPFE_PINPOL_POSITIVE,
75 .hd_pol = VPFE_PINPOL_POSITIVE,
76 .config_params = {
77 .data_sz = CCDC_DATA_10BITS,
78 },
79 },
80 .ycbcr = {
81 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
82 .frm_fmt = CCDC_FRMFMT_INTERLACED,
83 .win = CCDC_WIN_PAL,
84 .fid_pol = VPFE_PINPOL_POSITIVE,
85 .vd_pol = VPFE_PINPOL_POSITIVE,
86 .hd_pol = VPFE_PINPOL_POSITIVE,
87 .bt656_enable = 1,
88 .pix_order = CCDC_PIXORDER_CBYCRY,
89 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
61 }, 90 },
62};
63
64/* Object for CCDC ycbcr mode */
65static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
66 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
67 .frm_fmt = CCDC_FRMFMT_INTERLACED,
68 .win = CCDC_WIN_PAL,
69 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .hd_pol = VPFE_PINPOL_POSITIVE,
72 .bt656_enable = 1,
73 .pix_order = CCDC_PIXORDER_CBYCRY,
74 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
75}; 91};
76 92
77#define CCDC_MAX_RAW_YUV_FORMATS 2 93#define CCDC_MAX_RAW_YUV_FORMATS 2
@@ -84,25 +100,15 @@ static u32 ccdc_raw_bayer_pix_formats[] =
84static u32 ccdc_raw_yuv_pix_formats[] = 100static u32 ccdc_raw_yuv_pix_formats[] =
85 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV}; 101 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
86 102
87static void *__iomem ccdc_base_addr;
88static int ccdc_addr_size;
89static enum vpfe_hw_if_type ccdc_if_type;
90
91/* register access routines */ 103/* register access routines */
92static inline u32 regr(u32 offset) 104static inline u32 regr(u32 offset)
93{ 105{
94 return __raw_readl(ccdc_base_addr + offset); 106 return __raw_readl(ccdc_cfg.base_addr + offset);
95} 107}
96 108
97static inline void regw(u32 val, u32 offset) 109static inline void regw(u32 val, u32 offset)
98{ 110{
99 __raw_writel(val, ccdc_base_addr + offset); 111 __raw_writel(val, ccdc_cfg.base_addr + offset);
100}
101
102static void ccdc_set_ccdc_base(void *addr, int size)
103{
104 ccdc_base_addr = addr;
105 ccdc_addr_size = size;
106} 112}
107 113
108static void ccdc_enable(int flag) 114static void ccdc_enable(int flag)
@@ -132,7 +138,7 @@ void ccdc_setwin(struct v4l2_rect *image_win,
132 int vert_start, vert_nr_lines; 138 int vert_start, vert_nr_lines;
133 int val = 0, mid_img = 0; 139 int val = 0, mid_img = 0;
134 140
135 dev_dbg(dev, "\nStarting ccdc_setwin..."); 141 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
136 /* 142 /*
137 * ppc - per pixel count. indicates how many pixels per cell 143 * ppc - per pixel count. indicates how many pixels per cell
138 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2. 144 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
@@ -171,7 +177,7 @@ void ccdc_setwin(struct v4l2_rect *image_win,
171 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start, 177 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
172 CCDC_VERT_START); 178 CCDC_VERT_START);
173 regw(vert_nr_lines, CCDC_VERT_LINES); 179 regw(vert_nr_lines, CCDC_VERT_LINES);
174 dev_dbg(dev, "\nEnd of ccdc_setwin..."); 180 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
175} 181}
176 182
177static void ccdc_readregs(void) 183static void ccdc_readregs(void)
@@ -179,39 +185,39 @@ static void ccdc_readregs(void)
179 unsigned int val = 0; 185 unsigned int val = 0;
180 186
181 val = regr(CCDC_ALAW); 187 val = regr(CCDC_ALAW);
182 dev_notice(dev, "\nReading 0x%x to ALAW...\n", val); 188 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
183 val = regr(CCDC_CLAMP); 189 val = regr(CCDC_CLAMP);
184 dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val); 190 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
185 val = regr(CCDC_DCSUB); 191 val = regr(CCDC_DCSUB);
186 dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val); 192 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
187 val = regr(CCDC_BLKCMP); 193 val = regr(CCDC_BLKCMP);
188 dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val); 194 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
189 val = regr(CCDC_FPC_ADDR); 195 val = regr(CCDC_FPC_ADDR);
190 dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val); 196 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
191 val = regr(CCDC_FPC); 197 val = regr(CCDC_FPC);
192 dev_notice(dev, "\nReading 0x%x to FPC...\n", val); 198 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
193 val = regr(CCDC_FMTCFG); 199 val = regr(CCDC_FMTCFG);
194 dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val); 200 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
195 val = regr(CCDC_COLPTN); 201 val = regr(CCDC_COLPTN);
196 dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val); 202 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
197 val = regr(CCDC_FMT_HORZ); 203 val = regr(CCDC_FMT_HORZ);
198 dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val); 204 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
199 val = regr(CCDC_FMT_VERT); 205 val = regr(CCDC_FMT_VERT);
200 dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val); 206 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
201 val = regr(CCDC_HSIZE_OFF); 207 val = regr(CCDC_HSIZE_OFF);
202 dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val); 208 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
203 val = regr(CCDC_SDOFST); 209 val = regr(CCDC_SDOFST);
204 dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val); 210 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
205 val = regr(CCDC_VP_OUT); 211 val = regr(CCDC_VP_OUT);
206 dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val); 212 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
207 val = regr(CCDC_SYN_MODE); 213 val = regr(CCDC_SYN_MODE);
208 dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val); 214 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
209 val = regr(CCDC_HORZ_INFO); 215 val = regr(CCDC_HORZ_INFO);
210 dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val); 216 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
211 val = regr(CCDC_VERT_START); 217 val = regr(CCDC_VERT_START);
212 dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val); 218 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
213 val = regr(CCDC_VERT_LINES); 219 val = regr(CCDC_VERT_LINES);
214 dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val); 220 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
215} 221}
216 222
217static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) 223static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
@@ -220,7 +226,7 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
220 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) || 226 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
221 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) || 227 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
222 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) { 228 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
223 dev_dbg(dev, "\nInvalid data line select"); 229 dev_dbg(ccdc_cfg.dev, "\nInvalid data line select");
224 return -1; 230 return -1;
225 } 231 }
226 } 232 }
@@ -230,7 +236,7 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
230static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params) 236static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
231{ 237{
232 struct ccdc_config_params_raw *config_params = 238 struct ccdc_config_params_raw *config_params =
233 &ccdc_hw_params_raw.config_params; 239 &ccdc_cfg.bayer.config_params;
234 unsigned int *fpc_virtaddr = NULL; 240 unsigned int *fpc_virtaddr = NULL;
235 unsigned int *fpc_physaddr = NULL; 241 unsigned int *fpc_physaddr = NULL;
236 242
@@ -266,7 +272,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
266 FP_NUM_BYTES)); 272 FP_NUM_BYTES));
267 273
268 if (fpc_virtaddr == NULL) { 274 if (fpc_virtaddr == NULL) {
269 dev_dbg(dev, 275 dev_dbg(ccdc_cfg.dev,
270 "\nUnable to allocate memory for FPC"); 276 "\nUnable to allocate memory for FPC");
271 return -EFAULT; 277 return -EFAULT;
272 } 278 }
@@ -279,7 +285,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
279 if (copy_from_user(fpc_virtaddr, 285 if (copy_from_user(fpc_virtaddr,
280 (void __user *)raw_params->fault_pxl.fpc_table_addr, 286 (void __user *)raw_params->fault_pxl.fpc_table_addr,
281 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) { 287 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
282 dev_dbg(dev, "\n copy_from_user failed"); 288 dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed");
283 return -EFAULT; 289 return -EFAULT;
284 } 290 }
285 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr; 291 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
@@ -289,7 +295,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
289static int ccdc_close(struct device *dev) 295static int ccdc_close(struct device *dev)
290{ 296{
291 struct ccdc_config_params_raw *config_params = 297 struct ccdc_config_params_raw *config_params =
292 &ccdc_hw_params_raw.config_params; 298 &ccdc_cfg.bayer.config_params;
293 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL; 299 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
294 300
295 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr; 301 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
@@ -323,9 +329,8 @@ static void ccdc_restore_defaults(void)
323 329
324static int ccdc_open(struct device *device) 330static int ccdc_open(struct device *device)
325{ 331{
326 dev = device;
327 ccdc_restore_defaults(); 332 ccdc_restore_defaults();
328 if (ccdc_if_type == VPFE_RAW_BAYER) 333 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
329 ccdc_enable_vport(1); 334 ccdc_enable_vport(1);
330 return 0; 335 return 0;
331} 336}
@@ -341,12 +346,12 @@ static int ccdc_set_params(void __user *params)
341 struct ccdc_config_params_raw ccdc_raw_params; 346 struct ccdc_config_params_raw ccdc_raw_params;
342 int x; 347 int x;
343 348
344 if (ccdc_if_type != VPFE_RAW_BAYER) 349 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
345 return -EINVAL; 350 return -EINVAL;
346 351
347 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); 352 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
348 if (x) { 353 if (x) {
349 dev_dbg(dev, "ccdc_set_params: error in copying" 354 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying"
350 "ccdc params, %d\n", x); 355 "ccdc params, %d\n", x);
351 return -EFAULT; 356 return -EFAULT;
352 } 357 }
@@ -364,10 +369,10 @@ static int ccdc_set_params(void __user *params)
364 */ 369 */
365void ccdc_config_ycbcr(void) 370void ccdc_config_ycbcr(void)
366{ 371{
367 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; 372 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
368 u32 syn_mode; 373 u32 syn_mode;
369 374
370 dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); 375 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
371 /* 376 /*
372 * first restore the CCDC registers to default values 377 * first restore the CCDC registers to default values
373 * This is important since we assume default values to be set in 378 * This is important since we assume default values to be set in
@@ -428,7 +433,7 @@ void ccdc_config_ycbcr(void)
428 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST); 433 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
429 434
430 ccdc_sbl_reset(); 435 ccdc_sbl_reset();
431 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); 436 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
432 ccdc_readregs(); 437 ccdc_readregs();
433} 438}
434 439
@@ -440,9 +445,9 @@ static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
440 /* configure DCSub */ 445 /* configure DCSub */
441 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK; 446 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
442 regw(val, CCDC_DCSUB); 447 regw(val, CCDC_DCSUB);
443 dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val); 448 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
444 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP); 449 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
445 dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n"); 450 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
446 return; 451 return;
447 } 452 }
448 /* 453 /*
@@ -457,10 +462,10 @@ static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
457 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) << 462 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
458 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE); 463 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
459 regw(val, CCDC_CLAMP); 464 regw(val, CCDC_CLAMP);
460 dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val); 465 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
461 /* If Black clamping is enable then make dcsub 0 */ 466 /* If Black clamping is enable then make dcsub 0 */
462 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB); 467 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
463 dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n"); 468 dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
464} 469}
465 470
466static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp) 471static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
@@ -490,17 +495,17 @@ static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
490 495
491 /* Configure Fault pixel if needed */ 496 /* Configure Fault pixel if needed */
492 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR); 497 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
493 dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n", 498 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC_ADDR...\n",
494 (fpc->fpc_table_addr)); 499 (fpc->fpc_table_addr));
495 /* Write the FPC params with FPC disable */ 500 /* Write the FPC params with FPC disable */
496 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK; 501 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
497 regw(val, CCDC_FPC); 502 regw(val, CCDC_FPC);
498 503
499 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val); 504 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
500 /* read the FPC register */ 505 /* read the FPC register */
501 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE; 506 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
502 regw(val, CCDC_FPC); 507 regw(val, CCDC_FPC);
503 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val); 508 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
504} 509}
505 510
506/* 511/*
@@ -509,13 +514,13 @@ static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
509 */ 514 */
510void ccdc_config_raw(void) 515void ccdc_config_raw(void)
511{ 516{
512 struct ccdc_params_raw *params = &ccdc_hw_params_raw; 517 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
513 struct ccdc_config_params_raw *config_params = 518 struct ccdc_config_params_raw *config_params =
514 &ccdc_hw_params_raw.config_params; 519 &ccdc_cfg.bayer.config_params;
515 unsigned int syn_mode = 0; 520 unsigned int syn_mode = 0;
516 unsigned int val; 521 unsigned int val;
517 522
518 dev_dbg(dev, "\nStarting ccdc_config_raw..."); 523 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
519 524
520 /* Reset CCDC */ 525 /* Reset CCDC */
521 ccdc_restore_defaults(); 526 ccdc_restore_defaults();
@@ -545,7 +550,7 @@ void ccdc_config_raw(void)
545 val = ((config_params->alaw.gama_wd & 550 val = ((config_params->alaw.gama_wd &
546 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE); 551 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
547 regw(val, CCDC_ALAW); 552 regw(val, CCDC_ALAW);
548 dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val); 553 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
549 } 554 }
550 555
551 /* Configure video window */ 556 /* Configure video window */
@@ -582,11 +587,11 @@ void ccdc_config_raw(void)
582 /* Write value in FMTCFG */ 587 /* Write value in FMTCFG */
583 regw(val, CCDC_FMTCFG); 588 regw(val, CCDC_FMTCFG);
584 589
585 dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val); 590 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
586 /* Configure the color pattern according to mt9t001 sensor */ 591 /* Configure the color pattern according to mt9t001 sensor */
587 regw(CCDC_COLPTN_VAL, CCDC_COLPTN); 592 regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
588 593
589 dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n"); 594 dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
590 /* 595 /*
591 * Configure Data formatter(Video port) pixel selection 596 * Configure Data formatter(Video port) pixel selection
592 * (FMT_HORZ, FMT_VERT) 597 * (FMT_HORZ, FMT_VERT)
@@ -596,7 +601,7 @@ void ccdc_config_raw(void)
596 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK); 601 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
597 regw(val, CCDC_FMT_HORZ); 602 regw(val, CCDC_FMT_HORZ);
598 603
599 dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val); 604 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
600 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK) 605 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
601 << CCDC_FMT_VERT_FMTSLV_SHIFT; 606 << CCDC_FMT_VERT_FMTSLV_SHIFT;
602 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) 607 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
@@ -604,13 +609,13 @@ void ccdc_config_raw(void)
604 else 609 else
605 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK; 610 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
606 611
607 dev_dbg(dev, "\nparams->win.height 0x%x ...\n", 612 dev_dbg(ccdc_cfg.dev, "\nparams->win.height 0x%x ...\n",
608 params->win.height); 613 params->win.height);
609 regw(val, CCDC_FMT_VERT); 614 regw(val, CCDC_FMT_VERT);
610 615
611 dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val); 616 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
612 617
613 dev_dbg(dev, "\nbelow regw(val, FMT_VERT)..."); 618 dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
614 619
615 /* 620 /*
616 * Configure Horizontal offset register. If pack 8 is enabled then 621 * Configure Horizontal offset register. If pack 8 is enabled then
@@ -631,17 +636,17 @@ void ccdc_config_raw(void)
631 if (params->image_invert_enable) { 636 if (params->image_invert_enable) {
632 /* For intelace inverse mode */ 637 /* For intelace inverse mode */
633 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST); 638 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
634 dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n"); 639 dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
635 } 640 }
636 641
637 else { 642 else {
638 /* For intelace non inverse mode */ 643 /* For intelace non inverse mode */
639 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST); 644 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
640 dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n"); 645 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
641 } 646 }
642 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { 647 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
643 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST); 648 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
644 dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n"); 649 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to SDOFST...\n");
645 } 650 }
646 651
647 /* 652 /*
@@ -662,18 +667,18 @@ void ccdc_config_raw(void)
662 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK; 667 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
663 regw(val, CCDC_VP_OUT); 668 regw(val, CCDC_VP_OUT);
664 669
665 dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val); 670 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
666 regw(syn_mode, CCDC_SYN_MODE); 671 regw(syn_mode, CCDC_SYN_MODE);
667 dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode); 672 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
668 673
669 ccdc_sbl_reset(); 674 ccdc_sbl_reset();
670 dev_dbg(dev, "\nend of ccdc_config_raw..."); 675 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
671 ccdc_readregs(); 676 ccdc_readregs();
672} 677}
673 678
674static int ccdc_configure(void) 679static int ccdc_configure(void)
675{ 680{
676 if (ccdc_if_type == VPFE_RAW_BAYER) 681 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
677 ccdc_config_raw(); 682 ccdc_config_raw();
678 else 683 else
679 ccdc_config_ycbcr(); 684 ccdc_config_ycbcr();
@@ -682,24 +687,24 @@ static int ccdc_configure(void)
682 687
683static int ccdc_set_buftype(enum ccdc_buftype buf_type) 688static int ccdc_set_buftype(enum ccdc_buftype buf_type)
684{ 689{
685 if (ccdc_if_type == VPFE_RAW_BAYER) 690 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
686 ccdc_hw_params_raw.buf_type = buf_type; 691 ccdc_cfg.bayer.buf_type = buf_type;
687 else 692 else
688 ccdc_hw_params_ycbcr.buf_type = buf_type; 693 ccdc_cfg.ycbcr.buf_type = buf_type;
689 return 0; 694 return 0;
690} 695}
691 696
692static enum ccdc_buftype ccdc_get_buftype(void) 697static enum ccdc_buftype ccdc_get_buftype(void)
693{ 698{
694 if (ccdc_if_type == VPFE_RAW_BAYER) 699 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
695 return ccdc_hw_params_raw.buf_type; 700 return ccdc_cfg.bayer.buf_type;
696 return ccdc_hw_params_ycbcr.buf_type; 701 return ccdc_cfg.ycbcr.buf_type;
697} 702}
698 703
699static int ccdc_enum_pix(u32 *pix, int i) 704static int ccdc_enum_pix(u32 *pix, int i)
700{ 705{
701 int ret = -EINVAL; 706 int ret = -EINVAL;
702 if (ccdc_if_type == VPFE_RAW_BAYER) { 707 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
703 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { 708 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
704 *pix = ccdc_raw_bayer_pix_formats[i]; 709 *pix = ccdc_raw_bayer_pix_formats[i];
705 ret = 0; 710 ret = 0;
@@ -715,17 +720,17 @@ static int ccdc_enum_pix(u32 *pix, int i)
715 720
716static int ccdc_set_pixel_format(u32 pixfmt) 721static int ccdc_set_pixel_format(u32 pixfmt)
717{ 722{
718 if (ccdc_if_type == VPFE_RAW_BAYER) { 723 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
719 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; 724 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
720 if (pixfmt == V4L2_PIX_FMT_SBGGR8) 725 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
721 ccdc_hw_params_raw.config_params.alaw.enable = 1; 726 ccdc_cfg.bayer.config_params.alaw.enable = 1;
722 else if (pixfmt != V4L2_PIX_FMT_SBGGR16) 727 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
723 return -EINVAL; 728 return -EINVAL;
724 } else { 729 } else {
725 if (pixfmt == V4L2_PIX_FMT_YUYV) 730 if (pixfmt == V4L2_PIX_FMT_YUYV)
726 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; 731 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
727 else if (pixfmt == V4L2_PIX_FMT_UYVY) 732 else if (pixfmt == V4L2_PIX_FMT_UYVY)
728 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; 733 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
729 else 734 else
730 return -EINVAL; 735 return -EINVAL;
731 } 736 }
@@ -734,17 +739,16 @@ static int ccdc_set_pixel_format(u32 pixfmt)
734 739
735static u32 ccdc_get_pixel_format(void) 740static u32 ccdc_get_pixel_format(void)
736{ 741{
737 struct ccdc_a_law *alaw = 742 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
738 &ccdc_hw_params_raw.config_params.alaw;
739 u32 pixfmt; 743 u32 pixfmt;
740 744
741 if (ccdc_if_type == VPFE_RAW_BAYER) 745 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
742 if (alaw->enable) 746 if (alaw->enable)
743 pixfmt = V4L2_PIX_FMT_SBGGR8; 747 pixfmt = V4L2_PIX_FMT_SBGGR8;
744 else 748 else
745 pixfmt = V4L2_PIX_FMT_SBGGR16; 749 pixfmt = V4L2_PIX_FMT_SBGGR16;
746 else { 750 else {
747 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) 751 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
748 pixfmt = V4L2_PIX_FMT_YUYV; 752 pixfmt = V4L2_PIX_FMT_YUYV;
749 else 753 else
750 pixfmt = V4L2_PIX_FMT_UYVY; 754 pixfmt = V4L2_PIX_FMT_UYVY;
@@ -754,53 +758,53 @@ static u32 ccdc_get_pixel_format(void)
754 758
755static int ccdc_set_image_window(struct v4l2_rect *win) 759static int ccdc_set_image_window(struct v4l2_rect *win)
756{ 760{
757 if (ccdc_if_type == VPFE_RAW_BAYER) 761 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
758 ccdc_hw_params_raw.win = *win; 762 ccdc_cfg.bayer.win = *win;
759 else 763 else
760 ccdc_hw_params_ycbcr.win = *win; 764 ccdc_cfg.ycbcr.win = *win;
761 return 0; 765 return 0;
762} 766}
763 767
764static void ccdc_get_image_window(struct v4l2_rect *win) 768static void ccdc_get_image_window(struct v4l2_rect *win)
765{ 769{
766 if (ccdc_if_type == VPFE_RAW_BAYER) 770 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
767 *win = ccdc_hw_params_raw.win; 771 *win = ccdc_cfg.bayer.win;
768 else 772 else
769 *win = ccdc_hw_params_ycbcr.win; 773 *win = ccdc_cfg.ycbcr.win;
770} 774}
771 775
772static unsigned int ccdc_get_line_length(void) 776static unsigned int ccdc_get_line_length(void)
773{ 777{
774 struct ccdc_config_params_raw *config_params = 778 struct ccdc_config_params_raw *config_params =
775 &ccdc_hw_params_raw.config_params; 779 &ccdc_cfg.bayer.config_params;
776 unsigned int len; 780 unsigned int len;
777 781
778 if (ccdc_if_type == VPFE_RAW_BAYER) { 782 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
779 if ((config_params->alaw.enable) || 783 if ((config_params->alaw.enable) ||
780 (config_params->data_sz == CCDC_DATA_8BITS)) 784 (config_params->data_sz == CCDC_DATA_8BITS))
781 len = ccdc_hw_params_raw.win.width; 785 len = ccdc_cfg.bayer.win.width;
782 else 786 else
783 len = ccdc_hw_params_raw.win.width * 2; 787 len = ccdc_cfg.bayer.win.width * 2;
784 } else 788 } else
785 len = ccdc_hw_params_ycbcr.win.width * 2; 789 len = ccdc_cfg.ycbcr.win.width * 2;
786 return ALIGN(len, 32); 790 return ALIGN(len, 32);
787} 791}
788 792
789static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) 793static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
790{ 794{
791 if (ccdc_if_type == VPFE_RAW_BAYER) 795 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
792 ccdc_hw_params_raw.frm_fmt = frm_fmt; 796 ccdc_cfg.bayer.frm_fmt = frm_fmt;
793 else 797 else
794 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; 798 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
795 return 0; 799 return 0;
796} 800}
797 801
798static enum ccdc_frmfmt ccdc_get_frame_format(void) 802static enum ccdc_frmfmt ccdc_get_frame_format(void)
799{ 803{
800 if (ccdc_if_type == VPFE_RAW_BAYER) 804 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
801 return ccdc_hw_params_raw.frm_fmt; 805 return ccdc_cfg.bayer.frm_fmt;
802 else 806 else
803 return ccdc_hw_params_ycbcr.frm_fmt; 807 return ccdc_cfg.ycbcr.frm_fmt;
804} 808}
805 809
806static int ccdc_getfid(void) 810static int ccdc_getfid(void)
@@ -816,14 +820,14 @@ static inline void ccdc_setfbaddr(unsigned long addr)
816 820
817static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) 821static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
818{ 822{
819 ccdc_if_type = params->if_type; 823 ccdc_cfg.if_type = params->if_type;
820 824
821 switch (params->if_type) { 825 switch (params->if_type) {
822 case VPFE_BT656: 826 case VPFE_BT656:
823 case VPFE_YCBCR_SYNC_16: 827 case VPFE_YCBCR_SYNC_16:
824 case VPFE_YCBCR_SYNC_8: 828 case VPFE_YCBCR_SYNC_8:
825 ccdc_hw_params_ycbcr.vd_pol = params->vdpol; 829 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
826 ccdc_hw_params_ycbcr.hd_pol = params->hdpol; 830 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
827 break; 831 break;
828 default: 832 default:
829 /* TODO add support for raw bayer here */ 833 /* TODO add support for raw bayer here */
@@ -838,7 +842,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
838 .hw_ops = { 842 .hw_ops = {
839 .open = ccdc_open, 843 .open = ccdc_open,
840 .close = ccdc_close, 844 .close = ccdc_close,
841 .set_ccdc_base = ccdc_set_ccdc_base,
842 .reset = ccdc_sbl_reset, 845 .reset = ccdc_sbl_reset,
843 .enable = ccdc_enable, 846 .enable = ccdc_enable,
844 .set_hw_if_params = ccdc_set_hw_if_params, 847 .set_hw_if_params = ccdc_set_hw_if_params,
@@ -859,19 +862,105 @@ static struct ccdc_hw_device ccdc_hw_dev = {
859 }, 862 },
860}; 863};
861 864
862static int __init dm644x_ccdc_init(void) 865static int __init dm644x_ccdc_probe(struct platform_device *pdev)
863{ 866{
864 printk(KERN_NOTICE "dm644x_ccdc_init\n"); 867 struct resource *res;
865 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) 868 int status = 0;
866 return -1; 869
867 printk(KERN_NOTICE "%s is registered with vpfe.\n", 870 /*
868 ccdc_hw_dev.name); 871 * first try to register with vpfe. If not correct platform, then we
872 * don't have to iomap
873 */
874 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
875 if (status < 0)
876 return status;
877
878 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
879 if (!res) {
880 status = -ENODEV;
881 goto fail_nores;
882 }
883
884 res = request_mem_region(res->start, resource_size(res), res->name);
885 if (!res) {
886 status = -EBUSY;
887 goto fail_nores;
888 }
889
890 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
891 if (!ccdc_cfg.base_addr) {
892 status = -ENOMEM;
893 goto fail_nomem;
894 }
895
896 /* Get and enable Master clock */
897 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
898 if (IS_ERR(ccdc_cfg.mclk)) {
899 status = PTR_ERR(ccdc_cfg.mclk);
900 goto fail_nomap;
901 }
902 if (clk_enable(ccdc_cfg.mclk)) {
903 status = -ENODEV;
904 goto fail_mclk;
905 }
906
907 /* Get and enable Slave clock */
908 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
909 if (IS_ERR(ccdc_cfg.sclk)) {
910 status = PTR_ERR(ccdc_cfg.sclk);
911 goto fail_mclk;
912 }
913 if (clk_enable(ccdc_cfg.sclk)) {
914 status = -ENODEV;
915 goto fail_sclk;
916 }
917 ccdc_cfg.dev = &pdev->dev;
918 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
869 return 0; 919 return 0;
920fail_sclk:
921 clk_put(ccdc_cfg.sclk);
922fail_mclk:
923 clk_put(ccdc_cfg.mclk);
924fail_nomap:
925 iounmap(ccdc_cfg.base_addr);
926fail_nomem:
927 release_mem_region(res->start, resource_size(res));
928fail_nores:
929 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
930 return status;
870} 931}
871 932
872static void __exit dm644x_ccdc_exit(void) 933static int dm644x_ccdc_remove(struct platform_device *pdev)
873{ 934{
935 struct resource *res;
936
937 clk_put(ccdc_cfg.mclk);
938 clk_put(ccdc_cfg.sclk);
939 iounmap(ccdc_cfg.base_addr);
940 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
941 if (res)
942 release_mem_region(res->start, resource_size(res));
874 vpfe_unregister_ccdc_device(&ccdc_hw_dev); 943 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
944 return 0;
945}
946
947static struct platform_driver dm644x_ccdc_driver = {
948 .driver = {
949 .name = "dm644x_ccdc",
950 .owner = THIS_MODULE,
951 },
952 .remove = __devexit_p(dm644x_ccdc_remove),
953 .probe = dm644x_ccdc_probe,
954};
955
956static int __init dm644x_ccdc_init(void)
957{
958 return platform_driver_register(&dm644x_ccdc_driver);
959}
960
961static void __exit dm644x_ccdc_exit(void)
962{
963 platform_driver_unregister(&dm644x_ccdc_driver);
875} 964}
876 965
877module_init(dm644x_ccdc_init); 966module_init(dm644x_ccdc_init);
diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/video/davinci/isif.c
new file mode 100644
index 000000000000..29c29c668596
--- /dev/null
+++ b/drivers/media/video/davinci/isif.c
@@ -0,0 +1,1172 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Image Sensor Interface (ISIF) driver
19 *
20 * This driver is for configuring the ISIF IP available on DM365 or any other
21 * TI SoCs. This is used for capturing yuv or bayer video or image data
22 * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
23 * and DM6446, but with enhanced or additional ip blocks. The driver
24 * configures the ISIF upon commands from the vpfe bridge driver through
25 * ccdc_hw_device interface.
26 *
27 * TODO: 1) Raw bayer parameter settings and bayer capture
28 * 2) Add support for control ioctl
29 */
30#include <linux/delay.h>
31#include <linux/platform_device.h>
32#include <linux/uaccess.h>
33#include <linux/io.h>
34#include <linux/videodev2.h>
35#include <linux/clk.h>
36#include <linux/err.h>
37
38#include <mach/mux.h>
39
40#include <media/davinci/isif.h>
41#include <media/davinci/vpss.h>
42
43#include "isif_regs.h"
44#include "ccdc_hw_device.h"
45
46/* Defaults for module configuration parameters */
47static struct isif_config_params_raw isif_config_defaults = {
48 .linearize = {
49 .en = 0,
50 .corr_shft = ISIF_NO_SHIFT,
51 .scale_fact = {1, 0},
52 },
53 .df_csc = {
54 .df_or_csc = 0,
55 .csc = {
56 .en = 0,
57 },
58 },
59 .dfc = {
60 .en = 0,
61 },
62 .bclamp = {
63 .en = 0,
64 },
65 .gain_offset = {
66 .gain = {
67 .r_ye = {1, 0},
68 .gr_cy = {1, 0},
69 .gb_g = {1, 0},
70 .b_mg = {1, 0},
71 },
72 },
73 .culling = {
74 .hcpat_odd = 0xff,
75 .hcpat_even = 0xff,
76 .vcpat = 0xff,
77 },
78 .compress = {
79 .alg = ISIF_ALAW,
80 },
81};
82
83/* ISIF operation configuration */
84static struct isif_oper_config {
85 struct device *dev;
86 enum vpfe_hw_if_type if_type;
87 struct isif_ycbcr_config ycbcr;
88 struct isif_params_raw bayer;
89 enum isif_data_pack data_pack;
90 /* Master clock */
91 struct clk *mclk;
92 /* ISIF base address */
93 void __iomem *base_addr;
94 /* ISIF Linear Table 0 */
95 void __iomem *linear_tbl0_addr;
96 /* ISIF Linear Table 1 */
97 void __iomem *linear_tbl1_addr;
98} isif_cfg = {
99 .ycbcr = {
100 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
101 .frm_fmt = CCDC_FRMFMT_INTERLACED,
102 .win = ISIF_WIN_NTSC,
103 .fid_pol = VPFE_PINPOL_POSITIVE,
104 .vd_pol = VPFE_PINPOL_POSITIVE,
105 .hd_pol = VPFE_PINPOL_POSITIVE,
106 .pix_order = CCDC_PIXORDER_CBYCRY,
107 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
108 },
109 .bayer = {
110 .pix_fmt = CCDC_PIXFMT_RAW,
111 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
112 .win = ISIF_WIN_VGA,
113 .fid_pol = VPFE_PINPOL_POSITIVE,
114 .vd_pol = VPFE_PINPOL_POSITIVE,
115 .hd_pol = VPFE_PINPOL_POSITIVE,
116 .gain = {
117 .r_ye = {1, 0},
118 .gr_cy = {1, 0},
119 .gb_g = {1, 0},
120 .b_mg = {1, 0},
121 },
122 .cfa_pat = ISIF_CFA_PAT_MOSAIC,
123 .data_msb = ISIF_BIT_MSB_11,
124 .config_params = {
125 .data_shift = ISIF_NO_SHIFT,
126 .col_pat_field0 = {
127 .olop = ISIF_GREEN_BLUE,
128 .olep = ISIF_BLUE,
129 .elop = ISIF_RED,
130 .elep = ISIF_GREEN_RED,
131 },
132 .col_pat_field1 = {
133 .olop = ISIF_GREEN_BLUE,
134 .olep = ISIF_BLUE,
135 .elop = ISIF_RED,
136 .elep = ISIF_GREEN_RED,
137 },
138 .test_pat_gen = 0,
139 },
140 },
141 .data_pack = ISIF_DATA_PACK8,
142};
143
144/* Raw Bayer formats */
145static const u32 isif_raw_bayer_pix_formats[] = {
146 V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
147
148/* Raw YUV formats */
149static const u32 isif_raw_yuv_pix_formats[] = {
150 V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
151
152/* register access routines */
153static inline u32 regr(u32 offset)
154{
155 return __raw_readl(isif_cfg.base_addr + offset);
156}
157
158static inline void regw(u32 val, u32 offset)
159{
160 __raw_writel(val, isif_cfg.base_addr + offset);
161}
162
163/* reg_modify() - read, modify and write register */
164static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
165{
166 u32 new_val = (regr(offset) & ~mask) | (val & mask);
167
168 regw(new_val, offset);
169 return new_val;
170}
171
172static inline void regw_lin_tbl(u32 val, u32 offset, int i)
173{
174 if (!i)
175 __raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
176 else
177 __raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
178}
179
180static void isif_disable_all_modules(void)
181{
182 /* disable BC */
183 regw(0, CLAMPCFG);
184 /* disable vdfc */
185 regw(0, DFCCTL);
186 /* disable CSC */
187 regw(0, CSCCTL);
188 /* disable linearization */
189 regw(0, LINCFG0);
190 /* disable other modules here as they are supported */
191}
192
193static void isif_enable(int en)
194{
195 if (!en) {
196 /* Before disable isif, disable all ISIF modules */
197 isif_disable_all_modules();
198 /*
199 * wait for next VD. Assume lowest scan rate is 12 Hz. So
200 * 100 msec delay is good enough
201 */
202 msleep(100);
203 }
204 reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
205}
206
207static void isif_enable_output_to_sdram(int en)
208{
209 reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
210}
211
212static void isif_config_culling(struct isif_cul *cul)
213{
214 u32 val;
215
216 /* Horizontal pattern */
217 val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
218 regw(val, CULH);
219
220 /* vertical pattern */
221 regw(cul->vcpat, CULV);
222
223 /* LPF */
224 reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
225 cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
226}
227
228static void isif_config_gain_offset(void)
229{
230 struct isif_gain_offsets_adj *gain_off_p =
231 &isif_cfg.bayer.config_params.gain_offset;
232 u32 val;
233
234 val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
235 (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
236 (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
237 (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
238 (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
239 (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
240
241 reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
242
243 val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
244 gain_off_p->gain.r_ye.decimal;
245 regw(val, CRGAIN);
246
247 val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
248 gain_off_p->gain.gr_cy.decimal;
249 regw(val, CGRGAIN);
250
251 val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
252 gain_off_p->gain.gb_g.decimal;
253 regw(val, CGBGAIN);
254
255 val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
256 gain_off_p->gain.b_mg.decimal;
257 regw(val, CBGAIN);
258
259 regw(gain_off_p->offset, COFSTA);
260}
261
262static void isif_restore_defaults(void)
263{
264 enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
265
266 dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
267 isif_cfg.bayer.config_params = isif_config_defaults;
268 /* Enable clock to ISIF, IPIPEIF and BL */
269 vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
270 vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
271 vpss_enable_clock(VPSS_BL_CLOCK, 1);
272 /* Set default offset and gain */
273 isif_config_gain_offset();
274 vpss_select_ccdc_source(source);
275 dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
276}
277
278static int isif_open(struct device *device)
279{
280 isif_restore_defaults();
281 return 0;
282}
283
284/* This function will configure the window size to be capture in ISIF reg */
285static void isif_setwin(struct v4l2_rect *image_win,
286 enum ccdc_frmfmt frm_fmt, int ppc)
287{
288 int horz_start, horz_nr_pixels;
289 int vert_start, vert_nr_lines;
290 int mid_img = 0;
291
292 dev_dbg(isif_cfg.dev, "\nStarting isif_setwin...");
293 /*
294 * ppc - per pixel count. indicates how many pixels per cell
295 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
296 * raw capture this is 1
297 */
298 horz_start = image_win->left << (ppc - 1);
299 horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
300
301 /* Writing the horizontal info into the registers */
302 regw(horz_start & START_PX_HOR_MASK, SPH);
303 regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
304 vert_start = image_win->top;
305
306 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
307 vert_nr_lines = (image_win->height >> 1) - 1;
308 vert_start >>= 1;
309 /* To account for VD since line 0 doesn't have any data */
310 vert_start += 1;
311 } else {
312 /* To account for VD since line 0 doesn't have any data */
313 vert_start += 1;
314 vert_nr_lines = image_win->height - 1;
315 /* configure VDINT0 and VDINT1 */
316 mid_img = vert_start + (image_win->height / 2);
317 regw(mid_img, VDINT1);
318 }
319
320 regw(0, VDINT0);
321 regw(vert_start & START_VER_ONE_MASK, SLV0);
322 regw(vert_start & START_VER_TWO_MASK, SLV1);
323 regw(vert_nr_lines & NUM_LINES_VER, LNV);
324}
325
326static void isif_config_bclamp(struct isif_black_clamp *bc)
327{
328 u32 val;
329
330 /*
331 * DC Offset is always added to image data irrespective of bc enable
332 * status
333 */
334 regw(bc->dc_offset, CLDCOFST);
335
336 if (bc->en) {
337 val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
338
339 /* Enable BC and horizontal clamp caculation paramaters */
340 val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
341
342 regw(val, CLAMPCFG);
343
344 if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
345 /*
346 * Window count for calculation
347 * Base window selection
348 * pixel limit
349 * Horizontal size of window
350 * vertical size of the window
351 * Horizontal start position of the window
352 * Vertical start position of the window
353 */
354 val = bc->horz.win_count_calc |
355 ((!!bc->horz.base_win_sel_calc) <<
356 ISIF_HORZ_BC_WIN_SEL_SHIFT) |
357 ((!!bc->horz.clamp_pix_limit) <<
358 ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
359 (bc->horz.win_h_sz_calc <<
360 ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
361 (bc->horz.win_v_sz_calc <<
362 ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
363 regw(val, CLHWIN0);
364
365 regw(bc->horz.win_start_h_calc, CLHWIN1);
366 regw(bc->horz.win_start_v_calc, CLHWIN2);
367 }
368
369 /* vertical clamp caculation paramaters */
370
371 /* Reset clamp value sel for previous line */
372 val |=
373 (bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
374 (bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
375 regw(val, CLVWIN0);
376
377 /* Optical Black horizontal start position */
378 regw(bc->vert.ob_start_h, CLVWIN1);
379 /* Optical Black vertical start position */
380 regw(bc->vert.ob_start_v, CLVWIN2);
381 /* Optical Black vertical size for calculation */
382 regw(bc->vert.ob_v_sz_calc, CLVWIN3);
383 /* Vertical start position for BC subtraction */
384 regw(bc->vert_start_sub, CLSV);
385 }
386}
387
388static void isif_config_linearization(struct isif_linearize *linearize)
389{
390 u32 val, i;
391
392 if (!linearize->en) {
393 regw(0, LINCFG0);
394 return;
395 }
396
397 /* shift value for correction & enable linearization (set lsb) */
398 val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
399 regw(val, LINCFG0);
400
401 /* Scale factor */
402 val = ((!!linearize->scale_fact.integer) <<
403 ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
404 linearize->scale_fact.decimal;
405 regw(val, LINCFG1);
406
407 for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
408 if (i % 2)
409 regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
410 else
411 regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
412 }
413}
414
415static int isif_config_dfc(struct isif_dfc *vdfc)
416{
417 /* initialize retries to loop for max ~ 250 usec */
418 u32 val, count, retries = loops_per_jiffy / (4000/HZ);
419 int i;
420
421 if (!vdfc->en)
422 return 0;
423
424 /* Correction mode */
425 val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
426
427 /* Correct whole line or partial */
428 if (vdfc->corr_whole_line)
429 val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
430
431 /* level shift value */
432 val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
433
434 regw(val, DFCCTL);
435
436 /* Defect saturation level */
437 regw(vdfc->def_sat_level, VDFSATLV);
438
439 regw(vdfc->table[0].pos_vert, DFCMEM0);
440 regw(vdfc->table[0].pos_horz, DFCMEM1);
441 if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
442 vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
443 regw(vdfc->table[0].level_at_pos, DFCMEM2);
444 regw(vdfc->table[0].level_up_pixels, DFCMEM3);
445 regw(vdfc->table[0].level_low_pixels, DFCMEM4);
446 }
447
448 /* set DFCMARST and set DFCMWR */
449 val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
450 regw(val, DFCMEMCTL);
451
452 count = retries;
453 while (count && (regr(DFCMEMCTL) & 0x1))
454 count--;
455
456 if (!count) {
457 dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
458 return -1;
459 }
460
461 for (i = 1; i < vdfc->num_vdefects; i++) {
462 regw(vdfc->table[i].pos_vert, DFCMEM0);
463 regw(vdfc->table[i].pos_horz, DFCMEM1);
464 if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
465 vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
466 regw(vdfc->table[i].level_at_pos, DFCMEM2);
467 regw(vdfc->table[i].level_up_pixels, DFCMEM3);
468 regw(vdfc->table[i].level_low_pixels, DFCMEM4);
469 }
470 val = regr(DFCMEMCTL);
471 /* clear DFCMARST and set DFCMWR */
472 val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
473 val |= 1;
474 regw(val, DFCMEMCTL);
475
476 count = retries;
477 while (count && (regr(DFCMEMCTL) & 0x1))
478 count--;
479
480 if (!count) {
481 dev_err(isif_cfg.dev,
482 "defect table write timeout !!!\n");
483 return -1;
484 }
485 }
486 if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
487 /* Extra cycle needed */
488 regw(0, DFCMEM0);
489 regw(0x1FFF, DFCMEM1);
490 regw(1, DFCMEMCTL);
491 }
492
493 /* enable VDFC */
494 reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
495 DFCCTL);
496 return 0;
497}
498
499static void isif_config_csc(struct isif_df_csc *df_csc)
500{
501 u32 val1 = 0, val2 = 0, i;
502
503 if (!df_csc->csc.en) {
504 regw(0, CSCCTL);
505 return;
506 }
507 for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
508 if ((i % 2) == 0) {
509 /* CSCM - LSB */
510 val1 = (df_csc->csc.coeff[i].integer <<
511 ISIF_CSC_COEF_INTEG_SHIFT) |
512 df_csc->csc.coeff[i].decimal;
513 } else {
514
515 /* CSCM - MSB */
516 val2 = (df_csc->csc.coeff[i].integer <<
517 ISIF_CSC_COEF_INTEG_SHIFT) |
518 df_csc->csc.coeff[i].decimal;
519 val2 <<= ISIF_CSCM_MSB_SHIFT;
520 val2 |= val1;
521 regw(val2, (CSCM0 + ((i - 1) << 1)));
522 }
523 }
524
525 /* program the active area */
526 regw(df_csc->start_pix, FMTSPH);
527 /*
528 * one extra pixel as required for CSC. Actually number of
529 * pixel - 1 should be configured in this register. So we
530 * need to subtract 1 before writing to FMTSPH, but we will
531 * not do this since csc requires one extra pixel
532 */
533 regw(df_csc->num_pixels, FMTLNH);
534 regw(df_csc->start_line, FMTSLV);
535 /*
536 * one extra line as required for CSC. See reason documented for
537 * num_pixels
538 */
539 regw(df_csc->num_lines, FMTLNV);
540
541 /* Enable CSC */
542 regw(1, CSCCTL);
543}
544
545static int isif_config_raw(void)
546{
547 struct isif_params_raw *params = &isif_cfg.bayer;
548 struct isif_config_params_raw *module_params =
549 &isif_cfg.bayer.config_params;
550 struct vpss_pg_frame_size frame_size;
551 struct vpss_sync_pol sync;
552 u32 val;
553
554 dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
555
556 /*
557 * Configure CCDCFG register:-
558 * Set CCD Not to swap input since input is RAW data
559 * Set FID detection function to Latch at V-Sync
560 * Set WENLOG - isif valid area
561 * Set TRGSEL
562 * Set EXTRG
563 * Packed to 8 or 16 bits
564 */
565
566 val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
567 ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
568 ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
569
570 dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
571 regw(val, CCDCFG);
572
573 /*
574 * Configure the vertical sync polarity(MODESET.VDPOL)
575 * Configure the horizontal sync polarity (MODESET.HDPOL)
576 * Configure frame id polarity (MODESET.FLDPOL)
577 * Configure data polarity
578 * Configure External WEN Selection
579 * Configure frame format(progressive or interlace)
580 * Configure pixel format (Input mode)
581 * Configure the data shift
582 */
583
584 val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
585 (params->hd_pol << ISIF_HD_POL_SHIFT) |
586 (params->fid_pol << ISIF_FID_POL_SHIFT) |
587 (ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
588 (ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
589 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
590 (params->pix_fmt << ISIF_INPUT_SHIFT) |
591 (params->config_params.data_shift << ISIF_DATASFT_SHIFT);
592
593 regw(val, MODESET);
594 dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
595
596 /*
597 * Configure GAMMAWD register
598 * CFA pattern setting
599 */
600 val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
601
602 /* Gamma msb */
603 if (module_params->compress.alg == ISIF_ALAW)
604 val |= ISIF_ALAW_ENABLE;
605
606 val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
607 regw(val, CGAMMAWD);
608
609 /* Configure DPCM compression settings */
610 if (module_params->compress.alg == ISIF_DPCM) {
611 val = BIT(ISIF_DPCM_EN_SHIFT) |
612 (module_params->compress.pred <<
613 ISIF_DPCM_PREDICTOR_SHIFT);
614 }
615
616 regw(val, MISC);
617
618 /* Configure Gain & Offset */
619 isif_config_gain_offset();
620
621 /* Configure Color pattern */
622 val = (params->config_params.col_pat_field0.olop) |
623 (params->config_params.col_pat_field0.olep << 2) |
624 (params->config_params.col_pat_field0.elop << 4) |
625 (params->config_params.col_pat_field0.elep << 6) |
626 (params->config_params.col_pat_field1.olop << 8) |
627 (params->config_params.col_pat_field1.olep << 10) |
628 (params->config_params.col_pat_field1.elop << 12) |
629 (params->config_params.col_pat_field1.elep << 14);
630 regw(val, CCOLP);
631 dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
632
633 /* Configure HSIZE register */
634 val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
635
636 /* calculate line offset in 32 bytes based on pack value */
637 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
638 val |= ((params->win.width + 31) >> 5);
639 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
640 val |= (((params->win.width +
641 (params->win.width >> 2)) + 31) >> 5);
642 else
643 val |= (((params->win.width * 2) + 31) >> 5);
644 regw(val, HSIZE);
645
646 /* Configure SDOFST register */
647 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
648 if (params->image_invert_en) {
649 /* For interlace inverse mode */
650 regw(0x4B6D, SDOFST);
651 dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
652 } else {
653 /* For interlace non inverse mode */
654 regw(0x0B6D, SDOFST);
655 dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
656 }
657 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
658 if (params->image_invert_en) {
659 /* For progressive inverse mode */
660 regw(0x4000, SDOFST);
661 dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
662 } else {
663 /* For progressive non inverse mode */
664 regw(0x0000, SDOFST);
665 dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
666 }
667 }
668
669 /* Configure video window */
670 isif_setwin(&params->win, params->frm_fmt, 1);
671
672 /* Configure Black Clamp */
673 isif_config_bclamp(&module_params->bclamp);
674
675 /* Configure Vertical Defection Pixel Correction */
676 if (isif_config_dfc(&module_params->dfc) < 0)
677 return -EFAULT;
678
679 if (!module_params->df_csc.df_or_csc)
680 /* Configure Color Space Conversion */
681 isif_config_csc(&module_params->df_csc);
682
683 isif_config_linearization(&module_params->linearize);
684
685 /* Configure Culling */
686 isif_config_culling(&module_params->culling);
687
688 /* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
689 regw(module_params->horz_offset, DATAHOFST);
690 regw(module_params->vert_offset, DATAVOFST);
691
692 /* Setup test pattern if enabled */
693 if (params->config_params.test_pat_gen) {
694 /* Use the HD/VD pol settings from user */
695 sync.ccdpg_hdpol = params->hd_pol;
696 sync.ccdpg_vdpol = params->vd_pol;
697 dm365_vpss_set_sync_pol(sync);
698 frame_size.hlpfr = isif_cfg.bayer.win.width;
699 frame_size.pplen = isif_cfg.bayer.win.height;
700 dm365_vpss_set_pg_frame_size(frame_size);
701 vpss_select_ccdc_source(VPSS_PGLPBK);
702 }
703
704 dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
705 return 0;
706}
707
708static int isif_set_buftype(enum ccdc_buftype buf_type)
709{
710 if (isif_cfg.if_type == VPFE_RAW_BAYER)
711 isif_cfg.bayer.buf_type = buf_type;
712 else
713 isif_cfg.ycbcr.buf_type = buf_type;
714
715 return 0;
716
717}
718static enum ccdc_buftype isif_get_buftype(void)
719{
720 if (isif_cfg.if_type == VPFE_RAW_BAYER)
721 return isif_cfg.bayer.buf_type;
722
723 return isif_cfg.ycbcr.buf_type;
724}
725
726static int isif_enum_pix(u32 *pix, int i)
727{
728 int ret = -EINVAL;
729
730 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
731 if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
732 *pix = isif_raw_bayer_pix_formats[i];
733 ret = 0;
734 }
735 } else {
736 if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
737 *pix = isif_raw_yuv_pix_formats[i];
738 ret = 0;
739 }
740 }
741
742 return ret;
743}
744
745static int isif_set_pixel_format(unsigned int pixfmt)
746{
747 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
748 if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
749 if ((isif_cfg.bayer.config_params.compress.alg !=
750 ISIF_ALAW) &&
751 (isif_cfg.bayer.config_params.compress.alg !=
752 ISIF_DPCM)) {
753 dev_dbg(isif_cfg.dev,
754 "Either configure A-Law or DPCM\n");
755 return -EINVAL;
756 }
757 isif_cfg.data_pack = ISIF_PACK_8BIT;
758 } else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
759 isif_cfg.bayer.config_params.compress.alg =
760 ISIF_NO_COMPRESSION;
761 isif_cfg.data_pack = ISIF_PACK_16BIT;
762 } else
763 return -EINVAL;
764 isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
765 } else {
766 if (pixfmt == V4L2_PIX_FMT_YUYV)
767 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
768 else if (pixfmt == V4L2_PIX_FMT_UYVY)
769 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
770 else
771 return -EINVAL;
772 isif_cfg.data_pack = ISIF_PACK_8BIT;
773 }
774 return 0;
775}
776
777static u32 isif_get_pixel_format(void)
778{
779 u32 pixfmt;
780
781 if (isif_cfg.if_type == VPFE_RAW_BAYER)
782 if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
783 isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
784 pixfmt = V4L2_PIX_FMT_SBGGR8;
785 else
786 pixfmt = V4L2_PIX_FMT_SBGGR16;
787 else {
788 if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
789 pixfmt = V4L2_PIX_FMT_YUYV;
790 else
791 pixfmt = V4L2_PIX_FMT_UYVY;
792 }
793 return pixfmt;
794}
795
796static int isif_set_image_window(struct v4l2_rect *win)
797{
798 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
799 isif_cfg.bayer.win.top = win->top;
800 isif_cfg.bayer.win.left = win->left;
801 isif_cfg.bayer.win.width = win->width;
802 isif_cfg.bayer.win.height = win->height;
803 } else {
804 isif_cfg.ycbcr.win.top = win->top;
805 isif_cfg.ycbcr.win.left = win->left;
806 isif_cfg.ycbcr.win.width = win->width;
807 isif_cfg.ycbcr.win.height = win->height;
808 }
809 return 0;
810}
811
812static void isif_get_image_window(struct v4l2_rect *win)
813{
814 if (isif_cfg.if_type == VPFE_RAW_BAYER)
815 *win = isif_cfg.bayer.win;
816 else
817 *win = isif_cfg.ycbcr.win;
818}
819
820static unsigned int isif_get_line_length(void)
821{
822 unsigned int len;
823
824 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
825 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
826 len = ((isif_cfg.bayer.win.width));
827 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
828 len = (((isif_cfg.bayer.win.width * 2) +
829 (isif_cfg.bayer.win.width >> 2)));
830 else
831 len = (((isif_cfg.bayer.win.width * 2)));
832 } else
833 len = (((isif_cfg.ycbcr.win.width * 2)));
834 return ALIGN(len, 32);
835}
836
837static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
838{
839 if (isif_cfg.if_type == VPFE_RAW_BAYER)
840 isif_cfg.bayer.frm_fmt = frm_fmt;
841 else
842 isif_cfg.ycbcr.frm_fmt = frm_fmt;
843 return 0;
844}
845static enum ccdc_frmfmt isif_get_frame_format(void)
846{
847 if (isif_cfg.if_type == VPFE_RAW_BAYER)
848 return isif_cfg.bayer.frm_fmt;
849 return isif_cfg.ycbcr.frm_fmt;
850}
851
852static int isif_getfid(void)
853{
854 return (regr(MODESET) >> 15) & 0x1;
855}
856
857/* misc operations */
858static void isif_setfbaddr(unsigned long addr)
859{
860 regw((addr >> 21) & 0x07ff, CADU);
861 regw((addr >> 5) & 0x0ffff, CADL);
862}
863
864static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
865{
866 isif_cfg.if_type = params->if_type;
867
868 switch (params->if_type) {
869 case VPFE_BT656:
870 case VPFE_BT656_10BIT:
871 case VPFE_YCBCR_SYNC_8:
872 isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
873 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
874 break;
875 case VPFE_BT1120:
876 case VPFE_YCBCR_SYNC_16:
877 isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
878 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
879 break;
880 case VPFE_RAW_BAYER:
881 isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
882 break;
883 default:
884 dev_dbg(isif_cfg.dev, "Invalid interface type\n");
885 return -EINVAL;
886 }
887
888 return 0;
889}
890
891/* This function will configure ISIF for YCbCr parameters. */
892static int isif_config_ycbcr(void)
893{
894 struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
895 struct vpss_pg_frame_size frame_size;
896 u32 modeset = 0, ccdcfg = 0;
897 struct vpss_sync_pol sync;
898
899 dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
900
901 /* configure pixel format or input mode */
902 modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
903 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
904 (params->fid_pol << ISIF_FID_POL_SHIFT) |
905 (params->hd_pol << ISIF_HD_POL_SHIFT) |
906 (params->vd_pol << ISIF_VD_POL_SHIFT);
907
908 /* pack the data to 8-bit ISIFCFG */
909 switch (isif_cfg.if_type) {
910 case VPFE_BT656:
911 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
912 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
913 return -EINVAL;
914 }
915 modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
916 regw(3, REC656IF);
917 ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
918 break;
919 case VPFE_BT656_10BIT:
920 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
921 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
922 return -EINVAL;
923 }
924 /* setup BT.656, embedded sync */
925 regw(3, REC656IF);
926 /* enable 10 bit mode in ccdcfg */
927 ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
928 ISIF_BW656_ENABLE;
929 break;
930 case VPFE_BT1120:
931 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
932 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
933 return -EINVAL;
934 }
935 regw(3, REC656IF);
936 break;
937
938 case VPFE_YCBCR_SYNC_8:
939 ccdcfg |= ISIF_DATA_PACK8;
940 ccdcfg |= ISIF_YCINSWP_YCBCR;
941 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
942 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
943 return -EINVAL;
944 }
945 break;
946 case VPFE_YCBCR_SYNC_16:
947 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
948 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
949 return -EINVAL;
950 }
951 break;
952 default:
953 /* should never come here */
954 dev_dbg(isif_cfg.dev, "Invalid interface type\n");
955 return -EINVAL;
956 }
957
958 regw(modeset, MODESET);
959
960 /* Set up pix order */
961 ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
962
963 regw(ccdcfg, CCDCFG);
964
965 /* configure video window */
966 if ((isif_cfg.if_type == VPFE_BT1120) ||
967 (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
968 isif_setwin(&params->win, params->frm_fmt, 1);
969 else
970 isif_setwin(&params->win, params->frm_fmt, 2);
971
972 /*
973 * configure the horizontal line offset
974 * this is done by rounding up width to a multiple of 16 pixels
975 * and multiply by two to account for y:cb:cr 4:2:2 data
976 */
977 regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
978
979 /* configure the memory line offset */
980 if ((params->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
981 (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
982 /* two fields are interleaved in memory */
983 regw(0x00000249, SDOFST);
984
985 /* Setup test pattern if enabled */
986 if (isif_cfg.bayer.config_params.test_pat_gen) {
987 sync.ccdpg_hdpol = params->hd_pol;
988 sync.ccdpg_vdpol = params->vd_pol;
989 dm365_vpss_set_sync_pol(sync);
990 dm365_vpss_set_pg_frame_size(frame_size);
991 }
992 return 0;
993}
994
995static int isif_configure(void)
996{
997 if (isif_cfg.if_type == VPFE_RAW_BAYER)
998 return isif_config_raw();
999 return isif_config_ycbcr();
1000}
1001
1002static int isif_close(struct device *device)
1003{
1004 /* copy defaults to module params */
1005 isif_cfg.bayer.config_params = isif_config_defaults;
1006 return 0;
1007}
1008
1009static struct ccdc_hw_device isif_hw_dev = {
1010 .name = "ISIF",
1011 .owner = THIS_MODULE,
1012 .hw_ops = {
1013 .open = isif_open,
1014 .close = isif_close,
1015 .enable = isif_enable,
1016 .enable_out_to_sdram = isif_enable_output_to_sdram,
1017 .set_hw_if_params = isif_set_hw_if_params,
1018 .configure = isif_configure,
1019 .set_buftype = isif_set_buftype,
1020 .get_buftype = isif_get_buftype,
1021 .enum_pix = isif_enum_pix,
1022 .set_pixel_format = isif_set_pixel_format,
1023 .get_pixel_format = isif_get_pixel_format,
1024 .set_frame_format = isif_set_frame_format,
1025 .get_frame_format = isif_get_frame_format,
1026 .set_image_window = isif_set_image_window,
1027 .get_image_window = isif_get_image_window,
1028 .get_line_length = isif_get_line_length,
1029 .setfbaddr = isif_setfbaddr,
1030 .getfid = isif_getfid,
1031 },
1032};
1033
1034static int __init isif_probe(struct platform_device *pdev)
1035{
1036 void (*setup_pinmux)(void);
1037 struct resource *res;
1038 void *__iomem addr;
1039 int status = 0, i;
1040
1041 /*
1042 * first try to register with vpfe. If not correct platform, then we
1043 * don't have to iomap
1044 */
1045 status = vpfe_register_ccdc_device(&isif_hw_dev);
1046 if (status < 0)
1047 return status;
1048
1049 /* Get and enable Master clock */
1050 isif_cfg.mclk = clk_get(&pdev->dev, "master");
1051 if (IS_ERR(isif_cfg.mclk)) {
1052 status = PTR_ERR(isif_cfg.mclk);
1053 goto fail_mclk;
1054 }
1055 if (clk_enable(isif_cfg.mclk)) {
1056 status = -ENODEV;
1057 goto fail_mclk;
1058 }
1059
1060 /* Platform data holds setup_pinmux function ptr */
1061 if (NULL == pdev->dev.platform_data) {
1062 status = -ENODEV;
1063 goto fail_mclk;
1064 }
1065 setup_pinmux = pdev->dev.platform_data;
1066 /*
1067 * setup Mux configuration for ccdc which may be different for
1068 * different SoCs using this CCDC
1069 */
1070 setup_pinmux();
1071
1072 i = 0;
1073 /* Get the ISIF base address, linearization table0 and table1 addr. */
1074 while (i < 3) {
1075 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1076 if (!res) {
1077 status = -ENODEV;
1078 goto fail_nobase_res;
1079 }
1080 res = request_mem_region(res->start, resource_size(res),
1081 res->name);
1082 if (!res) {
1083 status = -EBUSY;
1084 goto fail_nobase_res;
1085 }
1086 addr = ioremap_nocache(res->start, resource_size(res));
1087 if (!addr) {
1088 status = -ENOMEM;
1089 goto fail_base_iomap;
1090 }
1091 switch (i) {
1092 case 0:
1093 /* ISIF base address */
1094 isif_cfg.base_addr = addr;
1095 break;
1096 case 1:
1097 /* ISIF linear tbl0 address */
1098 isif_cfg.linear_tbl0_addr = addr;
1099 break;
1100 default:
1101 /* ISIF linear tbl0 address */
1102 isif_cfg.linear_tbl1_addr = addr;
1103 break;
1104 }
1105 i++;
1106 }
1107 isif_cfg.dev = &pdev->dev;
1108
1109 printk(KERN_NOTICE "%s is registered with vpfe.\n",
1110 isif_hw_dev.name);
1111 return 0;
1112fail_base_iomap:
1113 release_mem_region(res->start, resource_size(res));
1114 i--;
1115fail_nobase_res:
1116 if (isif_cfg.base_addr)
1117 iounmap(isif_cfg.base_addr);
1118 if (isif_cfg.linear_tbl0_addr)
1119 iounmap(isif_cfg.linear_tbl0_addr);
1120
1121 while (i >= 0) {
1122 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1123 release_mem_region(res->start, resource_size(res));
1124 i--;
1125 }
1126fail_mclk:
1127 clk_put(isif_cfg.mclk);
1128 vpfe_unregister_ccdc_device(&isif_hw_dev);
1129 return status;
1130}
1131
1132static int isif_remove(struct platform_device *pdev)
1133{
1134 struct resource *res;
1135 int i = 0;
1136
1137 iounmap(isif_cfg.base_addr);
1138 iounmap(isif_cfg.linear_tbl0_addr);
1139 iounmap(isif_cfg.linear_tbl1_addr);
1140 while (i < 3) {
1141 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1142 if (res)
1143 release_mem_region(res->start, resource_size(res));
1144 i++;
1145 }
1146 vpfe_unregister_ccdc_device(&isif_hw_dev);
1147 return 0;
1148}
1149
1150static struct platform_driver isif_driver = {
1151 .driver = {
1152 .name = "isif",
1153 .owner = THIS_MODULE,
1154 },
1155 .remove = __devexit_p(isif_remove),
1156 .probe = isif_probe,
1157};
1158
1159static int __init isif_init(void)
1160{
1161 return platform_driver_register(&isif_driver);
1162}
1163
1164static void isif_exit(void)
1165{
1166 platform_driver_unregister(&isif_driver);
1167}
1168
1169module_init(isif_init);
1170module_exit(isif_exit);
1171
1172MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/davinci/isif_regs.h b/drivers/media/video/davinci/isif_regs.h
new file mode 100644
index 000000000000..f7b8893a2957
--- /dev/null
+++ b/drivers/media/video/davinci/isif_regs.h
@@ -0,0 +1,269 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _ISIF_REGS_H
19#define _ISIF_REGS_H
20
21/* ISIF registers relative offsets */
22#define SYNCEN 0x00
23#define MODESET 0x04
24#define HDW 0x08
25#define VDW 0x0c
26#define PPLN 0x10
27#define LPFR 0x14
28#define SPH 0x18
29#define LNH 0x1c
30#define SLV0 0x20
31#define SLV1 0x24
32#define LNV 0x28
33#define CULH 0x2c
34#define CULV 0x30
35#define HSIZE 0x34
36#define SDOFST 0x38
37#define CADU 0x3c
38#define CADL 0x40
39#define LINCFG0 0x44
40#define LINCFG1 0x48
41#define CCOLP 0x4c
42#define CRGAIN 0x50
43#define CGRGAIN 0x54
44#define CGBGAIN 0x58
45#define CBGAIN 0x5c
46#define COFSTA 0x60
47#define FLSHCFG0 0x64
48#define FLSHCFG1 0x68
49#define FLSHCFG2 0x6c
50#define VDINT0 0x70
51#define VDINT1 0x74
52#define VDINT2 0x78
53#define MISC 0x7c
54#define CGAMMAWD 0x80
55#define REC656IF 0x84
56#define CCDCFG 0x88
57/*****************************************************
58* Defect Correction registers
59*****************************************************/
60#define DFCCTL 0x8c
61#define VDFSATLV 0x90
62#define DFCMEMCTL 0x94
63#define DFCMEM0 0x98
64#define DFCMEM1 0x9c
65#define DFCMEM2 0xa0
66#define DFCMEM3 0xa4
67#define DFCMEM4 0xa8
68/****************************************************
69* Black Clamp registers
70****************************************************/
71#define CLAMPCFG 0xac
72#define CLDCOFST 0xb0
73#define CLSV 0xb4
74#define CLHWIN0 0xb8
75#define CLHWIN1 0xbc
76#define CLHWIN2 0xc0
77#define CLVRV 0xc4
78#define CLVWIN0 0xc8
79#define CLVWIN1 0xcc
80#define CLVWIN2 0xd0
81#define CLVWIN3 0xd4
82/****************************************************
83* Lense Shading Correction
84****************************************************/
85#define DATAHOFST 0xd8
86#define DATAVOFST 0xdc
87#define LSCHVAL 0xe0
88#define LSCVVAL 0xe4
89#define TWODLSCCFG 0xe8
90#define TWODLSCOFST 0xec
91#define TWODLSCINI 0xf0
92#define TWODLSCGRBU 0xf4
93#define TWODLSCGRBL 0xf8
94#define TWODLSCGROF 0xfc
95#define TWODLSCORBU 0x100
96#define TWODLSCORBL 0x104
97#define TWODLSCOROF 0x108
98#define TWODLSCIRQEN 0x10c
99#define TWODLSCIRQST 0x110
100/****************************************************
101* Data formatter
102****************************************************/
103#define FMTCFG 0x114
104#define FMTPLEN 0x118
105#define FMTSPH 0x11c
106#define FMTLNH 0x120
107#define FMTSLV 0x124
108#define FMTLNV 0x128
109#define FMTRLEN 0x12c
110#define FMTHCNT 0x130
111#define FMTAPTR_BASE 0x134
112/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
113#define FMTAPTR(i) (FMTAPTR_BASE + (i * 4))
114#define FMTPGMVF0 0x174
115#define FMTPGMVF1 0x178
116#define FMTPGMAPU0 0x17c
117#define FMTPGMAPU1 0x180
118#define FMTPGMAPS0 0x184
119#define FMTPGMAPS1 0x188
120#define FMTPGMAPS2 0x18c
121#define FMTPGMAPS3 0x190
122#define FMTPGMAPS4 0x194
123#define FMTPGMAPS5 0x198
124#define FMTPGMAPS6 0x19c
125#define FMTPGMAPS7 0x1a0
126/************************************************
127* Color Space Converter
128************************************************/
129#define CSCCTL 0x1a4
130#define CSCM0 0x1a8
131#define CSCM1 0x1ac
132#define CSCM2 0x1b0
133#define CSCM3 0x1b4
134#define CSCM4 0x1b8
135#define CSCM5 0x1bc
136#define CSCM6 0x1c0
137#define CSCM7 0x1c4
138#define OBWIN0 0x1c8
139#define OBWIN1 0x1cc
140#define OBWIN2 0x1d0
141#define OBWIN3 0x1d4
142#define OBVAL0 0x1d8
143#define OBVAL1 0x1dc
144#define OBVAL2 0x1e0
145#define OBVAL3 0x1e4
146#define OBVAL4 0x1e8
147#define OBVAL5 0x1ec
148#define OBVAL6 0x1f0
149#define OBVAL7 0x1f4
150#define CLKCTL 0x1f8
151
152/* Masks & Shifts below */
153#define START_PX_HOR_MASK 0x7FFF
154#define NUM_PX_HOR_MASK 0x7FFF
155#define START_VER_ONE_MASK 0x7FFF
156#define START_VER_TWO_MASK 0x7FFF
157#define NUM_LINES_VER 0x7FFF
158
159/* gain - offset masks */
160#define GAIN_INTEGER_SHIFT 9
161#define OFFSET_MASK 0xFFF
162#define GAIN_SDRAM_EN_SHIFT 12
163#define GAIN_IPIPE_EN_SHIFT 13
164#define GAIN_H3A_EN_SHIFT 14
165#define OFST_SDRAM_EN_SHIFT 8
166#define OFST_IPIPE_EN_SHIFT 9
167#define OFST_H3A_EN_SHIFT 10
168#define GAIN_OFFSET_EN_MASK 0x7700
169
170/* Culling */
171#define CULL_PAT_EVEN_LINE_SHIFT 8
172
173/* CCDCFG register */
174#define ISIF_YCINSWP_RAW (0x00 << 4)
175#define ISIF_YCINSWP_YCBCR (0x01 << 4)
176#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC (0x00 << 6)
177#define ISIF_CCDCFG_WENLOG_AND (0x00 << 8)
178#define ISIF_CCDCFG_TRGSEL_WEN (0x00 << 9)
179#define ISIF_CCDCFG_EXTRG_DISABLE (0x00 << 10)
180#define ISIF_LATCH_ON_VSYNC_DISABLE (0x01 << 15)
181#define ISIF_LATCH_ON_VSYNC_ENABLE (0x00 << 15)
182#define ISIF_DATA_PACK_MASK 3
183#define ISIF_DATA_PACK16 0
184#define ISIF_DATA_PACK12 1
185#define ISIF_DATA_PACK8 2
186#define ISIF_PIX_ORDER_SHIFT 11
187#define ISIF_BW656_ENABLE (0x01 << 5)
188
189/* MODESET registers */
190#define ISIF_VDHDOUT_INPUT (0x00 << 0)
191#define ISIF_INPUT_SHIFT 12
192#define ISIF_RAW_INPUT_MODE 0
193#define ISIF_FID_POL_SHIFT 4
194#define ISIF_HD_POL_SHIFT 3
195#define ISIF_VD_POL_SHIFT 2
196#define ISIF_DATAPOL_NORMAL 0
197#define ISIF_DATAPOL_SHIFT 6
198#define ISIF_EXWEN_DISABLE 0
199#define ISIF_EXWEN_SHIFT 5
200#define ISIF_FRM_FMT_SHIFT 7
201#define ISIF_DATASFT_SHIFT 8
202#define ISIF_LPF_SHIFT 14
203#define ISIF_LPF_MASK 1
204
205/* GAMMAWD registers */
206#define ISIF_ALAW_GAMA_WD_MASK 0xF
207#define ISIF_ALAW_GAMA_WD_SHIFT 1
208#define ISIF_ALAW_ENABLE 1
209#define ISIF_GAMMAWD_CFA_SHIFT 5
210
211/* HSIZE registers */
212#define ISIF_HSIZE_FLIP_MASK 1
213#define ISIF_HSIZE_FLIP_SHIFT 12
214
215/* MISC registers */
216#define ISIF_DPCM_EN_SHIFT 12
217#define ISIF_DPCM_PREDICTOR_SHIFT 13
218
219/* Black clamp related */
220#define ISIF_BC_MODE_COLOR_SHIFT 4
221#define ISIF_HORZ_BC_MODE_SHIFT 1
222#define ISIF_HORZ_BC_WIN_SEL_SHIFT 5
223#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT 6
224#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT 8
225#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT 12
226#define ISIF_VERT_BC_RST_VAL_SEL_SHIFT 4
227#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT 8
228
229/* VDFC registers */
230#define ISIF_VDFC_EN_SHIFT 4
231#define ISIF_VDFC_CORR_MOD_SHIFT 5
232#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT 7
233#define ISIF_VDFC_LEVEL_SHFT_SHIFT 8
234#define ISIF_VDFC_POS_MASK 0x1FFF
235#define ISIF_DFCMEMCTL_DFCMARST_SHIFT 2
236
237/* CSC registers */
238#define ISIF_CSC_COEF_INTEG_MASK 7
239#define ISIF_CSC_COEF_DECIMAL_MASK 0x1f
240#define ISIF_CSC_COEF_INTEG_SHIFT 5
241#define ISIF_CSCM_MSB_SHIFT 8
242#define ISIF_DF_CSC_SPH_MASK 0x1FFF
243#define ISIF_DF_CSC_LNH_MASK 0x1FFF
244#define ISIF_DF_CSC_SLV_MASK 0x1FFF
245#define ISIF_DF_CSC_LNV_MASK 0x1FFF
246#define ISIF_DF_NUMLINES 0x7FFF
247#define ISIF_DF_NUMPIX 0x1FFF
248
249/* Offsets for LSC/DFC/Gain */
250#define ISIF_DATA_H_OFFSET_MASK 0x1FFF
251#define ISIF_DATA_V_OFFSET_MASK 0x1FFF
252
253/* Linearization */
254#define ISIF_LIN_CORRSFT_SHIFT 4
255#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT 10
256
257
258/* Pattern registers */
259#define ISIF_PG_EN (1 << 3)
260#define ISIF_SEL_PG_SRC (3 << 4)
261#define ISIF_PG_VD_POL_SHIFT 0
262#define ISIF_PG_HD_POL_SHIFT 1
263
264/*random other junk*/
265#define ISIF_SYNCEN_VDHDEN_MASK (1 << 0)
266#define ISIF_SYNCEN_WEN_MASK (1 << 1)
267#define ISIF_SYNCEN_WEN_SHIFT 1
268
269#endif
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index de22bc9faf21..885cd54499cf 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -107,9 +107,6 @@ struct ccdc_config {
107 int vpfe_probed; 107 int vpfe_probed;
108 /* name of ccdc device */ 108 /* name of ccdc device */
109 char name[32]; 109 char name[32];
110 /* for storing mem maps for CCDC */
111 int ccdc_addr_size;
112 void *__iomem ccdc_addr;
113}; 110};
114 111
115/* data structures */ 112/* data structures */
@@ -229,7 +226,6 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
229 BUG_ON(!dev->hw_ops.set_image_window); 226 BUG_ON(!dev->hw_ops.set_image_window);
230 BUG_ON(!dev->hw_ops.get_image_window); 227 BUG_ON(!dev->hw_ops.get_image_window);
231 BUG_ON(!dev->hw_ops.get_line_length); 228 BUG_ON(!dev->hw_ops.get_line_length);
232 BUG_ON(!dev->hw_ops.setfbaddr);
233 BUG_ON(!dev->hw_ops.getfid); 229 BUG_ON(!dev->hw_ops.getfid);
234 230
235 mutex_lock(&ccdc_lock); 231 mutex_lock(&ccdc_lock);
@@ -240,25 +236,23 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
240 * walk through it during vpfe probe 236 * walk through it during vpfe probe
241 */ 237 */
242 printk(KERN_ERR "vpfe capture not initialized\n"); 238 printk(KERN_ERR "vpfe capture not initialized\n");
243 ret = -1; 239 ret = -EFAULT;
244 goto unlock; 240 goto unlock;
245 } 241 }
246 242
247 if (strcmp(dev->name, ccdc_cfg->name)) { 243 if (strcmp(dev->name, ccdc_cfg->name)) {
248 /* ignore this ccdc */ 244 /* ignore this ccdc */
249 ret = -1; 245 ret = -EINVAL;
250 goto unlock; 246 goto unlock;
251 } 247 }
252 248
253 if (ccdc_dev) { 249 if (ccdc_dev) {
254 printk(KERN_ERR "ccdc already registered\n"); 250 printk(KERN_ERR "ccdc already registered\n");
255 ret = -1; 251 ret = -EINVAL;
256 goto unlock; 252 goto unlock;
257 } 253 }
258 254
259 ccdc_dev = dev; 255 ccdc_dev = dev;
260 dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
261 ccdc_cfg->ccdc_addr_size);
262unlock: 256unlock:
263 mutex_unlock(&ccdc_lock); 257 mutex_unlock(&ccdc_lock);
264 return ret; 258 return ret;
@@ -1786,61 +1780,6 @@ static struct vpfe_device *vpfe_initialize(void)
1786 return vpfe_dev; 1780 return vpfe_dev;
1787} 1781}
1788 1782
1789static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
1790{
1791 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1792
1793 clk_disable(vpfe_cfg->vpssclk);
1794 clk_put(vpfe_cfg->vpssclk);
1795 clk_disable(vpfe_cfg->slaveclk);
1796 clk_put(vpfe_cfg->slaveclk);
1797 v4l2_info(vpfe_dev->pdev->driver,
1798 "vpfe vpss master & slave clocks disabled\n");
1799}
1800
1801static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
1802{
1803 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1804 int ret = -ENOENT;
1805
1806 vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
1807 if (NULL == vpfe_cfg->vpssclk) {
1808 v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
1809 "vpss_master\n");
1810 return ret;
1811 }
1812
1813 if (clk_enable(vpfe_cfg->vpssclk)) {
1814 v4l2_err(vpfe_dev->pdev->driver,
1815 "vpfe vpss master clock not enabled\n");
1816 goto out;
1817 }
1818 v4l2_info(vpfe_dev->pdev->driver,
1819 "vpfe vpss master clock enabled\n");
1820
1821 vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
1822 if (NULL == vpfe_cfg->slaveclk) {
1823 v4l2_err(vpfe_dev->pdev->driver,
1824 "No clock defined for vpss slave\n");
1825 goto out;
1826 }
1827
1828 if (clk_enable(vpfe_cfg->slaveclk)) {
1829 v4l2_err(vpfe_dev->pdev->driver,
1830 "vpfe vpss slave clock not enabled\n");
1831 goto out;
1832 }
1833 v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
1834 return 0;
1835out:
1836 if (vpfe_cfg->vpssclk)
1837 clk_put(vpfe_cfg->vpssclk);
1838 if (vpfe_cfg->slaveclk)
1839 clk_put(vpfe_cfg->slaveclk);
1840
1841 return -1;
1842}
1843
1844/* 1783/*
1845 * vpfe_probe : This function creates device entries by register 1784 * vpfe_probe : This function creates device entries by register
1846 * itself to the V4L2 driver and initializes fields of each 1785 * itself to the V4L2 driver and initializes fields of each
@@ -1870,7 +1809,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
1870 1809
1871 if (NULL == pdev->dev.platform_data) { 1810 if (NULL == pdev->dev.platform_data) {
1872 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); 1811 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
1873 ret = -ENOENT; 1812 ret = -ENODEV;
1874 goto probe_free_dev_mem; 1813 goto probe_free_dev_mem;
1875 } 1814 }
1876 1815
@@ -1884,18 +1823,13 @@ static __init int vpfe_probe(struct platform_device *pdev)
1884 goto probe_free_dev_mem; 1823 goto probe_free_dev_mem;
1885 } 1824 }
1886 1825
1887 /* enable vpss clocks */
1888 ret = vpfe_enable_clock(vpfe_dev);
1889 if (ret)
1890 goto probe_free_dev_mem;
1891
1892 mutex_lock(&ccdc_lock); 1826 mutex_lock(&ccdc_lock);
1893 /* Allocate memory for ccdc configuration */ 1827 /* Allocate memory for ccdc configuration */
1894 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); 1828 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
1895 if (NULL == ccdc_cfg) { 1829 if (NULL == ccdc_cfg) {
1896 v4l2_err(pdev->dev.driver, 1830 v4l2_err(pdev->dev.driver,
1897 "Memory allocation failed for ccdc_cfg\n"); 1831 "Memory allocation failed for ccdc_cfg\n");
1898 goto probe_disable_clock; 1832 goto probe_free_dev_mem;
1899 } 1833 }
1900 1834
1901 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); 1835 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
@@ -1904,61 +1838,34 @@ static __init int vpfe_probe(struct platform_device *pdev)
1904 if (!res1) { 1838 if (!res1) {
1905 v4l2_err(pdev->dev.driver, 1839 v4l2_err(pdev->dev.driver,
1906 "Unable to get interrupt for VINT0\n"); 1840 "Unable to get interrupt for VINT0\n");
1907 ret = -ENOENT; 1841 ret = -ENODEV;
1908 goto probe_disable_clock; 1842 goto probe_free_ccdc_cfg_mem;
1909 } 1843 }
1910 vpfe_dev->ccdc_irq0 = res1->start; 1844 vpfe_dev->ccdc_irq0 = res1->start;
1911 1845
1912 /* Get VINT1 irq resource */ 1846 /* Get VINT1 irq resource */
1913 res1 = platform_get_resource(pdev, 1847 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
1914 IORESOURCE_IRQ, 1);
1915 if (!res1) { 1848 if (!res1) {
1916 v4l2_err(pdev->dev.driver, 1849 v4l2_err(pdev->dev.driver,
1917 "Unable to get interrupt for VINT1\n"); 1850 "Unable to get interrupt for VINT1\n");
1918 ret = -ENOENT; 1851 ret = -ENODEV;
1919 goto probe_disable_clock; 1852 goto probe_free_ccdc_cfg_mem;
1920 } 1853 }
1921 vpfe_dev->ccdc_irq1 = res1->start; 1854 vpfe_dev->ccdc_irq1 = res1->start;
1922 1855
1923 /* Get address base of CCDC */
1924 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1925 if (!res1) {
1926 v4l2_err(pdev->dev.driver,
1927 "Unable to get register address map\n");
1928 ret = -ENOENT;
1929 goto probe_disable_clock;
1930 }
1931
1932 ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
1933 if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
1934 pdev->dev.driver->name)) {
1935 v4l2_err(pdev->dev.driver,
1936 "Failed request_mem_region for ccdc base\n");
1937 ret = -ENXIO;
1938 goto probe_disable_clock;
1939 }
1940 ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
1941 ccdc_cfg->ccdc_addr_size);
1942 if (!ccdc_cfg->ccdc_addr) {
1943 v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
1944 ret = -ENXIO;
1945 goto probe_out_release_mem1;
1946 }
1947
1948 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, 1856 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
1949 "vpfe_capture0", vpfe_dev); 1857 "vpfe_capture0", vpfe_dev);
1950 1858
1951 if (0 != ret) { 1859 if (0 != ret) {
1952 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n"); 1860 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
1953 goto probe_out_unmap1; 1861 goto probe_free_ccdc_cfg_mem;
1954 } 1862 }
1955 1863
1956 /* Allocate memory for video device */ 1864 /* Allocate memory for video device */
1957 vfd = video_device_alloc(); 1865 vfd = video_device_alloc();
1958 if (NULL == vfd) { 1866 if (NULL == vfd) {
1959 ret = -ENOMEM; 1867 ret = -ENOMEM;
1960 v4l2_err(pdev->dev.driver, 1868 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
1961 "Unable to alloc video device\n");
1962 goto probe_out_release_irq; 1869 goto probe_out_release_irq;
1963 } 1870 }
1964 1871
@@ -2073,12 +1980,7 @@ probe_out_video_release:
2073 video_device_release(vpfe_dev->video_dev); 1980 video_device_release(vpfe_dev->video_dev);
2074probe_out_release_irq: 1981probe_out_release_irq:
2075 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 1982 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2076probe_out_unmap1: 1983probe_free_ccdc_cfg_mem:
2077 iounmap(ccdc_cfg->ccdc_addr);
2078probe_out_release_mem1:
2079 release_mem_region(res1->start, res1->end - res1->start + 1);
2080probe_disable_clock:
2081 vpfe_disable_clock(vpfe_dev);
2082 mutex_unlock(&ccdc_lock); 1984 mutex_unlock(&ccdc_lock);
2083 kfree(ccdc_cfg); 1985 kfree(ccdc_cfg);
2084probe_free_dev_mem: 1986probe_free_dev_mem:
@@ -2092,7 +1994,6 @@ probe_free_dev_mem:
2092static int __devexit vpfe_remove(struct platform_device *pdev) 1994static int __devexit vpfe_remove(struct platform_device *pdev)
2093{ 1995{
2094 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); 1996 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
2095 struct resource *res;
2096 1997
2097 v4l2_info(pdev->dev.driver, "vpfe_remove\n"); 1998 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
2098 1999
@@ -2100,12 +2001,6 @@ static int __devexit vpfe_remove(struct platform_device *pdev)
2100 kfree(vpfe_dev->sd); 2001 kfree(vpfe_dev->sd);
2101 v4l2_device_unregister(&vpfe_dev->v4l2_dev); 2002 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2102 video_unregister_device(vpfe_dev->video_dev); 2003 video_unregister_device(vpfe_dev->video_dev);
2103 mutex_lock(&ccdc_lock);
2104 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2105 release_mem_region(res->start, res->end - res->start + 1);
2106 iounmap(ccdc_cfg->ccdc_addr);
2107 mutex_unlock(&ccdc_lock);
2108 vpfe_disable_clock(vpfe_dev);
2109 kfree(vpfe_dev); 2004 kfree(vpfe_dev);
2110 kfree(ccdc_cfg); 2005 kfree(ccdc_cfg);
2111 return 0; 2006 return 0;
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
index 7ee72ecd3d81..7918680917d0 100644
--- a/drivers/media/video/davinci/vpss.c
+++ b/drivers/media/video/davinci/vpss.c
@@ -15,7 +15,7 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 * 17 *
18 * common vpss driver for all video drivers. 18 * common vpss system module platform driver for all video drivers.
19 */ 19 */
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
@@ -35,12 +35,52 @@ MODULE_AUTHOR("Texas Instruments");
35/* DM644x defines */ 35/* DM644x defines */
36#define DM644X_SBL_PCR_VPSS (4) 36#define DM644X_SBL_PCR_VPSS (4)
37 37
38#define DM355_VPSSBL_INTSEL 0x10
39#define DM355_VPSSBL_EVTSEL 0x14
38/* vpss BL register offsets */ 40/* vpss BL register offsets */
39#define DM355_VPSSBL_CCDCMUX 0x1c 41#define DM355_VPSSBL_CCDCMUX 0x1c
40/* vpss CLK register offsets */ 42/* vpss CLK register offsets */
41#define DM355_VPSSCLK_CLKCTRL 0x04 43#define DM355_VPSSCLK_CLKCTRL 0x04
42/* masks and shifts */ 44/* masks and shifts */
43#define VPSS_HSSISEL_SHIFT 4 45#define VPSS_HSSISEL_SHIFT 4
46/*
47 * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
48 * IPIPE_INT1_SDR - vpss_int5
49 */
50#define DM355_VPSSBL_INTSEL_DEFAULT 0xff83ff10
51/* VENCINT - vpss_int8 */
52#define DM355_VPSSBL_EVTSEL_DEFAULT 0x4
53
54#define DM365_ISP5_PCCR 0x04
55#define DM365_ISP5_INTSEL1 0x10
56#define DM365_ISP5_INTSEL2 0x14
57#define DM365_ISP5_INTSEL3 0x18
58#define DM365_ISP5_CCDCMUX 0x20
59#define DM365_ISP5_PG_FRAME_SIZE 0x28
60#define DM365_VPBE_CLK_CTRL 0x00
61/*
62 * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
63 * AF - vpss_int3
64 */
65#define DM365_ISP5_INTSEL1_DEFAULT 0x0b1f0100
66/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
67#define DM365_ISP5_INTSEL2_DEFAULT 0x1f0a0f1f
68/* VENC - vpss_int8 */
69#define DM365_ISP5_INTSEL3_DEFAULT 0x00000015
70
71/* masks and shifts for DM365*/
72#define DM365_CCDC_PG_VD_POL_SHIFT 0
73#define DM365_CCDC_PG_HD_POL_SHIFT 1
74
75#define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4))
76#define CCD_SRC_SEL_SHIFT 4
77
78/* Different SoC platforms supported by this driver */
79enum vpss_platform_type {
80 DM644X,
81 DM355,
82 DM365,
83};
44 84
45/* 85/*
46 * vpss operations. Depends on platform. Not all functions are available 86 * vpss operations. Depends on platform. Not all functions are available
@@ -59,13 +99,9 @@ struct vpss_hw_ops {
59 99
60/* vpss configuration */ 100/* vpss configuration */
61struct vpss_oper_config { 101struct vpss_oper_config {
62 __iomem void *vpss_bl_regs_base; 102 __iomem void *vpss_regs_base0;
63 __iomem void *vpss_regs_base; 103 __iomem void *vpss_regs_base1;
64 struct resource *r1; 104 enum vpss_platform_type platform;
65 resource_size_t len1;
66 struct resource *r2;
67 resource_size_t len2;
68 char vpss_name[32];
69 spinlock_t vpss_lock; 105 spinlock_t vpss_lock;
70 struct vpss_hw_ops hw_ops; 106 struct vpss_hw_ops hw_ops;
71}; 107};
@@ -75,22 +111,46 @@ static struct vpss_oper_config oper_cfg;
75/* register access routines */ 111/* register access routines */
76static inline u32 bl_regr(u32 offset) 112static inline u32 bl_regr(u32 offset)
77{ 113{
78 return __raw_readl(oper_cfg.vpss_bl_regs_base + offset); 114 return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
79} 115}
80 116
81static inline void bl_regw(u32 val, u32 offset) 117static inline void bl_regw(u32 val, u32 offset)
82{ 118{
83 __raw_writel(val, oper_cfg.vpss_bl_regs_base + offset); 119 __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
84} 120}
85 121
86static inline u32 vpss_regr(u32 offset) 122static inline u32 vpss_regr(u32 offset)
87{ 123{
88 return __raw_readl(oper_cfg.vpss_regs_base + offset); 124 return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
89} 125}
90 126
91static inline void vpss_regw(u32 val, u32 offset) 127static inline void vpss_regw(u32 val, u32 offset)
92{ 128{
93 __raw_writel(val, oper_cfg.vpss_regs_base + offset); 129 __raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
130}
131
132/* For DM365 only */
133static inline u32 isp5_read(u32 offset)
134{
135 return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
136}
137
138/* For DM365 only */
139static inline void isp5_write(u32 val, u32 offset)
140{
141 __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
142}
143
144static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
145{
146 u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
147
148 /* if we are using pattern generator, enable it */
149 if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
150 temp |= 0x08;
151
152 temp |= (src_sel << CCD_SRC_SEL_SHIFT);
153 isp5_write(temp, DM365_ISP5_CCDCMUX);
94} 154}
95 155
96static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) 156static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
@@ -101,9 +161,9 @@ static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
101int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel) 161int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
102{ 162{
103 if (!oper_cfg.hw_ops.select_ccdc_source) 163 if (!oper_cfg.hw_ops.select_ccdc_source)
104 return -1; 164 return -EINVAL;
105 165
106 dm355_select_ccdc_source(src_sel); 166 oper_cfg.hw_ops.select_ccdc_source(src_sel);
107 return 0; 167 return 0;
108} 168}
109EXPORT_SYMBOL(vpss_select_ccdc_source); 169EXPORT_SYMBOL(vpss_select_ccdc_source);
@@ -114,7 +174,7 @@ static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
114 174
115 if (wbl_sel < VPSS_PCR_AEW_WBL_0 || 175 if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
116 wbl_sel > VPSS_PCR_CCDC_WBL_O) 176 wbl_sel > VPSS_PCR_CCDC_WBL_O)
117 return -1; 177 return -EINVAL;
118 178
119 /* writing a 0 clear the overflow */ 179 /* writing a 0 clear the overflow */
120 mask = ~(mask << wbl_sel); 180 mask = ~(mask << wbl_sel);
@@ -126,7 +186,7 @@ static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
126int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel) 186int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
127{ 187{
128 if (!oper_cfg.hw_ops.clear_wbl_overflow) 188 if (!oper_cfg.hw_ops.clear_wbl_overflow)
129 return -1; 189 return -EINVAL;
130 190
131 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel); 191 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
132} 192}
@@ -166,7 +226,7 @@ static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
166 default: 226 default:
167 printk(KERN_ERR "dm355_enable_clock:" 227 printk(KERN_ERR "dm355_enable_clock:"
168 " Invalid selector: %d\n", clock_sel); 228 " Invalid selector: %d\n", clock_sel);
169 return -1; 229 return -EINVAL;
170 } 230 }
171 231
172 spin_lock_irqsave(&oper_cfg.vpss_lock, flags); 232 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
@@ -181,100 +241,221 @@ static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
181 return 0; 241 return 0;
182} 242}
183 243
244static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
245{
246 unsigned long flags;
247 u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
248 u32 (*read)(u32 offset) = isp5_read;
249 void(*write)(u32 val, u32 offset) = isp5_write;
250
251 switch (clock_sel) {
252 case VPSS_BL_CLOCK:
253 break;
254 case VPSS_CCDC_CLOCK:
255 shift = 1;
256 break;
257 case VPSS_H3A_CLOCK:
258 shift = 2;
259 break;
260 case VPSS_RSZ_CLOCK:
261 shift = 3;
262 break;
263 case VPSS_IPIPE_CLOCK:
264 shift = 4;
265 break;
266 case VPSS_IPIPEIF_CLOCK:
267 shift = 5;
268 break;
269 case VPSS_PCLK_INTERNAL:
270 shift = 6;
271 break;
272 case VPSS_PSYNC_CLOCK_SEL:
273 shift = 7;
274 break;
275 case VPSS_VPBE_CLOCK:
276 read = vpss_regr;
277 write = vpss_regw;
278 offset = DM365_VPBE_CLK_CTRL;
279 break;
280 case VPSS_VENC_CLOCK_SEL:
281 shift = 2;
282 read = vpss_regr;
283 write = vpss_regw;
284 offset = DM365_VPBE_CLK_CTRL;
285 break;
286 case VPSS_LDC_CLOCK:
287 shift = 3;
288 read = vpss_regr;
289 write = vpss_regw;
290 offset = DM365_VPBE_CLK_CTRL;
291 break;
292 case VPSS_FDIF_CLOCK:
293 shift = 4;
294 read = vpss_regr;
295 write = vpss_regw;
296 offset = DM365_VPBE_CLK_CTRL;
297 break;
298 case VPSS_OSD_CLOCK_SEL:
299 shift = 6;
300 read = vpss_regr;
301 write = vpss_regw;
302 offset = DM365_VPBE_CLK_CTRL;
303 break;
304 case VPSS_LDC_CLOCK_SEL:
305 shift = 7;
306 read = vpss_regr;
307 write = vpss_regw;
308 offset = DM365_VPBE_CLK_CTRL;
309 break;
310 default:
311 printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
312 clock_sel);
313 return -1;
314 }
315
316 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
317 utemp = read(offset);
318 if (!en) {
319 mask = ~mask;
320 utemp &= (mask << shift);
321 } else
322 utemp |= (mask << shift);
323
324 write(utemp, offset);
325 spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
326
327 return 0;
328}
329
184int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en) 330int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
185{ 331{
186 if (!oper_cfg.hw_ops.enable_clock) 332 if (!oper_cfg.hw_ops.enable_clock)
187 return -1; 333 return -EINVAL;
188 334
189 return oper_cfg.hw_ops.enable_clock(clock_sel, en); 335 return oper_cfg.hw_ops.enable_clock(clock_sel, en);
190} 336}
191EXPORT_SYMBOL(vpss_enable_clock); 337EXPORT_SYMBOL(vpss_enable_clock);
192 338
339void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
340{
341 int val = 0;
342 val = isp5_read(DM365_ISP5_CCDCMUX);
343
344 val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
345 val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
346
347 isp5_write(val, DM365_ISP5_CCDCMUX);
348}
349EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
350
351void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
352{
353 int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
354
355 current_reg |= (frame_size.pplen - 1);
356 isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
357}
358EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
359
193static int __init vpss_probe(struct platform_device *pdev) 360static int __init vpss_probe(struct platform_device *pdev)
194{ 361{
195 int status, dm355 = 0; 362 struct resource *r1, *r2;
363 char *platform_name;
364 int status;
196 365
197 if (!pdev->dev.platform_data) { 366 if (!pdev->dev.platform_data) {
198 dev_err(&pdev->dev, "no platform data\n"); 367 dev_err(&pdev->dev, "no platform data\n");
199 return -ENOENT; 368 return -ENOENT;
200 } 369 }
201 strcpy(oper_cfg.vpss_name, pdev->dev.platform_data);
202 370
203 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) 371 platform_name = pdev->dev.platform_data;
204 dm355 = 1; 372 if (!strcmp(platform_name, "dm355_vpss"))
205 else if (strcmp(oper_cfg.vpss_name, "dm644x_vpss")) { 373 oper_cfg.platform = DM355;
374 else if (!strcmp(platform_name, "dm365_vpss"))
375 oper_cfg.platform = DM365;
376 else if (!strcmp(platform_name, "dm644x_vpss"))
377 oper_cfg.platform = DM644X;
378 else {
206 dev_err(&pdev->dev, "vpss driver not supported on" 379 dev_err(&pdev->dev, "vpss driver not supported on"
207 " this platform\n"); 380 " this platform\n");
208 return -ENODEV; 381 return -ENODEV;
209 } 382 }
210 383
211 dev_info(&pdev->dev, "%s vpss probed\n", oper_cfg.vpss_name); 384 dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
212 oper_cfg.r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 385 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
213 if (!oper_cfg.r1) 386 if (!r1)
214 return -ENOENT; 387 return -ENOENT;
215 388
216 oper_cfg.len1 = oper_cfg.r1->end - oper_cfg.r1->start + 1; 389 r1 = request_mem_region(r1->start, resource_size(r1), r1->name);
217 390 if (!r1)
218 oper_cfg.r1 = request_mem_region(oper_cfg.r1->start, oper_cfg.len1,
219 oper_cfg.r1->name);
220 if (!oper_cfg.r1)
221 return -EBUSY; 391 return -EBUSY;
222 392
223 oper_cfg.vpss_bl_regs_base = ioremap(oper_cfg.r1->start, oper_cfg.len1); 393 oper_cfg.vpss_regs_base0 = ioremap(r1->start, resource_size(r1));
224 if (!oper_cfg.vpss_bl_regs_base) { 394 if (!oper_cfg.vpss_regs_base0) {
225 status = -EBUSY; 395 status = -EBUSY;
226 goto fail1; 396 goto fail1;
227 } 397 }
228 398
229 if (dm355) { 399 if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
230 oper_cfg.r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 400 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
231 if (!oper_cfg.r2) { 401 if (!r2) {
232 status = -ENOENT; 402 status = -ENOENT;
233 goto fail2; 403 goto fail2;
234 } 404 }
235 oper_cfg.len2 = oper_cfg.r2->end - oper_cfg.r2->start + 1; 405 r2 = request_mem_region(r2->start, resource_size(r2), r2->name);
236 oper_cfg.r2 = request_mem_region(oper_cfg.r2->start, 406 if (!r2) {
237 oper_cfg.len2,
238 oper_cfg.r2->name);
239 if (!oper_cfg.r2) {
240 status = -EBUSY; 407 status = -EBUSY;
241 goto fail2; 408 goto fail2;
242 } 409 }
243 410
244 oper_cfg.vpss_regs_base = ioremap(oper_cfg.r2->start, 411 oper_cfg.vpss_regs_base1 = ioremap(r2->start,
245 oper_cfg.len2); 412 resource_size(r2));
246 if (!oper_cfg.vpss_regs_base) { 413 if (!oper_cfg.vpss_regs_base1) {
247 status = -EBUSY; 414 status = -EBUSY;
248 goto fail3; 415 goto fail3;
249 } 416 }
250 } 417 }
251 418
252 if (dm355) { 419 if (oper_cfg.platform == DM355) {
253 oper_cfg.hw_ops.enable_clock = dm355_enable_clock; 420 oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
254 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source; 421 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
422 /* Setup vpss interrupts */
423 bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
424 bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
425 } else if (oper_cfg.platform == DM365) {
426 oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
427 oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
428 /* Setup vpss interrupts */
429 isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
430 isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
431 isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
255 } else 432 } else
256 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow; 433 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
257 434
258 spin_lock_init(&oper_cfg.vpss_lock); 435 spin_lock_init(&oper_cfg.vpss_lock);
259 dev_info(&pdev->dev, "%s vpss probe success\n", oper_cfg.vpss_name); 436 dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
260 return 0; 437 return 0;
261 438
262fail3: 439fail3:
263 release_mem_region(oper_cfg.r2->start, oper_cfg.len2); 440 release_mem_region(r2->start, resource_size(r2));
264fail2: 441fail2:
265 iounmap(oper_cfg.vpss_bl_regs_base); 442 iounmap(oper_cfg.vpss_regs_base0);
266fail1: 443fail1:
267 release_mem_region(oper_cfg.r1->start, oper_cfg.len1); 444 release_mem_region(r1->start, resource_size(r1));
268 return status; 445 return status;
269} 446}
270 447
271static int __devexit vpss_remove(struct platform_device *pdev) 448static int __devexit vpss_remove(struct platform_device *pdev)
272{ 449{
273 iounmap(oper_cfg.vpss_bl_regs_base); 450 struct resource *res;
274 release_mem_region(oper_cfg.r1->start, oper_cfg.len1); 451
275 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) { 452 iounmap(oper_cfg.vpss_regs_base0);
276 iounmap(oper_cfg.vpss_regs_base); 453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
277 release_mem_region(oper_cfg.r2->start, oper_cfg.len2); 454 release_mem_region(res->start, resource_size(res));
455 if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
456 iounmap(oper_cfg.vpss_regs_base1);
457 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
458 release_mem_region(res->start, resource_size(res));
278 } 459 }
279 return 0; 460 return 0;
280} 461}
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 25100001ffff..ecbcefb08739 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -232,6 +232,12 @@ static struct em28xx_reg_seq vc211a_enable[] = {
232 { -1, -1, -1, -1}, 232 { -1, -1, -1, -1},
233}; 233};
234 234
235static struct em28xx_reg_seq dikom_dk300_digital[] = {
236 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
237 {EM2880_R04_GPO, 0x08, 0xff, 10},
238 { -1, -1, -1, -1},
239};
240
235 241
236/* 242/*
237 * Board definitions 243 * Board definitions
@@ -461,21 +467,30 @@ struct em28xx_board em28xx_boards[] = {
461 .name = "Leadtek Winfast USB II Deluxe", 467 .name = "Leadtek Winfast USB II Deluxe",
462 .valid = EM28XX_BOARD_NOT_VALIDATED, 468 .valid = EM28XX_BOARD_NOT_VALIDATED,
463 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 469 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
464 .tda9887_conf = TDA9887_PRESENT, 470 .has_ir_i2c = 1,
471 .tvaudio_addr = 0x58,
472 .tda9887_conf = TDA9887_PRESENT |
473 TDA9887_PORT2_ACTIVE |
474 TDA9887_QSS,
465 .decoder = EM28XX_SAA711X, 475 .decoder = EM28XX_SAA711X,
476 .adecoder = EM28XX_TVAUDIO,
466 .input = { { 477 .input = { {
467 .type = EM28XX_VMUX_TELEVISION, 478 .type = EM28XX_VMUX_TELEVISION,
468 .vmux = SAA7115_COMPOSITE2, 479 .vmux = SAA7115_COMPOSITE4,
469 .amux = EM28XX_AMUX_VIDEO, 480 .amux = EM28XX_AMUX_AUX,
470 }, { 481 }, {
471 .type = EM28XX_VMUX_COMPOSITE1, 482 .type = EM28XX_VMUX_COMPOSITE1,
472 .vmux = SAA7115_COMPOSITE0, 483 .vmux = SAA7115_COMPOSITE5,
473 .amux = EM28XX_AMUX_LINE_IN, 484 .amux = EM28XX_AMUX_LINE_IN,
474 }, { 485 }, {
475 .type = EM28XX_VMUX_SVIDEO, 486 .type = EM28XX_VMUX_SVIDEO,
476 .vmux = SAA7115_COMPOSITE0, 487 .vmux = SAA7115_SVIDEO3,
477 .amux = EM28XX_AMUX_LINE_IN, 488 .amux = EM28XX_AMUX_LINE_IN,
478 } }, 489 } },
490 .radio = {
491 .type = EM28XX_RADIO,
492 .amux = EM28XX_AMUX_AUX,
493 }
479 }, 494 },
480 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { 495 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
481 .name = "Videology 20K14XUSB USB2.0", 496 .name = "Videology 20K14XUSB USB2.0",
@@ -730,11 +745,12 @@ struct em28xx_board em28xx_boards[] = {
730 745
731 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { 746 [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
732 .name = "Terratec Hybrid XS Secam", 747 .name = "Terratec Hybrid XS Secam",
733 .valid = EM28XX_BOARD_NOT_VALIDATED,
734 .has_msp34xx = 1, 748 .has_msp34xx = 1,
735 .tuner_type = TUNER_XC2028, 749 .tuner_type = TUNER_XC2028,
736 .tuner_gpio = default_tuner_gpio, 750 .tuner_gpio = default_tuner_gpio,
737 .decoder = EM28XX_TVP5150, 751 .decoder = EM28XX_TVP5150,
752 .has_dvb = 1,
753 .dvb_gpio = default_digital,
738 .input = { { 754 .input = { {
739 .type = EM28XX_VMUX_TELEVISION, 755 .type = EM28XX_VMUX_TELEVISION,
740 .vmux = TVP5150_COMPOSITE0, 756 .vmux = TVP5150_COMPOSITE0,
@@ -1265,6 +1281,7 @@ struct em28xx_board em28xx_boards[] = {
1265 .decoder = EM28XX_SAA711X, 1281 .decoder = EM28XX_SAA711X,
1266 .has_dvb = 1, 1282 .has_dvb = 1,
1267 .dvb_gpio = em2882_kworld_315u_digital, 1283 .dvb_gpio = em2882_kworld_315u_digital,
1284 .ir_codes = &ir_codes_kworld_315u_table,
1268 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, 1285 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1269 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, 1286 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE,
1270 /* Analog mode - still not ready */ 1287 /* Analog mode - still not ready */
@@ -1431,6 +1448,21 @@ struct em28xx_board em28xx_boards[] = {
1431 .gpio = hauppauge_wintv_hvr_900_analog, 1448 .gpio = hauppauge_wintv_hvr_900_analog,
1432 } }, 1449 } },
1433 }, 1450 },
1451 [EM2882_BOARD_DIKOM_DK300] = {
1452 .name = "Dikom DK300",
1453 .tuner_type = TUNER_XC2028,
1454 .tuner_gpio = default_tuner_gpio,
1455 .decoder = EM28XX_TVP5150,
1456 .mts_firmware = 1,
1457 .has_dvb = 1,
1458 .dvb_gpio = dikom_dk300_digital,
1459 .input = { {
1460 .type = EM28XX_VMUX_TELEVISION,
1461 .vmux = TVP5150_COMPOSITE0,
1462 .amux = EM28XX_AMUX_VIDEO,
1463 .gpio = default_analog,
1464 } },
1465 },
1434 [EM2883_BOARD_KWORLD_HYBRID_330U] = { 1466 [EM2883_BOARD_KWORLD_HYBRID_330U] = {
1435 .name = "Kworld PlusTV HD Hybrid 330", 1467 .name = "Kworld PlusTV HD Hybrid 330",
1436 .tuner_type = TUNER_XC2028, 1468 .tuner_type = TUNER_XC2028,
@@ -1751,6 +1783,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1751 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1783 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
1752 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, 1784 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
1753 {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT}, 1785 {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
1786 {0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028},
1754}; 1787};
1755 1788
1756/* I2C devicelist hash table for devices with generic USB IDs */ 1789/* I2C devicelist hash table for devices with generic USB IDs */
@@ -2103,6 +2136,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2103 ctl->demod = XC3028_FE_DEFAULT; 2136 ctl->demod = XC3028_FE_DEFAULT;
2104 break; 2137 break;
2105 case EM2883_BOARD_KWORLD_HYBRID_330U: 2138 case EM2883_BOARD_KWORLD_HYBRID_330U:
2139 case EM2882_BOARD_DIKOM_DK300:
2106 ctl->demod = XC3028_FE_CHINA; 2140 ctl->demod = XC3028_FE_CHINA;
2107 ctl->fname = XC2028_DEFAULT_FIRMWARE; 2141 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2108 break; 2142 break;
@@ -2259,9 +2293,12 @@ static int em28xx_hint_board(struct em28xx *dev)
2259/* ----------------------------------------------------------------------- */ 2293/* ----------------------------------------------------------------------- */
2260void em28xx_register_i2c_ir(struct em28xx *dev) 2294void em28xx_register_i2c_ir(struct em28xx *dev)
2261{ 2295{
2296 /* Leadtek winfast tv USBII deluxe can find a non working IR-device */
2297 /* at address 0x18, so if that address is needed for another board in */
2298 /* the future, please put it after 0x1f. */
2262 struct i2c_board_info info; 2299 struct i2c_board_info info;
2263 const unsigned short addr_list[] = { 2300 const unsigned short addr_list[] = {
2264 0x30, 0x47, I2C_CLIENT_END 2301 0x1f, 0x30, 0x47, I2C_CLIENT_END
2265 }; 2302 };
2266 2303
2267 if (disable_ir) 2304 if (disable_ir)
@@ -2288,6 +2325,10 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2288 dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table; 2325 dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table;
2289 dev->init_data.get_key = em28xx_get_key_em_haup; 2326 dev->init_data.get_key = em28xx_get_key_em_haup;
2290 dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; 2327 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2328 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
2329 dev->init_data.ir_codes = &ir_codes_winfast_usbii_deluxe_table;;
2330 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
2331 dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
2291 break; 2332 break;
2292 } 2333 }
2293 2334
@@ -2381,6 +2422,31 @@ void em28xx_card_setup(struct em28xx *dev)
2381 em28xx_gpio_set(dev, dev->board.tuner_gpio); 2422 em28xx_gpio_set(dev, dev->board.tuner_gpio);
2382 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 2423 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
2383 break; 2424 break;
2425
2426/*
2427 * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR.
2428 *
2429 * This occurs because they share identical USB vendor and
2430 * product IDs.
2431 *
2432 * What we do here is look up the EEPROM hash of the Dikom
2433 * and if it is found then we decide that we do not have
2434 * a Kworld and reset the device to the Dikom instead.
2435 *
2436 * This solution is only valid if they do not share eeprom
2437 * hash identities which has not been determined as yet.
2438 */
2439 case EM2882_BOARD_KWORLD_VS_DVBT:
2440 if (!em28xx_hint_board(dev))
2441 em28xx_set_model(dev);
2442
2443 /* In cases where we had to use a board hint, the call to
2444 em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
2445 so make the call now so the analog GPIOs are set properly
2446 before probing the i2c bus. */
2447 em28xx_gpio_set(dev, dev->board.tuner_gpio);
2448 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
2449 break;
2384 } 2450 }
2385 2451
2386#if defined(CONFIG_MODULES) && defined(MODULE) 2452#if defined(CONFIG_MODULES) && defined(MODULE)
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index b311d4514bdf..5a37eccbd7d6 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -691,9 +691,15 @@ int em28xx_set_outfmt(struct em28xx *dev)
691 if (em28xx_vbi_supported(dev) == 1) { 691 if (em28xx_vbi_supported(dev) == 1) {
692 vinctrl |= EM28XX_VINCTRL_VBI_RAW; 692 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
693 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); 693 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
694 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); 694 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
695 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4); 695 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
696 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c); 696 if (dev->norm & V4L2_STD_525_60) {
697 /* NTSC */
698 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
699 } else if (dev->norm & V4L2_STD_625_50) {
700 /* PAL */
701 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
702 }
697 } 703 }
698 704
699 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl); 705 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
@@ -760,6 +766,13 @@ int em28xx_resolution_set(struct em28xx *dev)
760 width = norm_maxw(dev); 766 width = norm_maxw(dev);
761 height = norm_maxh(dev); 767 height = norm_maxh(dev);
762 768
769 /* Properly setup VBI */
770 dev->vbi_width = 720;
771 if (dev->norm & V4L2_STD_525_60)
772 dev->vbi_height = 12;
773 else
774 dev->vbi_height = 18;
775
763 if (!dev->progressive) 776 if (!dev->progressive)
764 height >>= norm_maxh(dev); 777 height >>= norm_maxh(dev);
765 778
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index cc0505eb900f..1b96356b3ab2 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -502,7 +502,9 @@ static int dvb_init(struct em28xx *dev)
502 } 502 }
503 break; 503 break;
504 case EM2880_BOARD_TERRATEC_HYBRID_XS: 504 case EM2880_BOARD_TERRATEC_HYBRID_XS:
505 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
505 case EM2881_BOARD_PINNACLE_HYBRID_PRO: 506 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
507 case EM2882_BOARD_DIKOM_DK300:
506 dvb->frontend = dvb_attach(zl10353_attach, 508 dvb->frontend = dvb_attach(zl10353_attach,
507 &em28xx_zl10353_xc3028_no_i2c_gate, 509 &em28xx_zl10353_xc3028_no_i2c_gate,
508 &dev->i2c_adap); 510 &dev->i2c_adap);
@@ -606,6 +608,7 @@ static int dvb_fini(struct em28xx *dev)
606 608
607 if (dev->dvb) { 609 if (dev->dvb) {
608 unregister_dvb(dev->dvb); 610 unregister_dvb(dev->dvb);
611 kfree(dev->dvb);
609 dev->dvb = NULL; 612 dev->dvb = NULL;
610 } 613 }
611 614
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index af0d935c29be..1fb754e20875 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -75,6 +75,10 @@ struct em28xx_IR {
75 unsigned int repeat_interval; 75 unsigned int repeat_interval;
76 76
77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); 77 int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
78
79 /* IR device properties */
80
81 struct ir_dev_props props;
78}; 82};
79 83
80/********************************************************** 84/**********************************************************
@@ -180,6 +184,36 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
180 return 1; 184 return 1;
181} 185}
182 186
187int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
188{
189 unsigned char subaddr, keydetect, key;
190
191 struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1},
192
193 { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
194
195 subaddr = 0x10;
196 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
197 i2cdprintk("read error\n");
198 return -EIO;
199 }
200 if (keydetect == 0x00)
201 return 0;
202
203 subaddr = 0x00;
204 msg[1].buf = &key;
205 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
206 i2cdprintk("read error\n");
207 return -EIO;
208 }
209 if (key == 0x00)
210 return 0;
211
212 *ir_key = key;
213 *ir_raw = key;
214 return 1;
215}
216
183/********************************************************** 217/**********************************************************
184 Poll based get keycode functions 218 Poll based get keycode functions
185 **********************************************************/ 219 **********************************************************/
@@ -336,35 +370,28 @@ static void em28xx_ir_stop(struct em28xx_IR *ir)
336 cancel_delayed_work_sync(&ir->work); 370 cancel_delayed_work_sync(&ir->work);
337} 371}
338 372
339int em28xx_ir_init(struct em28xx *dev) 373int em28xx_ir_change_protocol(void *priv, u64 ir_type)
340{ 374{
341 struct em28xx_IR *ir; 375 int rc = 0;
342 struct input_dev *input_dev; 376 struct em28xx_IR *ir = priv;
343 u8 ir_config; 377 struct em28xx *dev = ir->dev;
344 int err = -ENOMEM; 378 u8 ir_config = EM2874_IR_RC5;
345
346 if (dev->board.ir_codes == NULL) {
347 /* No remote control support */
348 return 0;
349 }
350
351 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
352 input_dev = input_allocate_device();
353 if (!ir || !input_dev)
354 goto err_out_free;
355
356 ir->input = input_dev;
357 ir_config = EM2874_IR_RC5;
358 379
359 /* Adjust xclk based o IR table for RC5/NEC tables */ 380 /* Adjust xclk based o IR table for RC5/NEC tables */
360 if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { 381
382 dev->board.ir_codes->ir_type = IR_TYPE_OTHER;
383 if (ir_type == IR_TYPE_RC5) {
361 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; 384 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
362 ir->full_code = 1; 385 ir->full_code = 1;
363 } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { 386 } else if (ir_type == IR_TYPE_NEC) {
364 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; 387 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
365 ir_config = EM2874_IR_NEC; 388 ir_config = EM2874_IR_NEC;
366 ir->full_code = 1; 389 ir->full_code = 1;
367 } 390 } else
391 rc = -EINVAL;
392
393 dev->board.ir_codes->ir_type = ir_type;
394
368 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, 395 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
369 EM28XX_XCLK_IR_RC5_MODE); 396 EM28XX_XCLK_IR_RC5_MODE);
370 397
@@ -380,9 +407,42 @@ int em28xx_ir_init(struct em28xx *dev)
380 break; 407 break;
381 default: 408 default:
382 printk("Unrecognized em28xx chip id: IR not supported\n"); 409 printk("Unrecognized em28xx chip id: IR not supported\n");
383 goto err_out_free; 410 rc = -EINVAL;
411 }
412
413 return rc;
414}
415
416int em28xx_ir_init(struct em28xx *dev)
417{
418 struct em28xx_IR *ir;
419 struct input_dev *input_dev;
420 int err = -ENOMEM;
421
422 if (dev->board.ir_codes == NULL) {
423 /* No remote control support */
424 return 0;
384 } 425 }
385 426
427 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
428 input_dev = input_allocate_device();
429 if (!ir || !input_dev)
430 goto err_out_free;
431
432 /* record handles to ourself */
433 ir->dev = dev;
434 dev->ir = ir;
435
436 ir->input = input_dev;
437
438 /*
439 * em2874 supports more protocols. For now, let's just announce
440 * the two protocols that were already tested
441 */
442 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
443 ir->props.priv = ir;
444 ir->props.change_protocol = em28xx_ir_change_protocol;
445
386 /* This is how often we ask the chip for IR information */ 446 /* This is how often we ask the chip for IR information */
387 ir->polling = 100; /* ms */ 447 ir->polling = 100; /* ms */
388 448
@@ -393,6 +453,8 @@ int em28xx_ir_init(struct em28xx *dev)
393 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 453 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
394 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 454 strlcat(ir->phys, "/input0", sizeof(ir->phys));
395 455
456 /* Set IR protocol */
457 em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type);
396 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); 458 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
397 if (err < 0) 459 if (err < 0)
398 goto err_out_free; 460 goto err_out_free;
@@ -405,14 +467,13 @@ int em28xx_ir_init(struct em28xx *dev)
405 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); 467 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
406 468
407 input_dev->dev.parent = &dev->udev->dev; 469 input_dev->dev.parent = &dev->udev->dev;
408 /* record handles to ourself */ 470
409 ir->dev = dev;
410 dev->ir = ir;
411 471
412 em28xx_ir_start(ir); 472 em28xx_ir_start(ir);
413 473
414 /* all done */ 474 /* all done */
415 err = ir_input_register(ir->input, dev->board.ir_codes); 475 err = ir_input_register(ir->input, dev->board.ir_codes,
476 &ir->props);
416 if (err) 477 if (err)
417 goto err_out_stop; 478 goto err_out_stop;
418 479
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 058ac87639ce..91e90559642b 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -173,8 +173,8 @@
173/* em2874 IR config register (0x50) */ 173/* em2874 IR config register (0x50) */
174#define EM2874_IR_NEC 0x00 174#define EM2874_IR_NEC 0x00
175#define EM2874_IR_RC5 0x04 175#define EM2874_IR_RC5 0x04
176#define EM2874_IR_RC5_MODE_0 0x08 176#define EM2874_IR_RC6_MODE_0 0x08
177#define EM2874_IR_RC5_MODE_6A 0x0b 177#define EM2874_IR_RC6_MODE_6A 0x0b
178 178
179/* em2874 Transport Stream Enable Register (0x5f) */ 179/* em2874 Transport Stream Enable Register (0x5f) */
180#define EM2874_TS1_CAPTURE_ENABLE (1 << 0) 180#define EM2874_TS1_CAPTURE_ENABLE (1 << 0)
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
index 94943e5a1529..c7dce39823d8 100644
--- a/drivers/media/video/em28xx/em28xx-vbi.c
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -71,7 +71,11 @@ free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
71static int 71static int
72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
73{ 73{
74 *size = 720 * 12 * 2; 74 struct em28xx_fh *fh = q->priv_data;
75 struct em28xx *dev = fh->dev;
76
77 *size = dev->vbi_width * dev->vbi_height * 2;
78
75 if (0 == *count) 79 if (0 == *count)
76 *count = vbibufs; 80 *count = vbibufs;
77 if (*count < 2) 81 if (*count < 2)
@@ -85,19 +89,18 @@ static int
85vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, 89vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
86 enum v4l2_field field) 90 enum v4l2_field field)
87{ 91{
92 struct em28xx_fh *fh = q->priv_data;
93 struct em28xx *dev = fh->dev;
88 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); 94 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
89 int rc = 0; 95 int rc = 0;
90 unsigned int size;
91
92 size = 720 * 12 * 2;
93 96
94 buf->vb.size = size; 97 buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
95 98
96 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 99 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
97 return -EINVAL; 100 return -EINVAL;
98 101
99 buf->vb.width = 720; 102 buf->vb.width = dev->vbi_width;
100 buf->vb.height = 12; 103 buf->vb.height = dev->vbi_height;
101 buf->vb.field = field; 104 buf->vb.field = field;
102 105
103 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 106 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 849b18c94037..ac2bd935927e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -282,7 +282,7 @@ static void em28xx_copy_vbi(struct em28xx *dev,
282{ 282{
283 void *startwrite, *startread; 283 void *startwrite, *startread;
284 int offset; 284 int offset;
285 int bytesperline = 720; 285 int bytesperline = dev->vbi_width;
286 286
287 if (dev == NULL) { 287 if (dev == NULL) {
288 em28xx_isocdbg("dev is null\n"); 288 em28xx_isocdbg("dev is null\n");
@@ -323,8 +323,8 @@ static void em28xx_copy_vbi(struct em28xx *dev,
323 323
324 /* Make sure the bottom field populates the second half of the frame */ 324 /* Make sure the bottom field populates the second half of the frame */
325 if (buf->top_field == 0) { 325 if (buf->top_field == 0) {
326 startwrite += bytesperline * 0x0c; 326 startwrite += bytesperline * dev->vbi_height;
327 offset += bytesperline * 0x0c; 327 offset += bytesperline * dev->vbi_height;
328 } 328 }
329 329
330 memcpy(startwrite, startread, len); 330 memcpy(startwrite, startread, len);
@@ -578,8 +578,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
578 dev->cur_field = p[2]; 578 dev->cur_field = p[2];
579 } 579 }
580 580
581 /* FIXME: get rid of hard-coded value */ 581 vbi_size = dev->vbi_width * dev->vbi_height;
582 vbi_size = 720 * 0x0c;
583 582
584 if (dev->capture_type == 0) { 583 if (dev->capture_type == 0) {
585 if (dev->vbi_read >= vbi_size) { 584 if (dev->vbi_read >= vbi_size) {
@@ -1850,18 +1849,27 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
1850static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, 1849static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1851 struct v4l2_format *format) 1850 struct v4l2_format *format)
1852{ 1851{
1853 format->fmt.vbi.samples_per_line = 720; 1852 struct em28xx_fh *fh = priv;
1853 struct em28xx *dev = fh->dev;
1854
1855 format->fmt.vbi.samples_per_line = dev->vbi_width;
1854 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 1856 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1855 format->fmt.vbi.offset = 0; 1857 format->fmt.vbi.offset = 0;
1856 format->fmt.vbi.flags = 0; 1858 format->fmt.vbi.flags = 0;
1859 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1860 format->fmt.vbi.count[0] = dev->vbi_height;
1861 format->fmt.vbi.count[1] = dev->vbi_height;
1857 1862
1858 /* Varies by video standard (NTSC, PAL, etc.) */ 1863 /* Varies by video standard (NTSC, PAL, etc.) */
1859 /* FIXME: hard-coded for NTSC support */ 1864 if (dev->norm & V4L2_STD_525_60) {
1860 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ 1865 /* NTSC */
1861 format->fmt.vbi.count[0] = 12; 1866 format->fmt.vbi.start[0] = 10;
1862 format->fmt.vbi.count[1] = 12; 1867 format->fmt.vbi.start[1] = 273;
1863 format->fmt.vbi.start[0] = 10; 1868 } else if (dev->norm & V4L2_STD_625_50) {
1864 format->fmt.vbi.start[1] = 273; 1869 /* PAL */
1870 format->fmt.vbi.start[0] = 6;
1871 format->fmt.vbi.start[1] = 318;
1872 }
1865 1873
1866 return 0; 1874 return 0;
1867} 1875}
@@ -1869,18 +1877,27 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1869static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, 1877static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
1870 struct v4l2_format *format) 1878 struct v4l2_format *format)
1871{ 1879{
1872 format->fmt.vbi.samples_per_line = 720; 1880 struct em28xx_fh *fh = priv;
1881 struct em28xx *dev = fh->dev;
1882
1883 format->fmt.vbi.samples_per_line = dev->vbi_width;
1873 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 1884 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1874 format->fmt.vbi.offset = 0; 1885 format->fmt.vbi.offset = 0;
1875 format->fmt.vbi.flags = 0; 1886 format->fmt.vbi.flags = 0;
1887 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1888 format->fmt.vbi.count[0] = dev->vbi_height;
1889 format->fmt.vbi.count[1] = dev->vbi_height;
1876 1890
1877 /* Varies by video standard (NTSC, PAL, etc.) */ 1891 /* Varies by video standard (NTSC, PAL, etc.) */
1878 /* FIXME: hard-coded for NTSC support */ 1892 if (dev->norm & V4L2_STD_525_60) {
1879 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */ 1893 /* NTSC */
1880 format->fmt.vbi.count[0] = 12; 1894 format->fmt.vbi.start[0] = 10;
1881 format->fmt.vbi.count[1] = 12; 1895 format->fmt.vbi.start[1] = 273;
1882 format->fmt.vbi.start[0] = 10; 1896 } else if (dev->norm & V4L2_STD_625_50) {
1883 format->fmt.vbi.start[1] = 273; 1897 /* PAL */
1898 format->fmt.vbi.start[0] = 6;
1899 format->fmt.vbi.start[1] = 318;
1900 }
1884 1901
1885 return 0; 1902 return 0;
1886} 1903}
@@ -1922,7 +1939,8 @@ static int vidioc_querybuf(struct file *file, void *priv,
1922 At a minimum, it causes a crash in zvbi since it does 1939 At a minimum, it causes a crash in zvbi since it does
1923 a memcpy based on the source buffer length */ 1940 a memcpy based on the source buffer length */
1924 int result = videobuf_querybuf(&fh->vb_vbiq, b); 1941 int result = videobuf_querybuf(&fh->vb_vbiq, b);
1925 b->length = 17280; 1942 b->length = dev->vbi_width * dev->vbi_height * 2;
1943
1926 return result; 1944 return result;
1927 } 1945 }
1928} 1946}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 80d9b4fa1b97..ba6fe5daff84 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -111,6 +111,7 @@
111#define EM2861_BOARD_GADMEI_UTV330PLUS 72 111#define EM2861_BOARD_GADMEI_UTV330PLUS 72
112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
113#define EM2800_BOARD_VC211A 74 113#define EM2800_BOARD_VC211A 74
114#define EM2882_BOARD_DIKOM_DK300 75
114 115
115/* Limits minimum and default number of buffers */ 116/* Limits minimum and default number of buffers */
116#define EM28XX_MIN_BUF 4 117#define EM28XX_MIN_BUF 4
@@ -552,7 +553,8 @@ struct em28xx {
552 int capture_type; 553 int capture_type;
553 int vbi_read; 554 int vbi_read;
554 unsigned char cur_field; 555 unsigned char cur_field;
555 556 unsigned int vbi_width;
557 unsigned int vbi_height; /* lines per field */
556 558
557 struct work_struct request_module_wk; 559 struct work_struct request_module_wk;
558 560
@@ -693,6 +695,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
693int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); 695int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
694int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, 696int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
695 u32 *ir_raw); 697 u32 *ir_raw);
698int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
699 u32 *ir_raw);
696void em28xx_register_snapshot_button(struct em28xx *dev); 700void em28xx_register_snapshot_button(struct em28xx *dev);
697void em28xx_deregister_snapshot_button(struct em28xx *dev); 701void em28xx_deregister_snapshot_button(struct em28xx *dev);
698 702
diff --git a/drivers/media/video/et61x251/Kconfig b/drivers/media/video/et61x251/Kconfig
index dcc1a0335440..87981b078fe6 100644
--- a/drivers/media/video/et61x251/Kconfig
+++ b/drivers/media/video/et61x251/Kconfig
@@ -1,7 +1,11 @@
1config USB_ET61X251 1config USB_ET61X251
2 tristate "USB ET61X[12]51 PC Camera Controller support" 2 tristate "USB ET61X[12]51 PC Camera Controller support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 default n
4 ---help--- 5 ---help---
6 This driver is DEPRECATED please use the gspca zc3xx module
7 instead.
8
5 Say Y here if you want support for cameras based on Etoms ET61X151 9 Say Y here if you want support for cameras based on Etoms ET61X151
6 or ET61X251 PC Camera Controllers. 10 or ET61X251 PC Camera Controllers.
7 11
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 609d65b0b10d..e0060c1f0544 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -21,6 +21,15 @@ source "drivers/media/video/gspca/m5602/Kconfig"
21source "drivers/media/video/gspca/stv06xx/Kconfig" 21source "drivers/media/video/gspca/stv06xx/Kconfig"
22source "drivers/media/video/gspca/gl860/Kconfig" 22source "drivers/media/video/gspca/gl860/Kconfig"
23 23
24config USB_GSPCA_BENQ
25 tristate "Benq USB Camera Driver"
26 depends on VIDEO_V4L2 && USB_GSPCA
27 help
28 Say Y here if you want support for the Benq DC E300 camera.
29
30 To compile this driver as a module, choose M here: the
31 module will be called gspca_benq.
32
24config USB_GSPCA_CONEX 33config USB_GSPCA_CONEX
25 tristate "Conexant Camera Driver" 34 tristate "Conexant Camera Driver"
26 depends on VIDEO_V4L2 && USB_GSPCA 35 depends on VIDEO_V4L2 && USB_GSPCA
@@ -30,6 +39,17 @@ config USB_GSPCA_CONEX
30 To compile this driver as a module, choose M here: the 39 To compile this driver as a module, choose M here: the
31 module will be called gspca_conex. 40 module will be called gspca_conex.
32 41
42config USB_GSPCA_CPIA1
43 tristate "cpia CPiA (version 1) Camera Driver"
44 depends on VIDEO_V4L2 && USB_GSPCA
45 help
46 Say Y here if you want support for USB cameras based on the cpia
47 CPiA chip. Note that you need atleast version 0.6.4 of libv4l for
48 applications to understand the videoformat generated by this driver.
49
50 To compile this driver as a module, choose M here: the
51 module will be called gspca_cpia1.
52
33config USB_GSPCA_ETOMS 53config USB_GSPCA_ETOMS
34 tristate "Etoms USB Camera Driver" 54 tristate "Etoms USB Camera Driver"
35 depends on VIDEO_V4L2 && USB_GSPCA 55 depends on VIDEO_V4L2 && USB_GSPCA
@@ -86,15 +106,25 @@ config USB_GSPCA_OV519
86 module will be called gspca_ov519. 106 module will be called gspca_ov519.
87 107
88config USB_GSPCA_OV534 108config USB_GSPCA_OV534
89 tristate "OV534 USB Camera Driver" 109 tristate "OV534 OV772x USB Camera Driver"
90 depends on VIDEO_V4L2 && USB_GSPCA 110 depends on VIDEO_V4L2 && USB_GSPCA
91 help 111 help
92 Say Y here if you want support for cameras based on the OV534 chip. 112 Say Y here if you want support for cameras based on the OV534 chip
93 (e.g. Sony Playstation EYE) 113 and sensor OV772x (e.g. Sony Playstation EYE)
94 114
95 To compile this driver as a module, choose M here: the 115 To compile this driver as a module, choose M here: the
96 module will be called gspca_ov534. 116 module will be called gspca_ov534.
97 117
118config USB_GSPCA_OV534_9
119 tristate "OV534 OV965x USB Camera Driver"
120 depends on VIDEO_V4L2 && USB_GSPCA
121 help
122 Say Y here if you want support for cameras based on the OV534 chip
123 and sensor OV965x (e.g. Hercules Dualpix)
124
125 To compile this driver as a module, choose M here: the
126 module will be called gspca_ov534_9.
127
98config USB_GSPCA_PAC207 128config USB_GSPCA_PAC207
99 tristate "Pixart PAC207 USB Camera Driver" 129 tristate "Pixart PAC207 USB Camera Driver"
100 depends on VIDEO_V4L2 && USB_GSPCA 130 depends on VIDEO_V4L2 && USB_GSPCA
@@ -122,6 +152,16 @@ config USB_GSPCA_PAC7311
122 To compile this driver as a module, choose M here: the 152 To compile this driver as a module, choose M here: the
123 module will be called gspca_pac7311. 153 module will be called gspca_pac7311.
124 154
155config USB_GSPCA_SN9C2028
156 tristate "SONIX Dual-Mode USB Camera Driver"
157 depends on VIDEO_V4L2 && USB_GSPCA
158 help
159 Say Y here if you want streaming support for Sonix SN9C2028 cameras.
160 These are supported as stillcams in libgphoto2/camlibs/sonix.
161
162 To compile this driver as a module, choose M here: the
163 module will be called gspca_sn9c2028.
164
125config USB_GSPCA_SN9C20X 165config USB_GSPCA_SN9C20X
126 tristate "SN9C20X USB Camera Driver" 166 tristate "SN9C20X USB Camera Driver"
127 depends on VIDEO_V4L2 && USB_GSPCA 167 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index ff2c7279d82e..6e4cf1ce01c9 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,5 +1,7 @@
1obj-$(CONFIG_USB_GSPCA) += gspca_main.o 1obj-$(CONFIG_USB_GSPCA) += gspca_main.o
2obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o
2obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o 3obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
4obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o
3obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o 5obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 6obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
5obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o 7obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
@@ -7,9 +9,11 @@ obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
7obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 9obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 10obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
9obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 11obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
12obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o
10obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 13obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
11obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o 14obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o
12obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 15obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
16obj-$(CONFIG_USB_GSPCA_SN9C2028) += gspca_sn9c2028.o
13obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o 17obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o
14obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 18obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
15obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o 19obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
@@ -30,7 +34,9 @@ obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
30obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o 34obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
31 35
32gspca_main-objs := gspca.o 36gspca_main-objs := gspca.o
37gspca_benq-objs := benq.o
33gspca_conex-objs := conex.o 38gspca_conex-objs := conex.o
39gspca_cpia1-objs := cpia1.o
34gspca_etoms-objs := etoms.o 40gspca_etoms-objs := etoms.o
35gspca_finepix-objs := finepix.o 41gspca_finepix-objs := finepix.o
36gspca_jeilinj-objs := jeilinj.o 42gspca_jeilinj-objs := jeilinj.o
@@ -38,9 +44,11 @@ gspca_mars-objs := mars.o
38gspca_mr97310a-objs := mr97310a.o 44gspca_mr97310a-objs := mr97310a.o
39gspca_ov519-objs := ov519.o 45gspca_ov519-objs := ov519.o
40gspca_ov534-objs := ov534.o 46gspca_ov534-objs := ov534.o
47gspca_ov534_9-objs := ov534_9.o
41gspca_pac207-objs := pac207.o 48gspca_pac207-objs := pac207.o
42gspca_pac7302-objs := pac7302.o 49gspca_pac7302-objs := pac7302.o
43gspca_pac7311-objs := pac7311.o 50gspca_pac7311-objs := pac7311.o
51gspca_sn9c2028-objs := sn9c2028.o
44gspca_sn9c20x-objs := sn9c20x.o 52gspca_sn9c20x-objs := sn9c20x.o
45gspca_sonixb-objs := sonixb.o 53gspca_sonixb-objs := sonixb.o
46gspca_sonixj-objs := sonixj.o 54gspca_sonixj-objs := sonixj.o
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c
new file mode 100644
index 000000000000..43ac4af8d3ed
--- /dev/null
+++ b/drivers/media/video/gspca/benq.c
@@ -0,0 +1,322 @@
1/*
2 * Benq DC E300 subdriver
3 *
4 * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr)
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 * 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#define MODULE_NAME "benq"
22
23#include "gspca.h"
24
25MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
26MODULE_DESCRIPTION("Benq DC E300 USB Camera Driver");
27MODULE_LICENSE("GPL");
28
29/* specific webcam descriptor */
30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */
32};
33
34/* V4L2 controls supported by the driver */
35static const struct ctrl sd_ctrls[] = {
36};
37
38static const struct v4l2_pix_format vga_mode[] = {
39 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
40 .bytesperline = 320,
41 .sizeimage = 320 * 240 * 3 / 8 + 590,
42 .colorspace = V4L2_COLORSPACE_JPEG},
43};
44
45static void sd_isoc_irq(struct urb *urb);
46
47/* -- write a register -- */
48static void reg_w(struct gspca_dev *gspca_dev,
49 u16 value, u16 index)
50{
51 struct usb_device *dev = gspca_dev->dev;
52 int ret;
53
54 if (gspca_dev->usb_err < 0)
55 return;
56 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
57 0x02,
58 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
59 value,
60 index,
61 NULL,
62 0,
63 500);
64 if (ret < 0) {
65 PDEBUG(D_ERR, "reg_w err %d", ret);
66 gspca_dev->usb_err = ret;
67 }
68}
69
70/* this function is called at probe time */
71static int sd_config(struct gspca_dev *gspca_dev,
72 const struct usb_device_id *id)
73{
74 gspca_dev->cam.cam_mode = vga_mode;
75 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
76 gspca_dev->cam.no_urb_create = 1;
77 gspca_dev->cam.reverse_alts = 1;
78 return 0;
79}
80
81/* this function is called at probe and resume time */
82static int sd_init(struct gspca_dev *gspca_dev)
83{
84 return 0;
85}
86
87static int sd_isoc_init(struct gspca_dev *gspca_dev)
88{
89 int ret;
90
91 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface,
92 gspca_dev->nbalt - 1);
93 if (ret < 0) {
94 err("usb_set_interface failed");
95 return ret;
96 }
97/* reg_w(gspca_dev, 0x0003, 0x0002); */
98 return 0;
99}
100
101/* -- start the camera -- */
102static int sd_start(struct gspca_dev *gspca_dev)
103{
104 struct urb *urb;
105 int i, n;
106
107 /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
108#if MAX_NURBS < 4
109#error "Not enough URBs in the gspca table"
110#endif
111#define SD_PKT_SZ 64
112#define SD_NPKT 32
113 for (n = 0; n < 4; n++) {
114 urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
115 if (!urb) {
116 err("usb_alloc_urb failed");
117 return -ENOMEM;
118 }
119 gspca_dev->urb[n] = urb;
120 urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
121 SD_PKT_SZ * SD_NPKT,
122 GFP_KERNEL,
123 &urb->transfer_dma);
124
125 if (urb->transfer_buffer == NULL) {
126 err("usb_buffer_alloc failed");
127 return -ENOMEM;
128 }
129 urb->dev = gspca_dev->dev;
130 urb->context = gspca_dev;
131 urb->transfer_buffer_length = SD_PKT_SZ * SD_NPKT;
132 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
133 n & 1 ? 0x82 : 0x83);
134 urb->transfer_flags = URB_ISO_ASAP
135 | URB_NO_TRANSFER_DMA_MAP;
136 urb->interval = 1;
137 urb->complete = sd_isoc_irq;
138 urb->number_of_packets = SD_NPKT;
139 for (i = 0; i < SD_NPKT; i++) {
140 urb->iso_frame_desc[i].length = SD_PKT_SZ;
141 urb->iso_frame_desc[i].offset = SD_PKT_SZ * i;
142 }
143 }
144
145 return gspca_dev->usb_err;
146}
147
148static void sd_stopN(struct gspca_dev *gspca_dev)
149{
150 reg_w(gspca_dev, 0x003c, 0x0003);
151 reg_w(gspca_dev, 0x003c, 0x0004);
152 reg_w(gspca_dev, 0x003c, 0x0005);
153 reg_w(gspca_dev, 0x003c, 0x0006);
154 reg_w(gspca_dev, 0x003c, 0x0007);
155 usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->nbalt - 1);
156}
157
158static void sd_pkt_scan(struct gspca_dev *gspca_dev,
159 u8 *data, /* isoc packet */
160 int len) /* iso packet length */
161{
162 /* unused */
163}
164
165/* reception of an URB */
166static void sd_isoc_irq(struct urb *urb)
167{
168 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
169 struct urb *urb0;
170 u8 *data;
171 int i, st;
172
173 PDEBUG(D_PACK, "sd isoc irq");
174 if (!gspca_dev->streaming)
175 return;
176 if (urb->status != 0) {
177 if (urb->status == -ESHUTDOWN)
178 return; /* disconnection */
179#ifdef CONFIG_PM
180 if (gspca_dev->frozen)
181 return;
182#endif
183 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
184 return;
185 }
186
187 /* if this is a control URN (ep 0x83), wait */
188 if (urb == gspca_dev->urb[0] || urb == gspca_dev->urb[2])
189 return;
190
191 /* scan both received URBs */
192 if (urb == gspca_dev->urb[1])
193 urb0 = gspca_dev->urb[0];
194 else
195 urb0 = gspca_dev->urb[2];
196 for (i = 0; i < urb->number_of_packets; i++) {
197
198 /* check the packet status and length */
199 if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
200 || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
201 PDEBUG(D_ERR, "ISOC bad lengths %d / %d",
202 urb0->iso_frame_desc[i].actual_length,
203 urb->iso_frame_desc[i].actual_length);
204 gspca_dev->last_packet_type = DISCARD_PACKET;
205 continue;
206 }
207 st = urb0->iso_frame_desc[i].status;
208 if (st == 0)
209 st = urb->iso_frame_desc[i].status;
210 if (st) {
211 PDEBUG(D_ERR,
212 "ISOC data error: [%d] status=%d",
213 i, st);
214 gspca_dev->last_packet_type = DISCARD_PACKET;
215 continue;
216 }
217
218 /*
219 * The images are received in URBs of different endpoints
220 * (0x83 and 0x82).
221 * Image pieces in URBs of ep 0x83 are continuated in URBs of
222 * ep 0x82 of the same index.
223 * The packets in the URBs of endpoint 0x83 start with:
224 * - 80 ba/bb 00 00 = start of image followed by 'ff d8'
225 * - 04 ba/bb oo oo = image piece
226 * where 'oo oo' is the image offset
227 (not cheked)
228 * - (other -> bad frame)
229 * The images are JPEG encoded with full header and
230 * normal ff escape.
231 * The end of image ('ff d9') may occur in any URB.
232 * (not cheked)
233 */
234 data = (u8 *) urb0->transfer_buffer
235 + urb0->iso_frame_desc[i].offset;
236 if (data[0] == 0x80 && (data[1] & 0xfe) == 0xba) {
237
238 /* new image */
239 gspca_frame_add(gspca_dev, LAST_PACKET,
240 NULL, 0);
241 gspca_frame_add(gspca_dev, FIRST_PACKET,
242 data + 4, SD_PKT_SZ - 4);
243 } else if (data[0] == 0x04 && (data[1] & 0xfe) == 0xba) {
244 gspca_frame_add(gspca_dev, INTER_PACKET,
245 data + 4, SD_PKT_SZ - 4);
246 } else {
247 gspca_dev->last_packet_type = DISCARD_PACKET;
248 continue;
249 }
250 data = (u8 *) urb->transfer_buffer
251 + urb->iso_frame_desc[i].offset;
252 gspca_frame_add(gspca_dev, INTER_PACKET,
253 data, SD_PKT_SZ);
254 }
255
256 /* resubmit the URBs */
257 st = usb_submit_urb(urb0, GFP_ATOMIC);
258 if (st < 0)
259 PDEBUG(D_ERR|D_PACK, "usb_submit_urb(0) ret %d", st);
260 st = usb_submit_urb(urb, GFP_ATOMIC);
261 if (st < 0)
262 PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
263}
264
265/* sub-driver description */
266static const struct sd_desc sd_desc = {
267 .name = MODULE_NAME,
268 .ctrls = sd_ctrls,
269 .nctrls = ARRAY_SIZE(sd_ctrls),
270 .config = sd_config,
271 .init = sd_init,
272 .isoc_init = sd_isoc_init,
273 .start = sd_start,
274 .stopN = sd_stopN,
275 .pkt_scan = sd_pkt_scan,
276};
277
278/* -- module initialisation -- */
279static const __devinitdata struct usb_device_id device_table[] = {
280 {USB_DEVICE(0x04a5, 0x3035)},
281 {}
282};
283MODULE_DEVICE_TABLE(usb, device_table);
284
285/* -- device connect -- */
286static int sd_probe(struct usb_interface *intf,
287 const struct usb_device_id *id)
288{
289 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
290 THIS_MODULE);
291}
292
293static struct usb_driver sd_driver = {
294 .name = MODULE_NAME,
295 .id_table = device_table,
296 .probe = sd_probe,
297 .disconnect = gspca_disconnect,
298#ifdef CONFIG_PM
299 .suspend = gspca_suspend,
300 .resume = gspca_resume,
301#endif
302};
303
304/* -- module insert / remove -- */
305static int __init sd_mod_init(void)
306{
307 int ret;
308
309 ret = usb_register(&sd_driver);
310 if (ret < 0)
311 return ret;
312 info("registered");
313 return 0;
314}
315static void __exit sd_mod_exit(void)
316{
317 usb_deregister(&sd_driver);
318 info("deregistered");
319}
320
321module_init(sd_mod_init);
322module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/coarse_expo_autogain.h b/drivers/media/video/gspca/coarse_expo_autogain.h
new file mode 100644
index 000000000000..1cb9d941eaf6
--- /dev/null
+++ b/drivers/media/video/gspca/coarse_expo_autogain.h
@@ -0,0 +1,116 @@
1/*
2 * Auto gain algorithm for camera's with a coarse exposure control
3 *
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * 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/* Autogain + exposure algorithm for cameras with a coarse exposure control
22 (usually this means we can only control the clockdiv to change exposure)
23 As changing the clockdiv so that the fps drops from 30 to 15 fps for
24 example, will lead to a huge exposure change (it effectively doubles),
25 this algorithm normally tries to only adjust the gain (between 40 and
26 80 %) and if that does not help, only then changes exposure. This leads
27 to a much more stable image then using the knee algorithm which at
28 certain points of the knee graph will only try to adjust exposure,
29 which leads to oscilating as one exposure step is huge.
30
31 Note this assumes that the sd struct for the cam in question has
32 exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
33
34 Returns 0 if no changes were made, 1 if the gain and or exposure settings
35 where changed. */
36static int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
37 int avg_lum, int desired_avg_lum, int deadzone)
38{
39 int i, steps, gain, orig_gain, exposure, orig_exposure;
40 int gain_low, gain_high;
41 const struct ctrl *gain_ctrl = NULL;
42 const struct ctrl *exposure_ctrl = NULL;
43 struct sd *sd = (struct sd *) gspca_dev;
44 int retval = 0;
45
46 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
47 if (gspca_dev->ctrl_dis & (1 << i))
48 continue;
49 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
50 gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
51 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
52 exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
53 }
54 if (!gain_ctrl || !exposure_ctrl) {
55 PDEBUG(D_ERR, "Error: gspca_coarse_grained_expo_autogain "
56 "called on cam without gain or exposure");
57 return 0;
58 }
59
60 if (gain_ctrl->get(gspca_dev, &gain) ||
61 exposure_ctrl->get(gspca_dev, &exposure))
62 return 0;
63
64 orig_gain = gain;
65 orig_exposure = exposure;
66 gain_low =
67 (gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 2;
68 gain_low += gain_ctrl->qctrl.minimum;
69 gain_high =
70 (gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 4;
71 gain_high += gain_ctrl->qctrl.minimum;
72
73 /* If we are of a multiple of deadzone, do multiple steps to reach the
74 desired lumination fast (with the risc of a slight overshoot) */
75 steps = (desired_avg_lum - avg_lum) / deadzone;
76
77 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
78 avg_lum, desired_avg_lum, steps);
79
80 if ((gain + steps) > gain_high &&
81 sd->exposure < exposure_ctrl->qctrl.maximum) {
82 gain = gain_high;
83 sd->exp_too_low_cnt++;
84 } else if ((gain + steps) < gain_low &&
85 sd->exposure > exposure_ctrl->qctrl.minimum) {
86 gain = gain_low;
87 sd->exp_too_high_cnt++;
88 } else {
89 gain += steps;
90 if (gain > gain_ctrl->qctrl.maximum)
91 gain = gain_ctrl->qctrl.maximum;
92 else if (gain < gain_ctrl->qctrl.minimum)
93 gain = gain_ctrl->qctrl.minimum;
94 sd->exp_too_high_cnt = 0;
95 sd->exp_too_low_cnt = 0;
96 }
97
98 if (sd->exp_too_high_cnt > 3) {
99 exposure--;
100 sd->exp_too_high_cnt = 0;
101 } else if (sd->exp_too_low_cnt > 3) {
102 exposure++;
103 sd->exp_too_low_cnt = 0;
104 }
105
106 if (gain != orig_gain) {
107 gain_ctrl->set(gspca_dev, gain);
108 retval = 1;
109 }
110 if (exposure != orig_exposure) {
111 exposure_ctrl->set(gspca_dev, exposure);
112 retval = 1;
113 }
114
115 return retval;
116}
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index c98b5d69c438..19fe6b24c9a3 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -52,7 +52,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54 54
55static struct ctrl sd_ctrls[] = { 55static const struct ctrl sd_ctrls[] = {
56 { 56 {
57 { 57 {
58 .id = V4L2_CID_BRIGHTNESS, 58 .id = V4L2_CID_BRIGHTNESS,
@@ -1032,7 +1032,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1032} 1032}
1033 1033
1034/* sub-driver description */ 1034/* sub-driver description */
1035static struct sd_desc sd_desc = { 1035static const struct sd_desc sd_desc = {
1036 .name = MODULE_NAME, 1036 .name = MODULE_NAME,
1037 .ctrls = sd_ctrls, 1037 .ctrls = sd_ctrls,
1038 .nctrls = ARRAY_SIZE(sd_ctrls), 1038 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
new file mode 100644
index 000000000000..82945ed5cbe5
--- /dev/null
+++ b/drivers/media/video/gspca/cpia1.c
@@ -0,0 +1,2022 @@
1/*
2 * cpia CPiA (1) gspca driver
3 *
4 * Copyright (C) 2010 Hans de Goede <hdgoede@redhat.com>
5 *
6 * This module is adapted from the in kernel v4l1 cpia driver which is :
7 *
8 * (C) Copyright 1999-2000 Peter Pregler
9 * (C) Copyright 1999-2000 Scott J. Bertin
10 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
11 * (C) Copyright 2000 STMicroelectronics
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 as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29#define MODULE_NAME "cpia1"
30
31#include "gspca.h"
32
33MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
34MODULE_DESCRIPTION("Vision CPiA");
35MODULE_LICENSE("GPL");
36
37/* constant value's */
38#define MAGIC_0 0x19
39#define MAGIC_1 0x68
40#define DATA_IN 0xC0
41#define DATA_OUT 0x40
42#define VIDEOSIZE_QCIF 0 /* 176x144 */
43#define VIDEOSIZE_CIF 1 /* 352x288 */
44#define SUBSAMPLE_420 0
45#define SUBSAMPLE_422 1
46#define YUVORDER_YUYV 0
47#define YUVORDER_UYVY 1
48#define NOT_COMPRESSED 0
49#define COMPRESSED 1
50#define NO_DECIMATION 0
51#define DECIMATION_ENAB 1
52#define EOI 0xff /* End Of Image */
53#define EOL 0xfd /* End Of Line */
54#define FRAME_HEADER_SIZE 64
55
56/* Image grab modes */
57#define CPIA_GRAB_SINGLE 0
58#define CPIA_GRAB_CONTINEOUS 1
59
60/* Compression parameters */
61#define CPIA_COMPRESSION_NONE 0
62#define CPIA_COMPRESSION_AUTO 1
63#define CPIA_COMPRESSION_MANUAL 2
64#define CPIA_COMPRESSION_TARGET_QUALITY 0
65#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
66
67/* Return offsets for GetCameraState */
68#define SYSTEMSTATE 0
69#define GRABSTATE 1
70#define STREAMSTATE 2
71#define FATALERROR 3
72#define CMDERROR 4
73#define DEBUGFLAGS 5
74#define VPSTATUS 6
75#define ERRORCODE 7
76
77/* SystemState */
78#define UNINITIALISED_STATE 0
79#define PASS_THROUGH_STATE 1
80#define LO_POWER_STATE 2
81#define HI_POWER_STATE 3
82#define WARM_BOOT_STATE 4
83
84/* GrabState */
85#define GRAB_IDLE 0
86#define GRAB_ACTIVE 1
87#define GRAB_DONE 2
88
89/* StreamState */
90#define STREAM_NOT_READY 0
91#define STREAM_READY 1
92#define STREAM_OPEN 2
93#define STREAM_PAUSED 3
94#define STREAM_FINISHED 4
95
96/* Fatal Error, CmdError, and DebugFlags */
97#define CPIA_FLAG 1
98#define SYSTEM_FLAG 2
99#define INT_CTRL_FLAG 4
100#define PROCESS_FLAG 8
101#define COM_FLAG 16
102#define VP_CTRL_FLAG 32
103#define CAPTURE_FLAG 64
104#define DEBUG_FLAG 128
105
106/* VPStatus */
107#define VP_STATE_OK 0x00
108
109#define VP_STATE_FAILED_VIDEOINIT 0x01
110#define VP_STATE_FAILED_AECACBINIT 0x02
111#define VP_STATE_AEC_MAX 0x04
112#define VP_STATE_ACB_BMAX 0x08
113
114#define VP_STATE_ACB_RMIN 0x10
115#define VP_STATE_ACB_GMIN 0x20
116#define VP_STATE_ACB_RMAX 0x40
117#define VP_STATE_ACB_GMAX 0x80
118
119/* default (minimum) compensation values */
120#define COMP_RED 220
121#define COMP_GREEN1 214
122#define COMP_GREEN2 COMP_GREEN1
123#define COMP_BLUE 230
124
125/* exposure status */
126#define EXPOSURE_VERY_LIGHT 0
127#define EXPOSURE_LIGHT 1
128#define EXPOSURE_NORMAL 2
129#define EXPOSURE_DARK 3
130#define EXPOSURE_VERY_DARK 4
131
132#define CPIA_MODULE_CPIA (0 << 5)
133#define CPIA_MODULE_SYSTEM (1 << 5)
134#define CPIA_MODULE_VP_CTRL (5 << 5)
135#define CPIA_MODULE_CAPTURE (6 << 5)
136#define CPIA_MODULE_DEBUG (7 << 5)
137
138#define INPUT (DATA_IN << 8)
139#define OUTPUT (DATA_OUT << 8)
140
141#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
142#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
143#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
144#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
145#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
146#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
147#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
148#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
149
150#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
151#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
152#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
153#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
154#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
155#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
156#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
157#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
158#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
159#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
160#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
161#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
162#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
163
164#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
165#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
166#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
167#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
168#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
169#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
170#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
171#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
172#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
173#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
174#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
175#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
176#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
177#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
178#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
179#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
180#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
181
182#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
183#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
184#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
185#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
186#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
187#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
188#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
189#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
190#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
191#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
192#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
193#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
194#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
195#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
196#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
197
198#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
199#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
200#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
201#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
202#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
203#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
204#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
205#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
206
207#define ROUND_UP_EXP_FOR_FLICKER 15
208
209/* Constants for automatic frame rate adjustment */
210#define MAX_EXP 302
211#define MAX_EXP_102 255
212#define LOW_EXP 140
213#define VERY_LOW_EXP 70
214#define TC 94
215#define EXP_ACC_DARK 50
216#define EXP_ACC_LIGHT 90
217#define HIGH_COMP_102 160
218#define MAX_COMP 239
219#define DARK_TIME 3
220#define LIGHT_TIME 3
221
222#define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \
223 sd->params.version.firmwareRevision == (y))
224
225/* Developer's Guide Table 5 p 3-34
226 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
227static u8 flicker_jumps[2][2][4] =
228{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
229 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
230};
231
232struct cam_params {
233 struct {
234 u8 firmwareVersion;
235 u8 firmwareRevision;
236 u8 vcVersion;
237 u8 vcRevision;
238 } version;
239 struct {
240 u16 vendor;
241 u16 product;
242 u16 deviceRevision;
243 } pnpID;
244 struct {
245 u8 vpVersion;
246 u8 vpRevision;
247 u16 cameraHeadID;
248 } vpVersion;
249 struct {
250 u8 systemState;
251 u8 grabState;
252 u8 streamState;
253 u8 fatalError;
254 u8 cmdError;
255 u8 debugFlags;
256 u8 vpStatus;
257 u8 errorCode;
258 } status;
259 struct {
260 u8 brightness;
261 u8 contrast;
262 u8 saturation;
263 } colourParams;
264 struct {
265 u8 gainMode;
266 u8 expMode;
267 u8 compMode;
268 u8 centreWeight;
269 u8 gain;
270 u8 fineExp;
271 u8 coarseExpLo;
272 u8 coarseExpHi;
273 u8 redComp;
274 u8 green1Comp;
275 u8 green2Comp;
276 u8 blueComp;
277 } exposure;
278 struct {
279 u8 balanceMode;
280 u8 redGain;
281 u8 greenGain;
282 u8 blueGain;
283 } colourBalance;
284 struct {
285 u8 divisor;
286 u8 baserate;
287 } sensorFps;
288 struct {
289 u8 gain1;
290 u8 gain2;
291 u8 gain4;
292 u8 gain8;
293 } apcor;
294 struct {
295 u8 disabled;
296 u8 flickerMode;
297 u8 coarseJump;
298 u8 allowableOverExposure;
299 } flickerControl;
300 struct {
301 u8 gain1;
302 u8 gain2;
303 u8 gain4;
304 u8 gain8;
305 } vlOffset;
306 struct {
307 u8 mode;
308 u8 decimation;
309 } compression;
310 struct {
311 u8 frTargeting;
312 u8 targetFR;
313 u8 targetQ;
314 } compressionTarget;
315 struct {
316 u8 yThreshold;
317 u8 uvThreshold;
318 } yuvThreshold;
319 struct {
320 u8 hysteresis;
321 u8 threshMax;
322 u8 smallStep;
323 u8 largeStep;
324 u8 decimationHysteresis;
325 u8 frDiffStepThresh;
326 u8 qDiffStepThresh;
327 u8 decimationThreshMod;
328 } compressionParams;
329 struct {
330 u8 videoSize; /* CIF/QCIF */
331 u8 subSample;
332 u8 yuvOrder;
333 } format;
334 struct { /* Intel QX3 specific data */
335 u8 qx3_detected; /* a QX3 is present */
336 u8 toplight; /* top light lit , R/W */
337 u8 bottomlight; /* bottom light lit, R/W */
338 u8 button; /* snapshot button pressed (R/O) */
339 u8 cradled; /* microscope is in cradle (R/O) */
340 } qx3;
341 struct {
342 u8 colStart; /* skip first 8*colStart pixels */
343 u8 colEnd; /* finish at 8*colEnd pixels */
344 u8 rowStart; /* skip first 4*rowStart lines */
345 u8 rowEnd; /* finish at 4*rowEnd lines */
346 } roi;
347 u8 ecpTiming;
348 u8 streamStartLine;
349};
350
351/* specific webcam descriptor */
352struct sd {
353 struct gspca_dev gspca_dev; /* !! must be the first item */
354 struct cam_params params; /* camera settings */
355
356 atomic_t cam_exposure;
357 atomic_t fps;
358 int exposure_count;
359 u8 exposure_status;
360 u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */
361 u8 first_frame;
362 u8 freq;
363};
364
365/* V4L2 controls supported by the driver */
366static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
367static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
368static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
369static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
370static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
371static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
372static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
373static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
374static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
375static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
376
377static struct ctrl sd_ctrls[] = {
378 {
379 {
380 .id = V4L2_CID_BRIGHTNESS,
381 .type = V4L2_CTRL_TYPE_INTEGER,
382 .name = "Brightness",
383 .minimum = 0,
384 .maximum = 100,
385 .step = 1,
386#define BRIGHTNESS_DEF 50
387 .default_value = BRIGHTNESS_DEF,
388 .flags = 0,
389 },
390 .set = sd_setbrightness,
391 .get = sd_getbrightness,
392 },
393 {
394 {
395 .id = V4L2_CID_CONTRAST,
396 .type = V4L2_CTRL_TYPE_INTEGER,
397 .name = "Contrast",
398 .minimum = 0,
399 .maximum = 96,
400 .step = 8,
401#define CONTRAST_DEF 48
402 .default_value = CONTRAST_DEF,
403 },
404 .set = sd_setcontrast,
405 .get = sd_getcontrast,
406 },
407 {
408 {
409 .id = V4L2_CID_SATURATION,
410 .type = V4L2_CTRL_TYPE_INTEGER,
411 .name = "Saturation",
412 .minimum = 0,
413 .maximum = 100,
414 .step = 1,
415#define SATURATION_DEF 50
416 .default_value = SATURATION_DEF,
417 },
418 .set = sd_setsaturation,
419 .get = sd_getsaturation,
420 },
421 {
422 {
423 .id = V4L2_CID_POWER_LINE_FREQUENCY,
424 .type = V4L2_CTRL_TYPE_MENU,
425 .name = "Light frequency filter",
426 .minimum = 0,
427 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
428 .step = 1,
429#define FREQ_DEF 1
430 .default_value = FREQ_DEF,
431 },
432 .set = sd_setfreq,
433 .get = sd_getfreq,
434 },
435 {
436 {
437#define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE
438 .id = V4L2_CID_COMP_TARGET,
439 .type = V4L2_CTRL_TYPE_MENU,
440 .name = "Compression Target",
441 .minimum = 0,
442 .maximum = 1,
443 .step = 1,
444#define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY
445 .default_value = COMP_TARGET_DEF,
446 },
447 .set = sd_setcomptarget,
448 .get = sd_getcomptarget,
449 },
450};
451
452static const struct v4l2_pix_format mode[] = {
453 {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
454 /* The sizeimage is trial and error, as with low framerates
455 the camera will pad out usb frames, making the image
456 data larger then strictly necessary */
457 .bytesperline = 160,
458 .sizeimage = 65536,
459 .colorspace = V4L2_COLORSPACE_SRGB,
460 .priv = 3},
461 {176, 144, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
462 .bytesperline = 172,
463 .sizeimage = 65536,
464 .colorspace = V4L2_COLORSPACE_SRGB,
465 .priv = 2},
466 {320, 240, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
467 .bytesperline = 320,
468 .sizeimage = 262144,
469 .colorspace = V4L2_COLORSPACE_SRGB,
470 .priv = 1},
471 {352, 288, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE,
472 .bytesperline = 352,
473 .sizeimage = 262144,
474 .colorspace = V4L2_COLORSPACE_SRGB,
475 .priv = 0},
476};
477
478/**********************************************************************
479 *
480 * General functions
481 *
482 **********************************************************************/
483
484static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
485{
486 u8 requesttype;
487 unsigned int pipe;
488 int ret, databytes = command[6] | (command[7] << 8);
489 /* Sometimes we see spurious EPIPE errors */
490 int retries = 3;
491
492 if (command[0] == DATA_IN) {
493 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
494 requesttype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
495 } else if (command[0] == DATA_OUT) {
496 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
497 requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
498 } else {
499 PDEBUG(D_ERR, "Unexpected first byte of command: %x",
500 command[0]);
501 return -EINVAL;
502 }
503
504retry:
505 ret = usb_control_msg(gspca_dev->dev, pipe,
506 command[1],
507 requesttype,
508 command[2] | (command[3] << 8),
509 command[4] | (command[5] << 8),
510 gspca_dev->usb_buf, databytes, 1000);
511
512 if (ret < 0)
513 PDEBUG(D_ERR, "usb_control_msg %02x, error %d", command[1],
514 ret);
515
516 if (ret == -EPIPE && retries > 0) {
517 retries--;
518 goto retry;
519 }
520
521 return (ret < 0) ? ret : 0;
522}
523
524/* send an arbitrary command to the camera */
525static int do_command(struct gspca_dev *gspca_dev, u16 command,
526 u8 a, u8 b, u8 c, u8 d)
527{
528 struct sd *sd = (struct sd *) gspca_dev;
529 int ret, datasize;
530 u8 cmd[8];
531
532 switch (command) {
533 case CPIA_COMMAND_GetCPIAVersion:
534 case CPIA_COMMAND_GetPnPID:
535 case CPIA_COMMAND_GetCameraStatus:
536 case CPIA_COMMAND_GetVPVersion:
537 case CPIA_COMMAND_GetColourParams:
538 case CPIA_COMMAND_GetColourBalance:
539 case CPIA_COMMAND_GetExposure:
540 datasize = 8;
541 break;
542 case CPIA_COMMAND_ReadMCPorts:
543 case CPIA_COMMAND_ReadVCRegs:
544 datasize = 4;
545 break;
546 default:
547 datasize = 0;
548 break;
549 }
550
551 cmd[0] = command >> 8;
552 cmd[1] = command & 0xff;
553 cmd[2] = a;
554 cmd[3] = b;
555 cmd[4] = c;
556 cmd[5] = d;
557 cmd[6] = datasize;
558 cmd[7] = 0;
559
560 ret = cpia_usb_transferCmd(gspca_dev, cmd);
561 if (ret)
562 return ret;
563
564 switch (command) {
565 case CPIA_COMMAND_GetCPIAVersion:
566 sd->params.version.firmwareVersion = gspca_dev->usb_buf[0];
567 sd->params.version.firmwareRevision = gspca_dev->usb_buf[1];
568 sd->params.version.vcVersion = gspca_dev->usb_buf[2];
569 sd->params.version.vcRevision = gspca_dev->usb_buf[3];
570 break;
571 case CPIA_COMMAND_GetPnPID:
572 sd->params.pnpID.vendor =
573 gspca_dev->usb_buf[0] | (gspca_dev->usb_buf[1] << 8);
574 sd->params.pnpID.product =
575 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
576 sd->params.pnpID.deviceRevision =
577 gspca_dev->usb_buf[4] | (gspca_dev->usb_buf[5] << 8);
578 break;
579 case CPIA_COMMAND_GetCameraStatus:
580 sd->params.status.systemState = gspca_dev->usb_buf[0];
581 sd->params.status.grabState = gspca_dev->usb_buf[1];
582 sd->params.status.streamState = gspca_dev->usb_buf[2];
583 sd->params.status.fatalError = gspca_dev->usb_buf[3];
584 sd->params.status.cmdError = gspca_dev->usb_buf[4];
585 sd->params.status.debugFlags = gspca_dev->usb_buf[5];
586 sd->params.status.vpStatus = gspca_dev->usb_buf[6];
587 sd->params.status.errorCode = gspca_dev->usb_buf[7];
588 break;
589 case CPIA_COMMAND_GetVPVersion:
590 sd->params.vpVersion.vpVersion = gspca_dev->usb_buf[0];
591 sd->params.vpVersion.vpRevision = gspca_dev->usb_buf[1];
592 sd->params.vpVersion.cameraHeadID =
593 gspca_dev->usb_buf[2] | (gspca_dev->usb_buf[3] << 8);
594 break;
595 case CPIA_COMMAND_GetColourParams:
596 sd->params.colourParams.brightness = gspca_dev->usb_buf[0];
597 sd->params.colourParams.contrast = gspca_dev->usb_buf[1];
598 sd->params.colourParams.saturation = gspca_dev->usb_buf[2];
599 break;
600 case CPIA_COMMAND_GetColourBalance:
601 sd->params.colourBalance.redGain = gspca_dev->usb_buf[0];
602 sd->params.colourBalance.greenGain = gspca_dev->usb_buf[1];
603 sd->params.colourBalance.blueGain = gspca_dev->usb_buf[2];
604 break;
605 case CPIA_COMMAND_GetExposure:
606 sd->params.exposure.gain = gspca_dev->usb_buf[0];
607 sd->params.exposure.fineExp = gspca_dev->usb_buf[1];
608 sd->params.exposure.coarseExpLo = gspca_dev->usb_buf[2];
609 sd->params.exposure.coarseExpHi = gspca_dev->usb_buf[3];
610 sd->params.exposure.redComp = gspca_dev->usb_buf[4];
611 sd->params.exposure.green1Comp = gspca_dev->usb_buf[5];
612 sd->params.exposure.green2Comp = gspca_dev->usb_buf[6];
613 sd->params.exposure.blueComp = gspca_dev->usb_buf[7];
614 break;
615
616 case CPIA_COMMAND_ReadMCPorts:
617 if (!sd->params.qx3.qx3_detected)
618 break;
619 /* test button press */
620 sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0);
621 if (sd->params.qx3.button) {
622 /* button pressed - unlock the latch */
623 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
624 3, 0xDF, 0xDF, 0);
625 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
626 3, 0xFF, 0xFF, 0);
627 }
628
629 /* test whether microscope is cradled */
630 sd->params.qx3.cradled = ((gspca_dev->usb_buf[2] & 0x40) == 0);
631 break;
632 }
633
634 return 0;
635}
636
637/* send a command to the camera with an additional data transaction */
638static int do_command_extended(struct gspca_dev *gspca_dev, u16 command,
639 u8 a, u8 b, u8 c, u8 d,
640 u8 e, u8 f, u8 g, u8 h,
641 u8 i, u8 j, u8 k, u8 l)
642{
643 u8 cmd[8];
644
645 cmd[0] = command >> 8;
646 cmd[1] = command & 0xff;
647 cmd[2] = a;
648 cmd[3] = b;
649 cmd[4] = c;
650 cmd[5] = d;
651 cmd[6] = 8;
652 cmd[7] = 0;
653 gspca_dev->usb_buf[0] = e;
654 gspca_dev->usb_buf[1] = f;
655 gspca_dev->usb_buf[2] = g;
656 gspca_dev->usb_buf[3] = h;
657 gspca_dev->usb_buf[4] = i;
658 gspca_dev->usb_buf[5] = j;
659 gspca_dev->usb_buf[6] = k;
660 gspca_dev->usb_buf[7] = l;
661
662 return cpia_usb_transferCmd(gspca_dev, cmd);
663}
664
665/* find_over_exposure
666 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
667 * Some calculation is required because this value changes with the brightness
668 * set with SetColourParameters
669 *
670 * Parameters: Brightness - last brightness value set with SetColourParameters
671 *
672 * Returns: OverExposure value to use with SetFlickerCtrl
673 */
674#define FLICKER_MAX_EXPOSURE 250
675#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
676#define FLICKER_BRIGHTNESS_CONSTANT 59
677static int find_over_exposure(int brightness)
678{
679 int MaxAllowableOverExposure, OverExposure;
680
681 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
682 FLICKER_BRIGHTNESS_CONSTANT;
683
684 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE)
685 OverExposure = MaxAllowableOverExposure;
686 else
687 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
688
689 return OverExposure;
690}
691#undef FLICKER_MAX_EXPOSURE
692#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
693#undef FLICKER_BRIGHTNESS_CONSTANT
694
695/* initialise cam_data structure */
696static void reset_camera_params(struct gspca_dev *gspca_dev)
697{
698 struct sd *sd = (struct sd *) gspca_dev;
699 struct cam_params *params = &sd->params;
700
701 /* The following parameter values are the defaults from
702 * "Software Developer's Guide for CPiA Cameras". Any changes
703 * to the defaults are noted in comments. */
704 params->colourParams.brightness = BRIGHTNESS_DEF;
705 params->colourParams.contrast = CONTRAST_DEF;
706 params->colourParams.saturation = SATURATION_DEF;
707 params->exposure.gainMode = 4;
708 params->exposure.expMode = 2; /* AEC */
709 params->exposure.compMode = 1;
710 params->exposure.centreWeight = 1;
711 params->exposure.gain = 0;
712 params->exposure.fineExp = 0;
713 params->exposure.coarseExpLo = 185;
714 params->exposure.coarseExpHi = 0;
715 params->exposure.redComp = COMP_RED;
716 params->exposure.green1Comp = COMP_GREEN1;
717 params->exposure.green2Comp = COMP_GREEN2;
718 params->exposure.blueComp = COMP_BLUE;
719 params->colourBalance.balanceMode = 2; /* ACB */
720 params->colourBalance.redGain = 32;
721 params->colourBalance.greenGain = 6;
722 params->colourBalance.blueGain = 92;
723 params->apcor.gain1 = 0x18;
724 params->apcor.gain2 = 0x16;
725 params->apcor.gain4 = 0x24;
726 params->apcor.gain8 = 0x34;
727 params->flickerControl.flickerMode = 0;
728 params->flickerControl.disabled = 1;
729
730 params->flickerControl.coarseJump =
731 flicker_jumps[sd->mainsFreq]
732 [params->sensorFps.baserate]
733 [params->sensorFps.divisor];
734 params->flickerControl.allowableOverExposure =
735 find_over_exposure(params->colourParams.brightness);
736 params->vlOffset.gain1 = 20;
737 params->vlOffset.gain2 = 24;
738 params->vlOffset.gain4 = 26;
739 params->vlOffset.gain8 = 26;
740 params->compressionParams.hysteresis = 3;
741 params->compressionParams.threshMax = 11;
742 params->compressionParams.smallStep = 1;
743 params->compressionParams.largeStep = 3;
744 params->compressionParams.decimationHysteresis = 2;
745 params->compressionParams.frDiffStepThresh = 5;
746 params->compressionParams.qDiffStepThresh = 3;
747 params->compressionParams.decimationThreshMod = 2;
748 /* End of default values from Software Developer's Guide */
749
750 /* Set Sensor FPS to 15fps. This seems better than 30fps
751 * for indoor lighting. */
752 params->sensorFps.divisor = 1;
753 params->sensorFps.baserate = 1;
754
755 params->yuvThreshold.yThreshold = 6; /* From windows driver */
756 params->yuvThreshold.uvThreshold = 6; /* From windows driver */
757
758 params->format.subSample = SUBSAMPLE_420;
759 params->format.yuvOrder = YUVORDER_YUYV;
760
761 params->compression.mode = CPIA_COMPRESSION_AUTO;
762 params->compression.decimation = NO_DECIMATION;
763
764 params->compressionTarget.frTargeting = COMP_TARGET_DEF;
765 params->compressionTarget.targetFR = 15; /* From windows driver */
766 params->compressionTarget.targetQ = 5; /* From windows driver */
767
768 params->qx3.qx3_detected = 0;
769 params->qx3.toplight = 0;
770 params->qx3.bottomlight = 0;
771 params->qx3.button = 0;
772 params->qx3.cradled = 0;
773}
774
775static void printstatus(struct cam_params *params)
776{
777 PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
778 params->status.systemState, params->status.grabState,
779 params->status.streamState, params->status.fatalError,
780 params->status.cmdError, params->status.debugFlags,
781 params->status.vpStatus, params->status.errorCode);
782}
783
784static int goto_low_power(struct gspca_dev *gspca_dev)
785{
786 struct sd *sd = (struct sd *) gspca_dev;
787 int ret;
788
789 ret = do_command(gspca_dev, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0);
790 if (ret)
791 return ret;
792
793 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
794 if (ret)
795 return ret;
796
797 if (sd->params.status.systemState != LO_POWER_STATE) {
798 if (sd->params.status.systemState != WARM_BOOT_STATE) {
799 PDEBUG(D_ERR,
800 "unexpected state after lo power cmd: %02x",
801 sd->params.status.systemState);
802 printstatus(&sd->params);
803 }
804 return -EIO;
805 }
806
807 PDEBUG(D_CONF, "camera now in LOW power state");
808 return 0;
809}
810
811static int goto_high_power(struct gspca_dev *gspca_dev)
812{
813 struct sd *sd = (struct sd *) gspca_dev;
814 int ret;
815
816 ret = do_command(gspca_dev, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0);
817 if (ret)
818 return ret;
819
820 msleep_interruptible(40); /* windows driver does it too */
821
822 if (signal_pending(current))
823 return -EINTR;
824
825 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
826 if (ret)
827 return ret;
828
829 if (sd->params.status.systemState != HI_POWER_STATE) {
830 PDEBUG(D_ERR, "unexpected state after hi power cmd: %02x",
831 sd->params.status.systemState);
832 printstatus(&sd->params);
833 return -EIO;
834 }
835
836 PDEBUG(D_CONF, "camera now in HIGH power state");
837 return 0;
838}
839
840static int get_version_information(struct gspca_dev *gspca_dev)
841{
842 int ret;
843
844 /* GetCPIAVersion */
845 ret = do_command(gspca_dev, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
846 if (ret)
847 return ret;
848
849 /* GetPnPID */
850 return do_command(gspca_dev, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
851}
852
853static int save_camera_state(struct gspca_dev *gspca_dev)
854{
855 int ret;
856
857 ret = do_command(gspca_dev, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
858 if (ret)
859 return ret;
860
861 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
862}
863
864int command_setformat(struct gspca_dev *gspca_dev)
865{
866 struct sd *sd = (struct sd *) gspca_dev;
867 int ret;
868
869 ret = do_command(gspca_dev, CPIA_COMMAND_SetFormat,
870 sd->params.format.videoSize,
871 sd->params.format.subSample,
872 sd->params.format.yuvOrder, 0);
873 if (ret)
874 return ret;
875
876 return do_command(gspca_dev, CPIA_COMMAND_SetROI,
877 sd->params.roi.colStart, sd->params.roi.colEnd,
878 sd->params.roi.rowStart, sd->params.roi.rowEnd);
879}
880
881int command_setcolourparams(struct gspca_dev *gspca_dev)
882{
883 struct sd *sd = (struct sd *) gspca_dev;
884 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
885 sd->params.colourParams.brightness,
886 sd->params.colourParams.contrast,
887 sd->params.colourParams.saturation, 0);
888}
889
890int command_setapcor(struct gspca_dev *gspca_dev)
891{
892 struct sd *sd = (struct sd *) gspca_dev;
893 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
894 sd->params.apcor.gain1,
895 sd->params.apcor.gain2,
896 sd->params.apcor.gain4,
897 sd->params.apcor.gain8);
898}
899
900int command_setvloffset(struct gspca_dev *gspca_dev)
901{
902 struct sd *sd = (struct sd *) gspca_dev;
903 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
904 sd->params.vlOffset.gain1,
905 sd->params.vlOffset.gain2,
906 sd->params.vlOffset.gain4,
907 sd->params.vlOffset.gain8);
908}
909
910int command_setexposure(struct gspca_dev *gspca_dev)
911{
912 struct sd *sd = (struct sd *) gspca_dev;
913 int ret;
914
915 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
916 sd->params.exposure.gainMode,
917 1,
918 sd->params.exposure.compMode,
919 sd->params.exposure.centreWeight,
920 sd->params.exposure.gain,
921 sd->params.exposure.fineExp,
922 sd->params.exposure.coarseExpLo,
923 sd->params.exposure.coarseExpHi,
924 sd->params.exposure.redComp,
925 sd->params.exposure.green1Comp,
926 sd->params.exposure.green2Comp,
927 sd->params.exposure.blueComp);
928 if (ret)
929 return ret;
930
931 if (sd->params.exposure.expMode != 1) {
932 ret = do_command_extended(gspca_dev, CPIA_COMMAND_SetExposure,
933 0,
934 sd->params.exposure.expMode,
935 0, 0,
936 sd->params.exposure.gain,
937 sd->params.exposure.fineExp,
938 sd->params.exposure.coarseExpLo,
939 sd->params.exposure.coarseExpHi,
940 0, 0, 0, 0);
941 }
942
943 return ret;
944}
945
946int command_setcolourbalance(struct gspca_dev *gspca_dev)
947{
948 struct sd *sd = (struct sd *) gspca_dev;
949
950 if (sd->params.colourBalance.balanceMode == 1) {
951 int ret;
952
953 ret = do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
954 1,
955 sd->params.colourBalance.redGain,
956 sd->params.colourBalance.greenGain,
957 sd->params.colourBalance.blueGain);
958 if (ret)
959 return ret;
960
961 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
962 3, 0, 0, 0);
963 }
964 if (sd->params.colourBalance.balanceMode == 2) {
965 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
966 2, 0, 0, 0);
967 }
968 if (sd->params.colourBalance.balanceMode == 3) {
969 return do_command(gspca_dev, CPIA_COMMAND_SetColourBalance,
970 3, 0, 0, 0);
971 }
972
973 return -EINVAL;
974}
975
976int command_setcompressiontarget(struct gspca_dev *gspca_dev)
977{
978 struct sd *sd = (struct sd *) gspca_dev;
979
980 return do_command(gspca_dev, CPIA_COMMAND_SetCompressionTarget,
981 sd->params.compressionTarget.frTargeting,
982 sd->params.compressionTarget.targetFR,
983 sd->params.compressionTarget.targetQ, 0);
984}
985
986int command_setyuvtresh(struct gspca_dev *gspca_dev)
987{
988 struct sd *sd = (struct sd *) gspca_dev;
989
990 return do_command(gspca_dev, CPIA_COMMAND_SetYUVThresh,
991 sd->params.yuvThreshold.yThreshold,
992 sd->params.yuvThreshold.uvThreshold, 0, 0);
993}
994
995int command_setcompressionparams(struct gspca_dev *gspca_dev)
996{
997 struct sd *sd = (struct sd *) gspca_dev;
998
999 return do_command_extended(gspca_dev,
1000 CPIA_COMMAND_SetCompressionParams,
1001 0, 0, 0, 0,
1002 sd->params.compressionParams.hysteresis,
1003 sd->params.compressionParams.threshMax,
1004 sd->params.compressionParams.smallStep,
1005 sd->params.compressionParams.largeStep,
1006 sd->params.compressionParams.decimationHysteresis,
1007 sd->params.compressionParams.frDiffStepThresh,
1008 sd->params.compressionParams.qDiffStepThresh,
1009 sd->params.compressionParams.decimationThreshMod);
1010}
1011
1012int command_setcompression(struct gspca_dev *gspca_dev)
1013{
1014 struct sd *sd = (struct sd *) gspca_dev;
1015
1016 return do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1017 sd->params.compression.mode,
1018 sd->params.compression.decimation, 0, 0);
1019}
1020
1021int command_setsensorfps(struct gspca_dev *gspca_dev)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 return do_command(gspca_dev, CPIA_COMMAND_SetSensorFPS,
1026 sd->params.sensorFps.divisor,
1027 sd->params.sensorFps.baserate, 0, 0);
1028}
1029
1030int command_setflickerctrl(struct gspca_dev *gspca_dev)
1031{
1032 struct sd *sd = (struct sd *) gspca_dev;
1033
1034 return do_command(gspca_dev, CPIA_COMMAND_SetFlickerCtrl,
1035 sd->params.flickerControl.flickerMode,
1036 sd->params.flickerControl.coarseJump,
1037 sd->params.flickerControl.allowableOverExposure,
1038 0);
1039}
1040
1041int command_setecptiming(struct gspca_dev *gspca_dev)
1042{
1043 struct sd *sd = (struct sd *) gspca_dev;
1044
1045 return do_command(gspca_dev, CPIA_COMMAND_SetECPTiming,
1046 sd->params.ecpTiming, 0, 0, 0);
1047}
1048
1049int command_pause(struct gspca_dev *gspca_dev)
1050{
1051 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1052}
1053
1054int command_resume(struct gspca_dev *gspca_dev)
1055{
1056 struct sd *sd = (struct sd *) gspca_dev;
1057
1058 return do_command(gspca_dev, CPIA_COMMAND_InitStreamCap,
1059 0, sd->params.streamStartLine, 0, 0);
1060}
1061
1062int command_setlights(struct gspca_dev *gspca_dev)
1063{
1064 struct sd *sd = (struct sd *) gspca_dev;
1065 int ret, p1, p2;
1066
1067 if (!sd->params.qx3.qx3_detected)
1068 return 0;
1069
1070 p1 = (sd->params.qx3.bottomlight == 0) << 1;
1071 p2 = (sd->params.qx3.toplight == 0) << 3;
1072
1073 ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
1074 0x90, 0x8F, 0x50, 0);
1075 if (ret)
1076 return ret;
1077
1078 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1079 p1 | p2 | 0xE0, 0);
1080}
1081
1082static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1083{
1084 /* Everything in here is from the Windows driver */
1085/* define for compgain calculation */
1086#if 0
1087#define COMPGAIN(base, curexp, newexp) \
1088 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
1089#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1090 (u16)((float)curexp * (float)(u8)(curcomp + 128) / \
1091 (float)(u8)(basecomp - 128))
1092#else
1093 /* equivalent functions without floating point math */
1094#define COMPGAIN(base, curexp, newexp) \
1095 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2 * newexp)))
1096#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
1097 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
1098#endif
1099
1100 struct sd *sd = (struct sd *) gspca_dev;
1101 int currentexp = sd->params.exposure.coarseExpLo +
1102 sd->params.exposure.coarseExpHi * 256;
1103 int ret, startexp;
1104
1105 if (on) {
1106 int cj = sd->params.flickerControl.coarseJump;
1107 sd->params.flickerControl.flickerMode = 1;
1108 sd->params.flickerControl.disabled = 0;
1109 if (sd->params.exposure.expMode != 2) {
1110 sd->params.exposure.expMode = 2;
1111 sd->exposure_status = EXPOSURE_NORMAL;
1112 }
1113 currentexp = currentexp << sd->params.exposure.gain;
1114 sd->params.exposure.gain = 0;
1115 /* round down current exposure to nearest value */
1116 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
1117 if (startexp < 1)
1118 startexp = 1;
1119 startexp = (startexp * cj) - 1;
1120 if (FIRMWARE_VERSION(1, 2))
1121 while (startexp > MAX_EXP_102)
1122 startexp -= cj;
1123 else
1124 while (startexp > MAX_EXP)
1125 startexp -= cj;
1126 sd->params.exposure.coarseExpLo = startexp & 0xff;
1127 sd->params.exposure.coarseExpHi = startexp >> 8;
1128 if (currentexp > startexp) {
1129 if (currentexp > (2 * startexp))
1130 currentexp = 2 * startexp;
1131 sd->params.exposure.redComp =
1132 COMPGAIN(COMP_RED, currentexp, startexp);
1133 sd->params.exposure.green1Comp =
1134 COMPGAIN(COMP_GREEN1, currentexp, startexp);
1135 sd->params.exposure.green2Comp =
1136 COMPGAIN(COMP_GREEN2, currentexp, startexp);
1137 sd->params.exposure.blueComp =
1138 COMPGAIN(COMP_BLUE, currentexp, startexp);
1139 } else {
1140 sd->params.exposure.redComp = COMP_RED;
1141 sd->params.exposure.green1Comp = COMP_GREEN1;
1142 sd->params.exposure.green2Comp = COMP_GREEN2;
1143 sd->params.exposure.blueComp = COMP_BLUE;
1144 }
1145 if (FIRMWARE_VERSION(1, 2))
1146 sd->params.exposure.compMode = 0;
1147 else
1148 sd->params.exposure.compMode = 1;
1149
1150 sd->params.apcor.gain1 = 0x18;
1151 sd->params.apcor.gain2 = 0x18;
1152 sd->params.apcor.gain4 = 0x16;
1153 sd->params.apcor.gain8 = 0x14;
1154 } else {
1155 sd->params.flickerControl.flickerMode = 0;
1156 sd->params.flickerControl.disabled = 1;
1157 /* Average equivalent coarse for each comp channel */
1158 startexp = EXP_FROM_COMP(COMP_RED,
1159 sd->params.exposure.redComp, currentexp);
1160 startexp += EXP_FROM_COMP(COMP_GREEN1,
1161 sd->params.exposure.green1Comp, currentexp);
1162 startexp += EXP_FROM_COMP(COMP_GREEN2,
1163 sd->params.exposure.green2Comp, currentexp);
1164 startexp += EXP_FROM_COMP(COMP_BLUE,
1165 sd->params.exposure.blueComp, currentexp);
1166 startexp = startexp >> 2;
1167 while (startexp > MAX_EXP && sd->params.exposure.gain <
1168 sd->params.exposure.gainMode - 1) {
1169 startexp = startexp >> 1;
1170 ++sd->params.exposure.gain;
1171 }
1172 if (FIRMWARE_VERSION(1, 2) && startexp > MAX_EXP_102)
1173 startexp = MAX_EXP_102;
1174 if (startexp > MAX_EXP)
1175 startexp = MAX_EXP;
1176 sd->params.exposure.coarseExpLo = startexp & 0xff;
1177 sd->params.exposure.coarseExpHi = startexp >> 8;
1178 sd->params.exposure.redComp = COMP_RED;
1179 sd->params.exposure.green1Comp = COMP_GREEN1;
1180 sd->params.exposure.green2Comp = COMP_GREEN2;
1181 sd->params.exposure.blueComp = COMP_BLUE;
1182 sd->params.exposure.compMode = 1;
1183 sd->params.apcor.gain1 = 0x18;
1184 sd->params.apcor.gain2 = 0x16;
1185 sd->params.apcor.gain4 = 0x24;
1186 sd->params.apcor.gain8 = 0x34;
1187 }
1188 sd->params.vlOffset.gain1 = 20;
1189 sd->params.vlOffset.gain2 = 24;
1190 sd->params.vlOffset.gain4 = 26;
1191 sd->params.vlOffset.gain8 = 26;
1192
1193 if (apply) {
1194 ret = command_setexposure(gspca_dev);
1195 if (ret)
1196 return ret;
1197
1198 ret = command_setapcor(gspca_dev);
1199 if (ret)
1200 return ret;
1201
1202 ret = command_setvloffset(gspca_dev);
1203 if (ret)
1204 return ret;
1205
1206 ret = command_setflickerctrl(gspca_dev);
1207 if (ret)
1208 return ret;
1209 }
1210
1211 return 0;
1212#undef EXP_FROM_COMP
1213#undef COMPGAIN
1214}
1215
1216/* monitor the exposure and adjust the sensor frame rate if needed */
1217static void monitor_exposure(struct gspca_dev *gspca_dev)
1218{
1219 struct sd *sd = (struct sd *) gspca_dev;
1220 u8 exp_acc, bcomp, gain, coarseL, cmd[8];
1221 int ret, light_exp, dark_exp, very_dark_exp;
1222 int old_exposure, new_exposure, framerate;
1223 int setfps = 0, setexp = 0, setflicker = 0;
1224
1225 /* get necessary stats and register settings from camera */
1226 /* do_command can't handle this, so do it ourselves */
1227 cmd[0] = CPIA_COMMAND_ReadVPRegs >> 8;
1228 cmd[1] = CPIA_COMMAND_ReadVPRegs & 0xff;
1229 cmd[2] = 30;
1230 cmd[3] = 4;
1231 cmd[4] = 9;
1232 cmd[5] = 8;
1233 cmd[6] = 8;
1234 cmd[7] = 0;
1235 ret = cpia_usb_transferCmd(gspca_dev, cmd);
1236 if (ret) {
1237 PDEBUG(D_ERR, "ReadVPRegs(30,4,9,8) - failed: %d", ret);
1238 return;
1239 }
1240 exp_acc = gspca_dev->usb_buf[0];
1241 bcomp = gspca_dev->usb_buf[1];
1242 gain = gspca_dev->usb_buf[2];
1243 coarseL = gspca_dev->usb_buf[3];
1244
1245 light_exp = sd->params.colourParams.brightness +
1246 TC - 50 + EXP_ACC_LIGHT;
1247 if (light_exp > 255)
1248 light_exp = 255;
1249 dark_exp = sd->params.colourParams.brightness +
1250 TC - 50 - EXP_ACC_DARK;
1251 if (dark_exp < 0)
1252 dark_exp = 0;
1253 very_dark_exp = dark_exp / 2;
1254
1255 old_exposure = sd->params.exposure.coarseExpHi * 256 +
1256 sd->params.exposure.coarseExpLo;
1257
1258 if (!sd->params.flickerControl.disabled) {
1259 /* Flicker control on */
1260 int max_comp = FIRMWARE_VERSION(1, 2) ? MAX_COMP :
1261 HIGH_COMP_102;
1262 bcomp += 128; /* decode */
1263 if (bcomp >= max_comp && exp_acc < dark_exp) {
1264 /* dark */
1265 if (exp_acc < very_dark_exp) {
1266 /* very dark */
1267 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1268 ++sd->exposure_count;
1269 else {
1270 sd->exposure_status =
1271 EXPOSURE_VERY_DARK;
1272 sd->exposure_count = 1;
1273 }
1274 } else {
1275 /* just dark */
1276 if (sd->exposure_status == EXPOSURE_DARK)
1277 ++sd->exposure_count;
1278 else {
1279 sd->exposure_status = EXPOSURE_DARK;
1280 sd->exposure_count = 1;
1281 }
1282 }
1283 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1284 /* light */
1285 if (old_exposure <= VERY_LOW_EXP) {
1286 /* very light */
1287 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1288 ++sd->exposure_count;
1289 else {
1290 sd->exposure_status =
1291 EXPOSURE_VERY_LIGHT;
1292 sd->exposure_count = 1;
1293 }
1294 } else {
1295 /* just light */
1296 if (sd->exposure_status == EXPOSURE_LIGHT)
1297 ++sd->exposure_count;
1298 else {
1299 sd->exposure_status = EXPOSURE_LIGHT;
1300 sd->exposure_count = 1;
1301 }
1302 }
1303 } else {
1304 /* not dark or light */
1305 sd->exposure_status = EXPOSURE_NORMAL;
1306 }
1307 } else {
1308 /* Flicker control off */
1309 if (old_exposure >= MAX_EXP && exp_acc < dark_exp) {
1310 /* dark */
1311 if (exp_acc < very_dark_exp) {
1312 /* very dark */
1313 if (sd->exposure_status == EXPOSURE_VERY_DARK)
1314 ++sd->exposure_count;
1315 else {
1316 sd->exposure_status =
1317 EXPOSURE_VERY_DARK;
1318 sd->exposure_count = 1;
1319 }
1320 } else {
1321 /* just dark */
1322 if (sd->exposure_status == EXPOSURE_DARK)
1323 ++sd->exposure_count;
1324 else {
1325 sd->exposure_status = EXPOSURE_DARK;
1326 sd->exposure_count = 1;
1327 }
1328 }
1329 } else if (old_exposure <= LOW_EXP || exp_acc > light_exp) {
1330 /* light */
1331 if (old_exposure <= VERY_LOW_EXP) {
1332 /* very light */
1333 if (sd->exposure_status == EXPOSURE_VERY_LIGHT)
1334 ++sd->exposure_count;
1335 else {
1336 sd->exposure_status =
1337 EXPOSURE_VERY_LIGHT;
1338 sd->exposure_count = 1;
1339 }
1340 } else {
1341 /* just light */
1342 if (sd->exposure_status == EXPOSURE_LIGHT)
1343 ++sd->exposure_count;
1344 else {
1345 sd->exposure_status = EXPOSURE_LIGHT;
1346 sd->exposure_count = 1;
1347 }
1348 }
1349 } else {
1350 /* not dark or light */
1351 sd->exposure_status = EXPOSURE_NORMAL;
1352 }
1353 }
1354
1355 framerate = atomic_read(&sd->fps);
1356 if (framerate > 30 || framerate < 1)
1357 framerate = 1;
1358
1359 if (!sd->params.flickerControl.disabled) {
1360 /* Flicker control on */
1361 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1362 sd->exposure_status == EXPOSURE_DARK) &&
1363 sd->exposure_count >= DARK_TIME * framerate &&
1364 sd->params.sensorFps.divisor < 3) {
1365
1366 /* dark for too long */
1367 ++sd->params.sensorFps.divisor;
1368 setfps = 1;
1369
1370 sd->params.flickerControl.coarseJump =
1371 flicker_jumps[sd->mainsFreq]
1372 [sd->params.sensorFps.baserate]
1373 [sd->params.sensorFps.divisor];
1374 setflicker = 1;
1375
1376 new_exposure = sd->params.flickerControl.coarseJump-1;
1377 while (new_exposure < old_exposure / 2)
1378 new_exposure +=
1379 sd->params.flickerControl.coarseJump;
1380 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1381 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1382 setexp = 1;
1383 sd->exposure_status = EXPOSURE_NORMAL;
1384 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1385
1386 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1387 sd->exposure_status == EXPOSURE_LIGHT) &&
1388 sd->exposure_count >= LIGHT_TIME * framerate &&
1389 sd->params.sensorFps.divisor > 0) {
1390
1391 /* light for too long */
1392 int max_exp = FIRMWARE_VERSION(1, 2) ? MAX_EXP_102 :
1393 MAX_EXP;
1394 --sd->params.sensorFps.divisor;
1395 setfps = 1;
1396
1397 sd->params.flickerControl.coarseJump =
1398 flicker_jumps[sd->mainsFreq]
1399 [sd->params.sensorFps.baserate]
1400 [sd->params.sensorFps.divisor];
1401 setflicker = 1;
1402
1403 new_exposure = sd->params.flickerControl.coarseJump-1;
1404 while (new_exposure < 2 * old_exposure &&
1405 new_exposure +
1406 sd->params.flickerControl.coarseJump < max_exp)
1407 new_exposure +=
1408 sd->params.flickerControl.coarseJump;
1409 sd->params.exposure.coarseExpLo = new_exposure & 0xff;
1410 sd->params.exposure.coarseExpHi = new_exposure >> 8;
1411 setexp = 1;
1412 sd->exposure_status = EXPOSURE_NORMAL;
1413 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1414 }
1415 } else {
1416 /* Flicker control off */
1417 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1418 sd->exposure_status == EXPOSURE_DARK) &&
1419 sd->exposure_count >= DARK_TIME * framerate &&
1420 sd->params.sensorFps.divisor < 3) {
1421
1422 /* dark for too long */
1423 ++sd->params.sensorFps.divisor;
1424 setfps = 1;
1425
1426 if (sd->params.exposure.gain > 0) {
1427 --sd->params.exposure.gain;
1428 setexp = 1;
1429 }
1430 sd->exposure_status = EXPOSURE_NORMAL;
1431 PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
1432
1433 } else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
1434 sd->exposure_status == EXPOSURE_LIGHT) &&
1435 sd->exposure_count >= LIGHT_TIME * framerate &&
1436 sd->params.sensorFps.divisor > 0) {
1437
1438 /* light for too long */
1439 --sd->params.sensorFps.divisor;
1440 setfps = 1;
1441
1442 if (sd->params.exposure.gain <
1443 sd->params.exposure.gainMode - 1) {
1444 ++sd->params.exposure.gain;
1445 setexp = 1;
1446 }
1447 sd->exposure_status = EXPOSURE_NORMAL;
1448 PDEBUG(D_CONF, "Automatically increasing sensor_fps");
1449 }
1450 }
1451
1452 if (setexp)
1453 command_setexposure(gspca_dev);
1454
1455 if (setfps)
1456 command_setsensorfps(gspca_dev);
1457
1458 if (setflicker)
1459 command_setflickerctrl(gspca_dev);
1460}
1461
1462/*-----------------------------------------------------------------*/
1463/* if flicker is switched off, this function switches it back on.It checks,
1464 however, that conditions are suitable before restarting it.
1465 This should only be called for firmware version 1.2.
1466
1467 It also adjust the colour balance when an exposure step is detected - as
1468 long as flicker is running
1469*/
1470static void restart_flicker(struct gspca_dev *gspca_dev)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
1473 int cam_exposure, old_exp;
1474
1475 if (!FIRMWARE_VERSION(1, 2))
1476 return;
1477
1478 cam_exposure = atomic_read(&sd->cam_exposure);
1479
1480 if (sd->params.flickerControl.flickerMode == 0 ||
1481 cam_exposure == 0)
1482 return;
1483
1484 old_exp = sd->params.exposure.coarseExpLo +
1485 sd->params.exposure.coarseExpHi*256;
1486 /*
1487 see how far away camera exposure is from a valid
1488 flicker exposure value
1489 */
1490 cam_exposure %= sd->params.flickerControl.coarseJump;
1491 if (!sd->params.flickerControl.disabled &&
1492 cam_exposure <= sd->params.flickerControl.coarseJump - 3) {
1493 /* Flicker control auto-disabled */
1494 sd->params.flickerControl.disabled = 1;
1495 }
1496
1497 if (sd->params.flickerControl.disabled &&
1498 old_exp > sd->params.flickerControl.coarseJump +
1499 ROUND_UP_EXP_FOR_FLICKER) {
1500 /* exposure is now high enough to switch
1501 flicker control back on */
1502 set_flicker(gspca_dev, 1, 1);
1503 }
1504}
1505
1506/* this function is called at probe time */
1507static int sd_config(struct gspca_dev *gspca_dev,
1508 const struct usb_device_id *id)
1509{
1510 struct cam *cam;
1511
1512 reset_camera_params(gspca_dev);
1513
1514 PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
1515 id->idVendor, id->idProduct);
1516
1517 cam = &gspca_dev->cam;
1518 cam->cam_mode = mode;
1519 cam->nmodes = ARRAY_SIZE(mode);
1520
1521 sd_setfreq(gspca_dev, FREQ_DEF);
1522
1523 return 0;
1524}
1525
1526/* -- start the camera -- */
1527static int sd_start(struct gspca_dev *gspca_dev)
1528{
1529 struct sd *sd = (struct sd *) gspca_dev;
1530 int priv, ret;
1531
1532 /* Start the camera in low power mode */
1533 if (goto_low_power(gspca_dev)) {
1534 if (sd->params.status.systemState != WARM_BOOT_STATE) {
1535 PDEBUG(D_ERR, "unexpected systemstate: %02x",
1536 sd->params.status.systemState);
1537 printstatus(&sd->params);
1538 return -ENODEV;
1539 }
1540
1541 /* FIXME: this is just dirty trial and error */
1542 ret = goto_high_power(gspca_dev);
1543 if (ret)
1544 return ret;
1545
1546 ret = do_command(gspca_dev, CPIA_COMMAND_DiscardFrame,
1547 0, 0, 0, 0);
1548 if (ret)
1549 return ret;
1550
1551 ret = goto_low_power(gspca_dev);
1552 if (ret)
1553 return ret;
1554 }
1555
1556 /* procedure described in developer's guide p3-28 */
1557
1558 /* Check the firmware version. */
1559 sd->params.version.firmwareVersion = 0;
1560 get_version_information(gspca_dev);
1561 if (sd->params.version.firmwareVersion != 1) {
1562 PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)",
1563 sd->params.version.firmwareVersion);
1564 return -ENODEV;
1565 }
1566
1567 /* A bug in firmware 1-02 limits gainMode to 2 */
1568 if (sd->params.version.firmwareRevision <= 2 &&
1569 sd->params.exposure.gainMode > 2) {
1570 sd->params.exposure.gainMode = 2;
1571 }
1572
1573 /* set QX3 detected flag */
1574 sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 &&
1575 sd->params.pnpID.product == 0x0001);
1576
1577 /* The fatal error checking should be done after
1578 * the camera powers up (developer's guide p 3-38) */
1579
1580 /* Set streamState before transition to high power to avoid bug
1581 * in firmware 1-02 */
1582 ret = do_command(gspca_dev, CPIA_COMMAND_ModifyCameraStatus,
1583 STREAMSTATE, 0, STREAM_NOT_READY, 0);
1584 if (ret)
1585 return ret;
1586
1587 /* GotoHiPower */
1588 ret = goto_high_power(gspca_dev);
1589 if (ret)
1590 return ret;
1591
1592 /* Check the camera status */
1593 ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1594 if (ret)
1595 return ret;
1596
1597 if (sd->params.status.fatalError) {
1598 PDEBUG(D_ERR, "fatal_error: %04x, vp_status: %04x",
1599 sd->params.status.fatalError,
1600 sd->params.status.vpStatus);
1601 return -EIO;
1602 }
1603
1604 /* VPVersion can't be retrieved before the camera is in HiPower,
1605 * so get it here instead of in get_version_information. */
1606 ret = do_command(gspca_dev, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
1607 if (ret)
1608 return ret;
1609
1610 /* Determine video mode settings */
1611 sd->params.streamStartLine = 120;
1612
1613 priv = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1614 if (priv & 0x01) { /* crop */
1615 sd->params.roi.colStart = 2;
1616 sd->params.roi.rowStart = 6;
1617 } else {
1618 sd->params.roi.colStart = 0;
1619 sd->params.roi.rowStart = 0;
1620 }
1621
1622 if (priv & 0x02) { /* quarter */
1623 sd->params.format.videoSize = VIDEOSIZE_QCIF;
1624 sd->params.roi.colStart /= 2;
1625 sd->params.roi.rowStart /= 2;
1626 sd->params.streamStartLine /= 2;
1627 } else
1628 sd->params.format.videoSize = VIDEOSIZE_CIF;
1629
1630 sd->params.roi.colEnd = sd->params.roi.colStart +
1631 (gspca_dev->width >> 3);
1632 sd->params.roi.rowEnd = sd->params.roi.rowStart +
1633 (gspca_dev->height >> 2);
1634
1635 /* And now set the camera to a known state */
1636 ret = do_command(gspca_dev, CPIA_COMMAND_SetGrabMode,
1637 CPIA_GRAB_CONTINEOUS, 0, 0, 0);
1638 if (ret)
1639 return ret;
1640 /* We start with compression disabled, as we need one uncompressed
1641 frame to handle later compressed frames */
1642 ret = do_command(gspca_dev, CPIA_COMMAND_SetCompression,
1643 CPIA_COMPRESSION_NONE,
1644 NO_DECIMATION, 0, 0);
1645 if (ret)
1646 return ret;
1647 ret = command_setcompressiontarget(gspca_dev);
1648 if (ret)
1649 return ret;
1650 ret = command_setcolourparams(gspca_dev);
1651 if (ret)
1652 return ret;
1653 ret = command_setformat(gspca_dev);
1654 if (ret)
1655 return ret;
1656 ret = command_setyuvtresh(gspca_dev);
1657 if (ret)
1658 return ret;
1659 ret = command_setecptiming(gspca_dev);
1660 if (ret)
1661 return ret;
1662 ret = command_setcompressionparams(gspca_dev);
1663 if (ret)
1664 return ret;
1665 ret = command_setexposure(gspca_dev);
1666 if (ret)
1667 return ret;
1668 ret = command_setcolourbalance(gspca_dev);
1669 if (ret)
1670 return ret;
1671 ret = command_setsensorfps(gspca_dev);
1672 if (ret)
1673 return ret;
1674 ret = command_setapcor(gspca_dev);
1675 if (ret)
1676 return ret;
1677 ret = command_setflickerctrl(gspca_dev);
1678 if (ret)
1679 return ret;
1680 ret = command_setvloffset(gspca_dev);
1681 if (ret)
1682 return ret;
1683
1684 /* Start stream */
1685 ret = command_resume(gspca_dev);
1686 if (ret)
1687 return ret;
1688
1689 /* Wait 6 frames before turning compression on for the sensor to get
1690 all settings and AEC/ACB to settle */
1691 sd->first_frame = 6;
1692 sd->exposure_status = EXPOSURE_NORMAL;
1693 sd->exposure_count = 0;
1694 atomic_set(&sd->cam_exposure, 0);
1695 atomic_set(&sd->fps, 0);
1696
1697 return 0;
1698}
1699
1700static void sd_stopN(struct gspca_dev *gspca_dev)
1701{
1702 command_pause(gspca_dev);
1703
1704 /* save camera state for later open (developers guide ch 3.5.3) */
1705 save_camera_state(gspca_dev);
1706
1707 /* GotoLoPower */
1708 goto_low_power(gspca_dev);
1709
1710 /* Update the camera status */
1711 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1712}
1713
1714/* this function is called at probe and resume time */
1715static int sd_init(struct gspca_dev *gspca_dev)
1716{
1717 struct sd *sd = (struct sd *) gspca_dev;
1718 int ret;
1719
1720 /* Start / Stop the camera to make sure we are talking to
1721 a supported camera, and to get some information from it
1722 to print. */
1723 ret = sd_start(gspca_dev);
1724 if (ret)
1725 return ret;
1726
1727 sd_stopN(gspca_dev);
1728
1729 PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
1730 sd->params.version.firmwareVersion,
1731 sd->params.version.firmwareRevision,
1732 sd->params.version.vcVersion,
1733 sd->params.version.vcRevision);
1734 PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
1735 sd->params.pnpID.vendor, sd->params.pnpID.product,
1736 sd->params.pnpID.deviceRevision);
1737 PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
1738 sd->params.vpVersion.vpVersion,
1739 sd->params.vpVersion.vpRevision,
1740 sd->params.vpVersion.cameraHeadID);
1741
1742 return 0;
1743}
1744
1745static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1746 u8 *data,
1747 int len)
1748{
1749 struct sd *sd = (struct sd *) gspca_dev;
1750
1751 /* Check for SOF */
1752 if (len >= 64 &&
1753 data[0] == MAGIC_0 && data[1] == MAGIC_1 &&
1754 data[16] == sd->params.format.videoSize &&
1755 data[17] == sd->params.format.subSample &&
1756 data[18] == sd->params.format.yuvOrder &&
1757 data[24] == sd->params.roi.colStart &&
1758 data[25] == sd->params.roi.colEnd &&
1759 data[26] == sd->params.roi.rowStart &&
1760 data[27] == sd->params.roi.rowEnd) {
1761 struct gspca_frame *frame = gspca_get_i_frame(gspca_dev);
1762
1763 atomic_set(&sd->cam_exposure, data[39] * 2);
1764 atomic_set(&sd->fps, data[41]);
1765
1766 if (frame == NULL) {
1767 gspca_dev->last_packet_type = DISCARD_PACKET;
1768 return;
1769 }
1770
1771 /* Check for proper EOF for last frame */
1772 if ((frame->data_end - frame->data) > 4 &&
1773 frame->data_end[-4] == 0xff &&
1774 frame->data_end[-3] == 0xff &&
1775 frame->data_end[-2] == 0xff &&
1776 frame->data_end[-1] == 0xff)
1777 gspca_frame_add(gspca_dev, LAST_PACKET,
1778 NULL, 0);
1779
1780 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1781 return;
1782 }
1783
1784 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1785}
1786
1787static void sd_dq_callback(struct gspca_dev *gspca_dev)
1788{
1789 struct sd *sd = (struct sd *) gspca_dev;
1790
1791 /* Set the normal compression settings once we have captured a
1792 few uncompressed frames (and AEC has hopefully settled) */
1793 if (sd->first_frame) {
1794 sd->first_frame--;
1795 if (sd->first_frame == 0)
1796 command_setcompression(gspca_dev);
1797 }
1798
1799 /* Switch flicker control back on if it got turned off */
1800 restart_flicker(gspca_dev);
1801
1802 /* If AEC is enabled, monitor the exposure and
1803 adjust the sensor frame rate if needed */
1804 if (sd->params.exposure.expMode == 2)
1805 monitor_exposure(gspca_dev);
1806
1807 /* Update our knowledge of the camera state */
1808 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1809 if (sd->params.qx3.qx3_detected)
1810 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1811}
1812
1813static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1814{
1815 struct sd *sd = (struct sd *) gspca_dev;
1816 int ret;
1817
1818 sd->params.colourParams.brightness = val;
1819 sd->params.flickerControl.allowableOverExposure =
1820 find_over_exposure(sd->params.colourParams.brightness);
1821 if (gspca_dev->streaming) {
1822 ret = command_setcolourparams(gspca_dev);
1823 if (ret)
1824 return ret;
1825 return command_setflickerctrl(gspca_dev);
1826 }
1827 return 0;
1828}
1829
1830static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1831{
1832 struct sd *sd = (struct sd *) gspca_dev;
1833
1834 *val = sd->params.colourParams.brightness;
1835 return 0;
1836}
1837
1838static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1839{
1840 struct sd *sd = (struct sd *) gspca_dev;
1841
1842 sd->params.colourParams.contrast = val;
1843 if (gspca_dev->streaming)
1844 return command_setcolourparams(gspca_dev);
1845
1846 return 0;
1847}
1848
1849static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1850{
1851 struct sd *sd = (struct sd *) gspca_dev;
1852
1853 *val = sd->params.colourParams.contrast;
1854 return 0;
1855}
1856
1857static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
1858{
1859 struct sd *sd = (struct sd *) gspca_dev;
1860
1861 sd->params.colourParams.saturation = val;
1862 if (gspca_dev->streaming)
1863 return command_setcolourparams(gspca_dev);
1864
1865 return 0;
1866}
1867
1868static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
1869{
1870 struct sd *sd = (struct sd *) gspca_dev;
1871
1872 *val = sd->params.colourParams.saturation;
1873 return 0;
1874}
1875
1876static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1877{
1878 struct sd *sd = (struct sd *) gspca_dev;
1879 int on;
1880
1881 switch (val) {
1882 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1883 on = 0;
1884 break;
1885 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1886 on = 1;
1887 sd->mainsFreq = 0;
1888 break;
1889 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1890 on = 1;
1891 sd->mainsFreq = 1;
1892 break;
1893 default:
1894 return -EINVAL;
1895 }
1896
1897 sd->freq = val;
1898 sd->params.flickerControl.coarseJump =
1899 flicker_jumps[sd->mainsFreq]
1900 [sd->params.sensorFps.baserate]
1901 [sd->params.sensorFps.divisor];
1902
1903 return set_flicker(gspca_dev, on, gspca_dev->streaming);
1904}
1905
1906static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1907{
1908 struct sd *sd = (struct sd *) gspca_dev;
1909
1910 *val = sd->freq;
1911 return 0;
1912}
1913
1914static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val)
1915{
1916 struct sd *sd = (struct sd *) gspca_dev;
1917
1918 sd->params.compressionTarget.frTargeting = val;
1919 if (gspca_dev->streaming)
1920 return command_setcompressiontarget(gspca_dev);
1921
1922 return 0;
1923}
1924
1925static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val)
1926{
1927 struct sd *sd = (struct sd *) gspca_dev;
1928
1929 *val = sd->params.compressionTarget.frTargeting;
1930 return 0;
1931}
1932
1933static int sd_querymenu(struct gspca_dev *gspca_dev,
1934 struct v4l2_querymenu *menu)
1935{
1936 switch (menu->id) {
1937 case V4L2_CID_POWER_LINE_FREQUENCY:
1938 switch (menu->index) {
1939 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1940 strcpy((char *) menu->name, "NoFliker");
1941 return 0;
1942 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1943 strcpy((char *) menu->name, "50 Hz");
1944 return 0;
1945 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1946 strcpy((char *) menu->name, "60 Hz");
1947 return 0;
1948 }
1949 break;
1950 case V4L2_CID_COMP_TARGET:
1951 switch (menu->index) {
1952 case CPIA_COMPRESSION_TARGET_QUALITY:
1953 strcpy((char *) menu->name, "Quality");
1954 return 0;
1955 case CPIA_COMPRESSION_TARGET_FRAMERATE:
1956 strcpy((char *) menu->name, "Framerate");
1957 return 0;
1958 }
1959 break;
1960 }
1961 return -EINVAL;
1962}
1963
1964/* sub-driver description */
1965static const struct sd_desc sd_desc = {
1966 .name = MODULE_NAME,
1967 .ctrls = sd_ctrls,
1968 .nctrls = ARRAY_SIZE(sd_ctrls),
1969 .config = sd_config,
1970 .init = sd_init,
1971 .start = sd_start,
1972 .stopN = sd_stopN,
1973 .dq_callback = sd_dq_callback,
1974 .pkt_scan = sd_pkt_scan,
1975 .querymenu = sd_querymenu,
1976};
1977
1978/* -- module initialisation -- */
1979static const __devinitdata struct usb_device_id device_table[] = {
1980 {USB_DEVICE(0x0553, 0x0002)},
1981 {USB_DEVICE(0x0813, 0x0001)},
1982 {}
1983};
1984MODULE_DEVICE_TABLE(usb, device_table);
1985
1986/* -- device connect -- */
1987static int sd_probe(struct usb_interface *intf,
1988 const struct usb_device_id *id)
1989{
1990 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1991 THIS_MODULE);
1992}
1993
1994static struct usb_driver sd_driver = {
1995 .name = MODULE_NAME,
1996 .id_table = device_table,
1997 .probe = sd_probe,
1998 .disconnect = gspca_disconnect,
1999#ifdef CONFIG_PM
2000 .suspend = gspca_suspend,
2001 .resume = gspca_resume,
2002#endif
2003};
2004
2005/* -- module insert / remove -- */
2006static int __init sd_mod_init(void)
2007{
2008 int ret;
2009 ret = usb_register(&sd_driver);
2010 if (ret < 0)
2011 return ret;
2012 PDEBUG(D_PROBE, "registered");
2013 return 0;
2014}
2015static void __exit sd_mod_exit(void)
2016{
2017 usb_deregister(&sd_driver);
2018 PDEBUG(D_PROBE, "deregistered");
2019}
2020
2021module_init(sd_mod_init);
2022module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index fdf4c0ec5e7a..ecd4d743d2bc 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -52,7 +52,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
54 54
55static struct ctrl sd_ctrls[] = { 55static const struct ctrl sd_ctrls[] = {
56 { 56 {
57 { 57 {
58 .id = V4L2_CID_BRIGHTNESS, 58 .id = V4L2_CID_BRIGHTNESS,
@@ -851,7 +851,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
851} 851}
852 852
853/* sub-driver description */ 853/* sub-driver description */
854static struct sd_desc sd_desc = { 854static const struct sd_desc sd_desc = {
855 .name = MODULE_NAME, 855 .name = MODULE_NAME,
856 .ctrls = sd_ctrls, 856 .ctrls = sd_ctrls,
857 .nctrls = ARRAY_SIZE(sd_ctrls), 857 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 4878c8f66543..9e42476c0eaf 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -161,7 +161,7 @@ static int gl860_build_control_table(struct gspca_dev *gspca_dev)
161 161
162/*==================== sud-driver structure initialisation =================*/ 162/*==================== sud-driver structure initialisation =================*/
163 163
164static struct sd_desc sd_desc_mi1320 = { 164static const struct sd_desc sd_desc_mi1320 = {
165 .name = MODULE_NAME, 165 .name = MODULE_NAME,
166 .ctrls = sd_ctrls_mi1320, 166 .ctrls = sd_ctrls_mi1320,
167 .nctrls = GL860_NCTRLS, 167 .nctrls = GL860_NCTRLS,
@@ -174,7 +174,7 @@ static struct sd_desc sd_desc_mi1320 = {
174 .dq_callback = sd_callback, 174 .dq_callback = sd_callback,
175}; 175};
176 176
177static struct sd_desc sd_desc_mi2020 = { 177static const struct sd_desc sd_desc_mi2020 = {
178 .name = MODULE_NAME, 178 .name = MODULE_NAME,
179 .ctrls = sd_ctrls_mi2020, 179 .ctrls = sd_ctrls_mi2020,
180 .nctrls = GL860_NCTRLS, 180 .nctrls = GL860_NCTRLS,
@@ -187,7 +187,7 @@ static struct sd_desc sd_desc_mi2020 = {
187 .dq_callback = sd_callback, 187 .dq_callback = sd_callback,
188}; 188};
189 189
190static struct sd_desc sd_desc_mi2020b = { 190static const struct sd_desc sd_desc_mi2020b = {
191 .name = MODULE_NAME, 191 .name = MODULE_NAME,
192 .ctrls = sd_ctrls_mi2020b, 192 .ctrls = sd_ctrls_mi2020b,
193 .nctrls = GL860_NCTRLS, 193 .nctrls = GL860_NCTRLS,
@@ -200,7 +200,7 @@ static struct sd_desc sd_desc_mi2020b = {
200 .dq_callback = sd_callback, 200 .dq_callback = sd_callback,
201}; 201};
202 202
203static struct sd_desc sd_desc_ov2640 = { 203static const struct sd_desc sd_desc_ov2640 = {
204 .name = MODULE_NAME, 204 .name = MODULE_NAME,
205 .ctrls = sd_ctrls_ov2640, 205 .ctrls = sd_ctrls_ov2640,
206 .nctrls = GL860_NCTRLS, 206 .nctrls = GL860_NCTRLS,
@@ -213,7 +213,7 @@ static struct sd_desc sd_desc_ov2640 = {
213 .dq_callback = sd_callback, 213 .dq_callback = sd_callback,
214}; 214};
215 215
216static struct sd_desc sd_desc_ov9655 = { 216static const struct sd_desc sd_desc_ov9655 = {
217 .name = MODULE_NAME, 217 .name = MODULE_NAME,
218 .ctrls = sd_ctrls_ov9655, 218 .ctrls = sd_ctrls_ov9655,
219 .nctrls = GL860_NCTRLS, 219 .nctrls = GL860_NCTRLS,
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index bd6214d4ab3b..222af479150b 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -3,6 +3,9 @@
3 * 3 *
4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
5 * 5 *
6 * Camera button input handling by Márton Németh
7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
8 *
6 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your 11 * Free Software Foundation; either version 2 of the License, or (at your
@@ -37,6 +40,11 @@
37 40
38#include "gspca.h" 41#include "gspca.h"
39 42
43#ifdef CONFIG_INPUT
44#include <linux/input.h>
45#include <linux/usb/input.h>
46#endif
47
40/* global values */ 48/* global values */
41#define DEF_NURBS 3 /* default number of URBs */ 49#define DEF_NURBS 3 /* default number of URBs */
42#if DEF_NURBS > MAX_NURBS 50#if DEF_NURBS > MAX_NURBS
@@ -47,7 +55,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 55MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
49 57
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 8, 0) 58#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 9, 0)
51 59
52#ifdef GSPCA_DEBUG 60#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 61int gspca_debug = D_ERR | D_PROBE;
@@ -104,15 +112,185 @@ static const struct vm_operations_struct gspca_vm_ops = {
104 .close = gspca_vm_close, 112 .close = gspca_vm_close,
105}; 113};
106 114
115/*
116 * Input and interrupt endpoint handling functions
117 */
118#ifdef CONFIG_INPUT
119static void int_irq(struct urb *urb)
120{
121 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
122 int ret;
123
124 ret = urb->status;
125 switch (ret) {
126 case 0:
127 if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,
128 urb->transfer_buffer, urb->actual_length) < 0) {
129 PDEBUG(D_ERR, "Unknown packet received");
130 }
131 break;
132
133 case -ENOENT:
134 case -ECONNRESET:
135 case -ENODEV:
136 case -ESHUTDOWN:
137 /* Stop is requested either by software or hardware is gone,
138 * keep the ret value non-zero and don't resubmit later.
139 */
140 break;
141
142 default:
143 PDEBUG(D_ERR, "URB error %i, resubmitting", urb->status);
144 urb->status = 0;
145 ret = 0;
146 }
147
148 if (ret == 0) {
149 ret = usb_submit_urb(urb, GFP_ATOMIC);
150 if (ret < 0)
151 PDEBUG(D_ERR, "Resubmit URB failed with error %i", ret);
152 }
153}
154
155static int gspca_input_connect(struct gspca_dev *dev)
156{
157 struct input_dev *input_dev;
158 int err = 0;
159
160 dev->input_dev = NULL;
161 if (dev->sd_desc->int_pkt_scan || dev->sd_desc->other_input) {
162 input_dev = input_allocate_device();
163 if (!input_dev)
164 return -ENOMEM;
165
166 usb_make_path(dev->dev, dev->phys, sizeof(dev->phys));
167 strlcat(dev->phys, "/input0", sizeof(dev->phys));
168
169 input_dev->name = dev->sd_desc->name;
170 input_dev->phys = dev->phys;
171
172 usb_to_input_id(dev->dev, &input_dev->id);
173
174 input_dev->evbit[0] = BIT_MASK(EV_KEY);
175 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
176 input_dev->dev.parent = &dev->dev->dev;
177
178 err = input_register_device(input_dev);
179 if (err) {
180 PDEBUG(D_ERR, "Input device registration failed "
181 "with error %i", err);
182 input_dev->dev.parent = NULL;
183 input_free_device(input_dev);
184 } else {
185 dev->input_dev = input_dev;
186 }
187 }
188
189 return err;
190}
191
192static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
193 struct usb_endpoint_descriptor *ep)
194{
195 unsigned int buffer_len;
196 int interval;
197 struct urb *urb;
198 struct usb_device *dev;
199 void *buffer = NULL;
200 int ret = -EINVAL;
201
202 buffer_len = ep->wMaxPacketSize;
203 interval = ep->bInterval;
204 PDEBUG(D_PROBE, "found int in endpoint: 0x%x, "
205 "buffer_len=%u, interval=%u",
206 ep->bEndpointAddress, buffer_len, interval);
207
208 dev = gspca_dev->dev;
209
210 urb = usb_alloc_urb(0, GFP_KERNEL);
211 if (!urb) {
212 ret = -ENOMEM;
213 goto error;
214 }
215
216 buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize,
217 GFP_KERNEL, &urb->transfer_dma);
218 if (!buffer) {
219 ret = -ENOMEM;
220 goto error_buffer;
221 }
222 usb_fill_int_urb(urb, dev,
223 usb_rcvintpipe(dev, ep->bEndpointAddress),
224 buffer, buffer_len,
225 int_irq, (void *)gspca_dev, interval);
226 gspca_dev->int_urb = urb;
227 ret = usb_submit_urb(urb, GFP_KERNEL);
228 if (ret < 0) {
229 PDEBUG(D_ERR, "submit URB failed with error %i", ret);
230 goto error_submit;
231 }
232 return ret;
233
234error_submit:
235 usb_buffer_free(dev,
236 urb->transfer_buffer_length,
237 urb->transfer_buffer,
238 urb->transfer_dma);
239error_buffer:
240 usb_free_urb(urb);
241error:
242 return ret;
243}
244
245static void gspca_input_create_urb(struct gspca_dev *gspca_dev)
246{
247 struct usb_interface *intf;
248 struct usb_host_interface *intf_desc;
249 struct usb_endpoint_descriptor *ep;
250 int i;
251
252 if (gspca_dev->sd_desc->int_pkt_scan) {
253 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
254 intf_desc = intf->cur_altsetting;
255 for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
256 ep = &intf_desc->endpoint[i].desc;
257 if (usb_endpoint_dir_in(ep) &&
258 usb_endpoint_xfer_int(ep)) {
259
260 alloc_and_submit_int_urb(gspca_dev, ep);
261 break;
262 }
263 }
264 }
265}
266
267static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
268{
269 struct urb *urb;
270
271 urb = gspca_dev->int_urb;
272 if (urb) {
273 gspca_dev->int_urb = NULL;
274 usb_kill_urb(urb);
275 usb_buffer_free(gspca_dev->dev,
276 urb->transfer_buffer_length,
277 urb->transfer_buffer,
278 urb->transfer_dma);
279 usb_free_urb(urb);
280 }
281}
282#else
283#define gspca_input_connect(gspca_dev) 0
284#define gspca_input_create_urb(gspca_dev)
285#define gspca_input_destroy_urb(gspca_dev)
286#endif
287
107/* get the current input frame buffer */ 288/* get the current input frame buffer */
108struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev) 289struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
109{ 290{
110 struct gspca_frame *frame; 291 struct gspca_frame *frame;
111 int i;
112 292
113 i = gspca_dev->fr_i; 293 frame = gspca_dev->cur_frame;
114 i = gspca_dev->fr_queue[i];
115 frame = &gspca_dev->frame[i];
116 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) 294 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
117 != V4L2_BUF_FLAG_QUEUED) 295 != V4L2_BUF_FLAG_QUEUED)
118 return NULL; 296 return NULL;
@@ -486,11 +664,13 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
486 i, ep->desc.bEndpointAddress); 664 i, ep->desc.bEndpointAddress);
487 gspca_dev->alt = i; /* memorize the current alt setting */ 665 gspca_dev->alt = i; /* memorize the current alt setting */
488 if (gspca_dev->nbalt > 1) { 666 if (gspca_dev->nbalt > 1) {
667 gspca_input_destroy_urb(gspca_dev);
489 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 668 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
490 if (ret < 0) { 669 if (ret < 0) {
491 err("set alt %d err %d", i, ret); 670 err("set alt %d err %d", i, ret);
492 return NULL; 671 ep = NULL;
493 } 672 }
673 gspca_input_create_urb(gspca_dev);
494 } 674 }
495 return ep; 675 return ep;
496} 676}
@@ -534,26 +714,22 @@ static int create_urbs(struct gspca_dev *gspca_dev,
534 nurbs = 1; 714 nurbs = 1;
535 } 715 }
536 716
537 gspca_dev->nurbs = nurbs;
538 for (n = 0; n < nurbs; n++) { 717 for (n = 0; n < nurbs; n++) {
539 urb = usb_alloc_urb(npkt, GFP_KERNEL); 718 urb = usb_alloc_urb(npkt, GFP_KERNEL);
540 if (!urb) { 719 if (!urb) {
541 err("usb_alloc_urb failed"); 720 err("usb_alloc_urb failed");
542 destroy_urbs(gspca_dev);
543 return -ENOMEM; 721 return -ENOMEM;
544 } 722 }
723 gspca_dev->urb[n] = urb;
545 urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev, 724 urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
546 bsize, 725 bsize,
547 GFP_KERNEL, 726 GFP_KERNEL,
548 &urb->transfer_dma); 727 &urb->transfer_dma);
549 728
550 if (urb->transfer_buffer == NULL) { 729 if (urb->transfer_buffer == NULL) {
551 usb_free_urb(urb); 730 err("usb_buffer_alloc failed");
552 err("usb_buffer_urb failed");
553 destroy_urbs(gspca_dev);
554 return -ENOMEM; 731 return -ENOMEM;
555 } 732 }
556 gspca_dev->urb[n] = urb;
557 urb->dev = gspca_dev->dev; 733 urb->dev = gspca_dev->dev;
558 urb->context = gspca_dev; 734 urb->context = gspca_dev;
559 urb->transfer_buffer_length = bsize; 735 urb->transfer_buffer_length = bsize;
@@ -585,6 +761,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
585static int gspca_init_transfer(struct gspca_dev *gspca_dev) 761static int gspca_init_transfer(struct gspca_dev *gspca_dev)
586{ 762{
587 struct usb_host_endpoint *ep; 763 struct usb_host_endpoint *ep;
764 struct urb *urb;
588 int n, ret; 765 int n, ret;
589 766
590 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 767 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -595,6 +772,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
595 goto out; 772 goto out;
596 } 773 }
597 774
775 gspca_dev->usb_err = 0;
776
598 /* set the higher alternate setting and 777 /* set the higher alternate setting and
599 * loop until urb submit succeeds */ 778 * loop until urb submit succeeds */
600 if (gspca_dev->cam.reverse_alts) 779 if (gspca_dev->cam.reverse_alts)
@@ -613,10 +792,15 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
613 goto out; 792 goto out;
614 } 793 }
615 for (;;) { 794 for (;;) {
616 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); 795 if (!gspca_dev->cam.no_urb_create) {
617 ret = create_urbs(gspca_dev, ep); 796 PDEBUG(D_STREAM, "init transfer alt %d",
618 if (ret < 0) 797 gspca_dev->alt);
619 goto out; 798 ret = create_urbs(gspca_dev, ep);
799 if (ret < 0) {
800 destroy_urbs(gspca_dev);
801 goto out;
802 }
803 }
620 804
621 /* clear the bulk endpoint */ 805 /* clear the bulk endpoint */
622 if (gspca_dev->cam.bulk) 806 if (gspca_dev->cam.bulk)
@@ -636,8 +820,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
636 break; 820 break;
637 821
638 /* submit the URBs */ 822 /* submit the URBs */
639 for (n = 0; n < gspca_dev->nurbs; n++) { 823 for (n = 0; n < MAX_NURBS; n++) {
640 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); 824 urb = gspca_dev->urb[n];
825 if (urb == NULL)
826 break;
827 ret = usb_submit_urb(urb, GFP_KERNEL);
641 if (ret < 0) 828 if (ret < 0)
642 break; 829 break;
643 } 830 }
@@ -694,7 +881,9 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
694 if (gspca_dev->sd_desc->stopN) 881 if (gspca_dev->sd_desc->stopN)
695 gspca_dev->sd_desc->stopN(gspca_dev); 882 gspca_dev->sd_desc->stopN(gspca_dev);
696 destroy_urbs(gspca_dev); 883 destroy_urbs(gspca_dev);
884 gspca_input_destroy_urb(gspca_dev);
697 gspca_set_alt0(gspca_dev); 885 gspca_set_alt0(gspca_dev);
886 gspca_input_create_urb(gspca_dev);
698 } 887 }
699 888
700 /* always call stop0 to free the subdriver's resources */ 889 /* always call stop0 to free the subdriver's resources */
@@ -2060,11 +2249,12 @@ int gspca_dev_probe(struct usb_interface *intf,
2060 PDEBUG(D_ERR, "Too many config"); 2249 PDEBUG(D_ERR, "Too many config");
2061 return -ENODEV; 2250 return -ENODEV;
2062 } 2251 }
2252
2253 /* the USB video interface must be the first one */
2063 interface = &intf->cur_altsetting->desc; 2254 interface = &intf->cur_altsetting->desc;
2064 if (interface->bInterfaceNumber > 0) { 2255 if (dev->config->desc.bNumInterfaces != 1 &&
2065 PDEBUG(D_ERR, "intf != 0"); 2256 interface->bInterfaceNumber != 0)
2066 return -ENODEV; 2257 return -ENODEV;
2067 }
2068 2258
2069 /* create the device */ 2259 /* create the device */
2070 if (dev_size < sizeof *gspca_dev) 2260 if (dev_size < sizeof *gspca_dev)
@@ -2096,6 +2286,10 @@ int gspca_dev_probe(struct usb_interface *intf,
2096 goto out; 2286 goto out;
2097 gspca_set_default_mode(gspca_dev); 2287 gspca_set_default_mode(gspca_dev);
2098 2288
2289 ret = gspca_input_connect(gspca_dev);
2290 if (ret)
2291 goto out;
2292
2099 mutex_init(&gspca_dev->usb_lock); 2293 mutex_init(&gspca_dev->usb_lock);
2100 mutex_init(&gspca_dev->read_lock); 2294 mutex_init(&gspca_dev->read_lock);
2101 mutex_init(&gspca_dev->queue_lock); 2295 mutex_init(&gspca_dev->queue_lock);
@@ -2116,8 +2310,15 @@ int gspca_dev_probe(struct usb_interface *intf,
2116 2310
2117 usb_set_intfdata(intf, gspca_dev); 2311 usb_set_intfdata(intf, gspca_dev);
2118 PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev)); 2312 PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
2313
2314 gspca_input_create_urb(gspca_dev);
2315
2119 return 0; 2316 return 0;
2120out: 2317out:
2318#ifdef CONFIG_INPUT
2319 if (gspca_dev->input_dev)
2320 input_unregister_device(gspca_dev->input_dev);
2321#endif
2121 kfree(gspca_dev->usb_buf); 2322 kfree(gspca_dev->usb_buf);
2122 kfree(gspca_dev); 2323 kfree(gspca_dev);
2123 return ret; 2324 return ret;
@@ -2133,6 +2334,9 @@ EXPORT_SYMBOL(gspca_dev_probe);
2133void gspca_disconnect(struct usb_interface *intf) 2334void gspca_disconnect(struct usb_interface *intf)
2134{ 2335{
2135 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2336 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2337#ifdef CONFIG_INPUT
2338 struct input_dev *input_dev;
2339#endif
2136 2340
2137 PDEBUG(D_PROBE, "%s disconnect", 2341 PDEBUG(D_PROBE, "%s disconnect",
2138 video_device_node_name(&gspca_dev->vdev)); 2342 video_device_node_name(&gspca_dev->vdev));
@@ -2144,6 +2348,15 @@ void gspca_disconnect(struct usb_interface *intf)
2144 wake_up_interruptible(&gspca_dev->wq); 2348 wake_up_interruptible(&gspca_dev->wq);
2145 } 2349 }
2146 2350
2351#ifdef CONFIG_INPUT
2352 gspca_input_destroy_urb(gspca_dev);
2353 input_dev = gspca_dev->input_dev;
2354 if (input_dev) {
2355 gspca_dev->input_dev = NULL;
2356 input_unregister_device(input_dev);
2357 }
2358#endif
2359
2147 /* the device is freed at exit of this function */ 2360 /* the device is freed at exit of this function */
2148 gspca_dev->dev = NULL; 2361 gspca_dev->dev = NULL;
2149 mutex_unlock(&gspca_dev->usb_lock); 2362 mutex_unlock(&gspca_dev->usb_lock);
@@ -2169,6 +2382,7 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message)
2169 if (gspca_dev->sd_desc->stopN) 2382 if (gspca_dev->sd_desc->stopN)
2170 gspca_dev->sd_desc->stopN(gspca_dev); 2383 gspca_dev->sd_desc->stopN(gspca_dev);
2171 destroy_urbs(gspca_dev); 2384 destroy_urbs(gspca_dev);
2385 gspca_input_destroy_urb(gspca_dev);
2172 gspca_set_alt0(gspca_dev); 2386 gspca_set_alt0(gspca_dev);
2173 if (gspca_dev->sd_desc->stop0) 2387 if (gspca_dev->sd_desc->stop0)
2174 gspca_dev->sd_desc->stop0(gspca_dev); 2388 gspca_dev->sd_desc->stop0(gspca_dev);
@@ -2182,6 +2396,7 @@ int gspca_resume(struct usb_interface *intf)
2182 2396
2183 gspca_dev->frozen = 0; 2397 gspca_dev->frozen = 0;
2184 gspca_dev->sd_desc->init(gspca_dev); 2398 gspca_dev->sd_desc->init(gspca_dev);
2399 gspca_input_create_urb(gspca_dev);
2185 if (gspca_dev->streaming) 2400 if (gspca_dev->streaming)
2186 return gspca_init_transfer(gspca_dev); 2401 return gspca_init_transfer(gspca_dev);
2187 return 0; 2402 return 0;
@@ -2205,6 +2420,8 @@ int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
2205 int retval = 0; 2420 int retval = 0;
2206 2421
2207 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 2422 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
2423 if (gspca_dev->ctrl_dis & (1 << i))
2424 continue;
2208 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN) 2425 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
2209 gain_ctrl = &gspca_dev->sd_desc->ctrls[i]; 2426 gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
2210 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE) 2427 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 59c7941da999..02c696a22be0 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -48,26 +48,27 @@ extern int gspca_debug;
48 48
49/* used to list framerates supported by a camera mode (resolution) */ 49/* used to list framerates supported by a camera mode (resolution) */
50struct framerates { 50struct framerates {
51 int *rates; 51 const u8 *rates;
52 int nrates; 52 int nrates;
53}; 53};
54 54
55/* device information - set at probe time */ 55/* device information - set at probe time */
56struct cam { 56struct cam {
57 int bulk_size; /* buffer size when image transfer by bulk */
58 const struct v4l2_pix_format *cam_mode; /* size nmodes */ 57 const struct v4l2_pix_format *cam_mode; /* size nmodes */
59 char nmodes;
60 const struct framerates *mode_framerates; /* must have size nmode, 58 const struct framerates *mode_framerates; /* must have size nmode,
61 * just like cam_mode */ 59 * just like cam_mode */
62 __u8 bulk_nurbs; /* number of URBs in bulk mode 60 u32 bulk_size; /* buffer size when image transfer by bulk */
61 u32 input_flags; /* value for ENUM_INPUT status flags */
62 u8 nmodes; /* size of cam_mode */
63 u8 no_urb_create; /* don't create transfer URBs */
64 u8 bulk_nurbs; /* number of URBs in bulk mode
63 * - cannot be > MAX_NURBS 65 * - cannot be > MAX_NURBS
64 * - when 0 and bulk_size != 0 means 66 * - when 0 and bulk_size != 0 means
65 * 1 URB and submit done by subdriver */ 67 * 1 URB and submit done by subdriver */
66 u8 bulk; /* image transfer by 0:isoc / 1:bulk */ 68 u8 bulk; /* image transfer by 0:isoc / 1:bulk */
67 u8 npkt; /* number of packets in an ISOC message 69 u8 npkt; /* number of packets in an ISOC message
68 * 0 is the default value: 32 packets */ 70 * 0 is the default value: 32 packets */
69 u32 input_flags; /* value for ENUM_INPUT status flags */ 71 u8 reverse_alts; /* Alt settings are in high to low order */
70 char reverse_alts; /* Alt settings are in high to low order */
71}; 72};
72 73
73struct gspca_dev; 74struct gspca_dev;
@@ -90,6 +91,9 @@ typedef int (*cam_qmnu_op) (struct gspca_dev *,
90typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 91typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
91 u8 *data, 92 u8 *data,
92 int len); 93 int len);
94typedef int (*cam_int_pkt_op) (struct gspca_dev *gspca_dev,
95 u8 *data,
96 int len);
93 97
94struct ctrl { 98struct ctrl {
95 struct v4l2_queryctrl qctrl; 99 struct v4l2_queryctrl qctrl;
@@ -125,6 +129,12 @@ struct sd_desc {
125 cam_reg_op get_register; 129 cam_reg_op get_register;
126#endif 130#endif
127 cam_ident_op get_chip_ident; 131 cam_ident_op get_chip_ident;
132#ifdef CONFIG_INPUT
133 cam_int_pkt_op int_pkt_scan;
134 /* other_input makes the gspca core create gspca_dev->input even when
135 int_pkt_scan is NULL, for cams with non interrupt driven buttons */
136 u8 other_input;
137#endif
128}; 138};
129 139
130/* packet types when moving from iso buf to frame buf */ 140/* packet types when moving from iso buf to frame buf */
@@ -147,6 +157,10 @@ struct gspca_dev {
147 struct module *module; /* subdriver handling the device */ 157 struct module *module; /* subdriver handling the device */
148 struct usb_device *dev; 158 struct usb_device *dev;
149 struct file *capt_file; /* file doing video capture */ 159 struct file *capt_file; /* file doing video capture */
160#ifdef CONFIG_INPUT
161 struct input_dev *input_dev;
162 char phys[64]; /* physical device path */
163#endif
150 164
151 struct cam cam; /* device information */ 165 struct cam cam; /* device information */
152 const struct sd_desc *sd_desc; /* subdriver description */ 166 const struct sd_desc *sd_desc; /* subdriver description */
@@ -156,6 +170,9 @@ struct gspca_dev {
156#define USB_BUF_SZ 64 170#define USB_BUF_SZ 64
157 __u8 *usb_buf; /* buffer for USB exchanges */ 171 __u8 *usb_buf; /* buffer for USB exchanges */
158 struct urb *urb[MAX_NURBS]; 172 struct urb *urb[MAX_NURBS];
173#ifdef CONFIG_INPUT
174 struct urb *int_urb;
175#endif
159 176
160 __u8 *frbuf; /* buffer for nframes */ 177 __u8 *frbuf; /* buffer for nframes */
161 struct gspca_frame frame[GSPCA_MAX_FRAMES]; 178 struct gspca_frame frame[GSPCA_MAX_FRAMES];
@@ -187,7 +204,6 @@ struct gspca_dev {
187 char users; /* number of opens */ 204 char users; /* number of opens */
188 char present; /* device connected */ 205 char present; /* device connected */
189 char nbufread; /* number of buffers for read() */ 206 char nbufread; /* number of buffers for read() */
190 char nurbs; /* number of allocated URBs */
191 char memory; /* memory type (V4L2_MEMORY_xxx) */ 207 char memory; /* memory type (V4L2_MEMORY_xxx) */
192 __u8 iface; /* USB interface number */ 208 __u8 iface; /* USB interface number */
193 __u8 alt; /* USB alternate setting */ 209 __u8 alt; /* USB alternate setting */
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 8d071dff6944..c0722fa64606 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -48,7 +48,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
48 } 48 }
49}; 49};
50 50
51const static struct ctrl mt9m111_ctrls[] = { 51static const struct ctrl mt9m111_ctrls[] = {
52#define VFLIP_IDX 0 52#define VFLIP_IDX 0
53 { 53 {
54 { 54 {
@@ -171,7 +171,7 @@ int mt9m111_probe(struct sd *sd)
171 return -ENODEV; 171 return -ENODEV;
172 } 172 }
173 173
174 info("Probing for a mt9m111 sensor"); 174 PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
175 175
176 /* Do the preinit */ 176 /* Do the preinit */
177 for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) { 177 for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 2a28b74cb3f9..62c1cbf06666 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -33,7 +33,7 @@ static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 33static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 34static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35 35
36const static struct ctrl ov7660_ctrls[] = { 36static const struct ctrl ov7660_ctrls[] = {
37#define GAIN_IDX 1 37#define GAIN_IDX 1
38 { 38 {
39 { 39 {
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index f5588ebe667c..4d9dcf29da2e 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -94,7 +94,7 @@ int ov7660_start(struct sd *sd);
94int ov7660_stop(struct sd *sd); 94int ov7660_stop(struct sd *sd);
95void ov7660_disconnect(struct sd *sd); 95void ov7660_disconnect(struct sd *sd);
96 96
97const static struct m5602_sensor ov7660 = { 97static const struct m5602_sensor ov7660 = {
98 .name = "ov7660", 98 .name = "ov7660",
99 .i2c_slave_id = 0x42, 99 .i2c_slave_id = 0x42,
100 .i2c_regW = 1, 100 .i2c_regW = 1,
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 923cdd5f7a6b..069ba0044f8b 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -307,7 +307,7 @@ int ov9650_probe(struct sd *sd)
307 return -ENODEV; 307 return -ENODEV;
308 } 308 }
309 309
310 info("Probing for an ov9650 sensor"); 310 PDEBUG(D_PROBE, "Probing for an ov9650 sensor");
311 311
312 /* Run the pre-init before probing the sensor */ 312 /* Run the pre-init before probing the sensor */
313 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { 313 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 8d74d8065b79..925b87d66f40 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -205,7 +205,7 @@ int po1030_probe(struct sd *sd)
205 return -ENODEV; 205 return -ENODEV;
206 } 206 }
207 207
208 info("Probing for a po1030 sensor"); 208 PDEBUG(D_PROBE, "Probing for a po1030 sensor");
209 209
210 /* Run the pre-init to actually probe the unit */ 210 /* Run the pre-init to actually probe the unit */
211 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { 211 for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 1b536f7d30cf..da0a38c78708 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -248,7 +248,7 @@ int s5k4aa_probe(struct sd *sd)
248 return -ENODEV; 248 return -ENODEV;
249 } 249 }
250 250
251 info("Probing for a s5k4aa sensor"); 251 PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
252 252
253 /* Preinit the sensor */ 253 /* Preinit the sensor */
254 for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) { 254 for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 6b89f33a4ce0..fbd91545497a 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -143,7 +143,7 @@ int s5k83a_probe(struct sd *sd)
143 return -ENODEV; 143 return -ENODEV;
144 } 144 }
145 145
146 info("Probing for a s5k83a sensor"); 146 PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
147 147
148 /* Preinit the sensor */ 148 /* Preinit the sensor */
149 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) { 149 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 9cf8d68c71bf..3d9229e22b25 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -54,7 +54,7 @@ static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 54static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 55static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
56 56
57static struct ctrl sd_ctrls[] = { 57static const struct ctrl sd_ctrls[] = {
58 { 58 {
59 { 59 {
60 .id = V4L2_CID_BRIGHTNESS, 60 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 9154870e07d2..33744e724eaa 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -57,6 +57,14 @@
57#define MR97310A_GAIN_MAX 31 57#define MR97310A_GAIN_MAX 31
58#define MR97310A_GAIN_DEFAULT 25 58#define MR97310A_GAIN_DEFAULT 25
59 59
60#define MR97310A_CONTRAST_MIN 0
61#define MR97310A_CONTRAST_MAX 31
62#define MR97310A_CONTRAST_DEFAULT 23
63
64#define MR97310A_CS_GAIN_MIN 0
65#define MR97310A_CS_GAIN_MAX 0x7ff
66#define MR97310A_CS_GAIN_DEFAULT 0x110
67
60#define MR97310A_MIN_CLOCKDIV_MIN 3 68#define MR97310A_MIN_CLOCKDIV_MIN 3
61#define MR97310A_MIN_CLOCKDIV_MAX 8 69#define MR97310A_MIN_CLOCKDIV_MAX 8
62#define MR97310A_MIN_CLOCKDIV_DEFAULT 3 70#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
@@ -82,7 +90,8 @@ struct sd {
82 90
83 int brightness; 91 int brightness;
84 u16 exposure; 92 u16 exposure;
85 u8 gain; 93 u32 gain;
94 u8 contrast;
86 u8 min_clockdiv; 95 u8 min_clockdiv;
87}; 96};
88 97
@@ -98,6 +107,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 107static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 108static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 109static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
110static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 112static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 113static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val); 114static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
@@ -105,11 +116,13 @@ static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
105static void setbrightness(struct gspca_dev *gspca_dev); 116static void setbrightness(struct gspca_dev *gspca_dev);
106static void setexposure(struct gspca_dev *gspca_dev); 117static void setexposure(struct gspca_dev *gspca_dev);
107static void setgain(struct gspca_dev *gspca_dev); 118static void setgain(struct gspca_dev *gspca_dev);
119static void setcontrast(struct gspca_dev *gspca_dev);
108 120
109/* V4L2 controls supported by the driver */ 121/* V4L2 controls supported by the driver */
110static struct ctrl sd_ctrls[] = { 122static const struct ctrl sd_ctrls[] = {
111/* Separate brightness control description for Argus QuickClix as it has 123/* Separate brightness control description for Argus QuickClix as it has
112 different limits from the other mr97310a cameras */ 124 * different limits from the other mr97310a cameras, and separate gain
125 * control for Sakar CyberPix camera. */
113 { 126 {
114#define NORM_BRIGHTNESS_IDX 0 127#define NORM_BRIGHTNESS_IDX 0
115 { 128 {
@@ -171,7 +184,37 @@ static struct ctrl sd_ctrls[] = {
171 .get = sd_getgain, 184 .get = sd_getgain,
172 }, 185 },
173 { 186 {
174#define MIN_CLOCKDIV_IDX 4 187#define SAKAR_CS_GAIN_IDX 4
188 {
189 .id = V4L2_CID_GAIN,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Gain",
192 .minimum = MR97310A_CS_GAIN_MIN,
193 .maximum = MR97310A_CS_GAIN_MAX,
194 .step = 1,
195 .default_value = MR97310A_CS_GAIN_DEFAULT,
196 .flags = 0,
197 },
198 .set = sd_setgain,
199 .get = sd_getgain,
200 },
201 {
202#define CONTRAST_IDX 5
203 {
204 .id = V4L2_CID_CONTRAST,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Contrast",
207 .minimum = MR97310A_CONTRAST_MIN,
208 .maximum = MR97310A_CONTRAST_MAX,
209 .step = 1,
210 .default_value = MR97310A_CONTRAST_DEFAULT,
211 .flags = 0,
212 },
213 .set = sd_setcontrast,
214 .get = sd_getcontrast,
215 },
216 {
217#define MIN_CLOCKDIV_IDX 6
175 { 218 {
176 .id = V4L2_CID_PRIVATE_BASE, 219 .id = V4L2_CID_PRIVATE_BASE,
177 .type = V4L2_CTRL_TYPE_INTEGER, 220 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -327,7 +370,6 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
327 if (err_code < 0) 370 if (err_code < 0)
328 return err_code; 371 return err_code;
329 372
330 err_code = mr_write(gspca_dev, 1);
331 data[0] = 0x19; 373 data[0] = 0x19;
332 data[1] = 0x51; 374 data[1] = 0x51;
333 err_code = mr_write(gspca_dev, 2); 375 err_code = mr_write(gspca_dev, 2);
@@ -437,6 +479,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
437{ 479{
438 struct sd *sd = (struct sd *) gspca_dev; 480 struct sd *sd = (struct sd *) gspca_dev;
439 struct cam *cam; 481 struct cam *cam;
482 int gain_default = MR97310A_GAIN_DEFAULT;
440 int err_code; 483 int err_code;
441 484
442 cam = &gspca_dev->cam; 485 cam = &gspca_dev->cam;
@@ -460,12 +503,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
460 if (err_code < 0) 503 if (err_code < 0)
461 return err_code; 504 return err_code;
462 505
506 /* Now, the query for sensor type. */
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
463 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { 511 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
464 sd->cam_type = CAM_TYPE_CIF; 512 sd->cam_type = CAM_TYPE_CIF;
465 cam->nmodes--; 513 cam->nmodes--;
466 err_code = cam_get_response16(gspca_dev, 0x06, 1);
467 if (err_code < 0)
468 return err_code;
469 /* 514 /*
470 * All but one of the known CIF cameras share the same USB ID, 515 * All but one of the known CIF cameras share the same USB ID,
471 * but two different init routines are in use, and the control 516 * but two different init routines are in use, and the control
@@ -473,12 +518,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
473 * of the two known varieties is connected! 518 * of the two known varieties is connected!
474 * 519 *
475 * A list of known CIF cameras follows. They all report either 520 * A list of known CIF cameras follows. They all report either
476 * 0002 for type 0 or 0003 for type 1. 521 * 0200 for type 0 or 0300 for type 1.
477 * If you have another to report, please do 522 * If you have another to report, please do
478 * 523 *
479 * Name sd->sensor_type reported by 524 * Name sd->sensor_type reported by
480 * 525 *
481 * Sakar Spy-shot 0 T. Kilgore 526 * Sakar 56379 Spy-shot 0 T. Kilgore
482 * Innovage 0 T. Kilgore 527 * Innovage 0 T. Kilgore
483 * Vivitar Mini 0 H. De Goede 528 * Vivitar Mini 0 H. De Goede
484 * Vivitar Mini 0 E. Rodriguez 529 * Vivitar Mini 0 E. Rodriguez
@@ -487,7 +532,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
487 * Philips dig. keych. 1 T. Kilgore 532 * Philips dig. keych. 1 T. Kilgore
488 * Trust Spyc@m 100 1 A. Jacobs 533 * Trust Spyc@m 100 1 A. Jacobs
489 */ 534 */
490 switch (gspca_dev->usb_buf[1]) { 535 switch (gspca_dev->usb_buf[0]) {
491 case 2: 536 case 2:
492 sd->sensor_type = 0; 537 sd->sensor_type = 0;
493 break; 538 break;
@@ -504,20 +549,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
504 } else { 549 } else {
505 sd->cam_type = CAM_TYPE_VGA; 550 sd->cam_type = CAM_TYPE_VGA;
506 551
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
511 /* 552 /*
512 * Here is a table of the responses to the previous command 553 * Here is a table of the responses to the query for sensor
513 * from the known MR97310A VGA cameras. 554 * type, from the known MR97310A VGA cameras. Six different
555 * cameras of which five share the same USB ID.
514 * 556 *
515 * Name gspca_dev->usb_buf[] sd->sensor_type 557 * Name gspca_dev->usb_buf[] sd->sensor_type
516 * sd->do_lcd_stop 558 * sd->do_lcd_stop
517 * Aiptek Pencam VGA+ 0300 0 1 559 * Aiptek Pencam VGA+ 0300 0 1
518 * ION digital 0350 0 1 560 * ION digital 0300 0 1
519 * Argus DC-1620 0450 1 0 561 * Argus DC-1620 0450 1 0
520 * Argus QuickClix 0420 1 1 562 * Argus QuickClix 0420 1 1
563 * Sakar 77379 Digital 0350 0 1
564 * Sakar 1638x CyberPix 0120 0 2
521 * 565 *
522 * Based upon these results, we assume default settings 566 * Based upon these results, we assume default settings
523 * and then correct as necessary, as follows. 567 * and then correct as necessary, as follows.
@@ -527,10 +571,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
527 sd->sensor_type = 1; 571 sd->sensor_type = 1;
528 sd->do_lcd_stop = 0; 572 sd->do_lcd_stop = 0;
529 sd->adj_colors = 0; 573 sd->adj_colors = 0;
530 if ((gspca_dev->usb_buf[0] != 0x03) && 574 if (gspca_dev->usb_buf[0] == 0x01) {
575 sd->sensor_type = 2;
576 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
531 (gspca_dev->usb_buf[0] != 0x04)) { 577 (gspca_dev->usb_buf[0] != 0x04)) {
532 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", 578 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
533 gspca_dev->usb_buf[1]); 579 gspca_dev->usb_buf[0]);
534 PDEBUG(D_ERR, "Defaults assumed, may not work"); 580 PDEBUG(D_ERR, "Defaults assumed, may not work");
535 PDEBUG(D_ERR, "Please report this"); 581 PDEBUG(D_ERR, "Please report this");
536 } 582 }
@@ -560,7 +606,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
560 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", 606 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
561 sd->sensor_type); 607 sd->sensor_type);
562 } 608 }
563 /* Stop streaming as we've started it to probe the sensor type. */ 609 /* Stop streaming as we've started it only to probe the sensor type. */
564 sd_stopN(gspca_dev); 610 sd_stopN(gspca_dev);
565 611
566 if (force_sensor_type != -1) { 612 if (force_sensor_type != -1) {
@@ -574,9 +620,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
574 /* No brightness for sensor_type 0 */ 620 /* No brightness for sensor_type 0 */
575 if (sd->sensor_type == 0) 621 if (sd->sensor_type == 0)
576 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | 622 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
577 (1 << ARGUS_QC_BRIGHTNESS_IDX); 623 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
624 (1 << CONTRAST_IDX) |
625 (1 << SAKAR_CS_GAIN_IDX);
578 else 626 else
579 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | 627 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
628 (1 << CONTRAST_IDX) |
629 (1 << SAKAR_CS_GAIN_IDX) |
580 (1 << MIN_CLOCKDIV_IDX); 630 (1 << MIN_CLOCKDIV_IDX);
581 } else { 631 } else {
582 /* All controls need to be disabled if VGA sensor_type is 0 */ 632 /* All controls need to be disabled if VGA sensor_type is 0 */
@@ -585,17 +635,30 @@ static int sd_config(struct gspca_dev *gspca_dev,
585 (1 << ARGUS_QC_BRIGHTNESS_IDX) | 635 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
586 (1 << EXPOSURE_IDX) | 636 (1 << EXPOSURE_IDX) |
587 (1 << GAIN_IDX) | 637 (1 << GAIN_IDX) |
638 (1 << CONTRAST_IDX) |
639 (1 << SAKAR_CS_GAIN_IDX) |
588 (1 << MIN_CLOCKDIV_IDX); 640 (1 << MIN_CLOCKDIV_IDX);
589 else if (sd->do_lcd_stop) 641 else if (sd->sensor_type == 2) {
642 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
643 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
644 (1 << GAIN_IDX) |
645 (1 << MIN_CLOCKDIV_IDX);
646 gain_default = MR97310A_CS_GAIN_DEFAULT;
647 } else if (sd->do_lcd_stop)
590 /* Argus QuickClix has different brightness limits */ 648 /* Argus QuickClix has different brightness limits */
591 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); 649 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
650 (1 << CONTRAST_IDX) |
651 (1 << SAKAR_CS_GAIN_IDX);
592 else 652 else
593 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); 653 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
654 (1 << CONTRAST_IDX) |
655 (1 << SAKAR_CS_GAIN_IDX);
594 } 656 }
595 657
596 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; 658 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
597 sd->exposure = MR97310A_EXPOSURE_DEFAULT; 659 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
598 sd->gain = MR97310A_GAIN_DEFAULT; 660 sd->gain = gain_default;
661 sd->contrast = MR97310A_CONTRAST_DEFAULT;
599 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; 662 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
600 663
601 return 0; 664 return 0;
@@ -697,6 +760,12 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
697 {0x13, 0x00, {0x01}, 1}, 760 {0x13, 0x00, {0x01}, 1},
698 {0, 0, {0}, 0} 761 {0, 0, {0}, 0}
699 }; 762 };
763 /* Without this command the cam won't work with USB-UHCI */
764 gspca_dev->usb_buf[0] = 0x0a;
765 gspca_dev->usb_buf[1] = 0x00;
766 err_code = mr_write(gspca_dev, 2);
767 if (err_code < 0)
768 return err_code;
700 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, 769 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
701 ARRAY_SIZE(cif_sensor1_init_data)); 770 ARRAY_SIZE(cif_sensor1_init_data));
702 } 771 }
@@ -717,6 +786,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
717 data[5] = 0x00; 786 data[5] = 0x00;
718 data[10] = 0x91; 787 data[10] = 0x91;
719 } 788 }
789 if (sd->sensor_type == 2) {
790 data[5] = 0x00;
791 data[10] = 0x18;
792 }
720 793
721 switch (gspca_dev->width) { 794 switch (gspca_dev->width) {
722 case 160: 795 case 160:
@@ -731,6 +804,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
731 data[4] = 0x78; /* reg 3, V size/4 */ 804 data[4] = 0x78; /* reg 3, V size/4 */
732 data[6] = 0x04; /* reg 5, H start */ 805 data[6] = 0x04; /* reg 5, H start */
733 data[8] = 0x03; /* reg 7, V start */ 806 data[8] = 0x03; /* reg 7, V start */
807 if (sd->sensor_type == 2) {
808 data[6] = 2;
809 data[8] = 1;
810 }
734 if (sd->do_lcd_stop) 811 if (sd->do_lcd_stop)
735 data[8] = 0x04; /* Bayer tile shifted */ 812 data[8] = 0x04; /* Bayer tile shifted */
736 break; 813 break;
@@ -753,7 +830,6 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
753 return err_code; 830 return err_code;
754 831
755 if (!sd->sensor_type) { 832 if (!sd->sensor_type) {
756 /* The only known sensor_type 0 cam is the Argus DC-1620 */
757 const struct sensor_w_data vga_sensor0_init_data[] = { 833 const struct sensor_w_data vga_sensor0_init_data[] = {
758 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, 834 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
759 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, 835 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
@@ -764,7 +840,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
764 }; 840 };
765 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, 841 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
766 ARRAY_SIZE(vga_sensor0_init_data)); 842 ARRAY_SIZE(vga_sensor0_init_data));
767 } else { /* sd->sensor_type = 1 */ 843 } else if (sd->sensor_type == 1) {
768 const struct sensor_w_data color_adj[] = { 844 const struct sensor_w_data color_adj[] = {
769 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, 845 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
770 /* adjusted blue, green, red gain correct 846 /* adjusted blue, green, red gain correct
@@ -802,6 +878,48 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
802 878
803 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, 879 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
804 ARRAY_SIZE(vga_sensor1_init_data)); 880 ARRAY_SIZE(vga_sensor1_init_data));
881 } else { /* sensor type == 2 */
882 const struct sensor_w_data vga_sensor2_init_data[] = {
883
884 {0x01, 0x00, {0x48}, 1},
885 {0x02, 0x00, {0x22}, 1},
886 /* Reg 3 msb and 4 is lsb of the exposure setting*/
887 {0x05, 0x00, {0x10}, 1},
888 {0x06, 0x00, {0x00}, 1},
889 {0x07, 0x00, {0x00}, 1},
890 {0x08, 0x00, {0x00}, 1},
891 {0x09, 0x00, {0x00}, 1},
892 /* The following are used in the gain control
893 * which is BTW completely borked in the OEM driver
894 * The values for each color go from 0 to 0x7ff
895 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
896 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
897 *{0x0c, 0x00, {0x01}, 1}, red gain msb
898 *{0x0d, 0x00, {0x10}, 1}, red gain lsb
899 *{0x0e, 0x00, {0x01}, 1}, blue gain msb
900 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
901 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
902 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
903 */
904 {0x12, 0x00, {0x00}, 1},
905 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
906 {0x14, 0x00, {0x00}, 1},
907 {0x15, 0x00, {0x06}, 1},
908 {0x16, 0x00, {0x01}, 1},
909 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
910 {0x18, 0x00, {0x02}, 1},
911 {0x19, 0x00, {0x82}, 1}, /* don't mess with */
912 {0x1a, 0x00, {0x00}, 1},
913 {0x1b, 0x00, {0x20}, 1},
914 /* {0x1c, 0x00, {0x17}, 1}, contrast control */
915 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
916 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
917 {0x1f, 0x00, {0x0c}, 1},
918 {0x20, 0x00, {0x00}, 1},
919 {0, 0, {0}, 0}
920 };
921 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
922 ARRAY_SIZE(vga_sensor2_init_data));
805 } 923 }
806 return err_code; 924 return err_code;
807} 925}
@@ -834,6 +952,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
834 return err_code; 952 return err_code;
835 953
836 setbrightness(gspca_dev); 954 setbrightness(gspca_dev);
955 setcontrast(gspca_dev);
837 setexposure(gspca_dev); 956 setexposure(gspca_dev);
838 setgain(gspca_dev); 957 setgain(gspca_dev);
839 958
@@ -893,7 +1012,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
893static void setexposure(struct gspca_dev *gspca_dev) 1012static void setexposure(struct gspca_dev *gspca_dev)
894{ 1013{
895 struct sd *sd = (struct sd *) gspca_dev; 1014 struct sd *sd = (struct sd *) gspca_dev;
896 int exposure; 1015 int exposure = MR97310A_EXPOSURE_DEFAULT;
897 u8 buf[2]; 1016 u8 buf[2];
898 1017
899 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) 1018 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
@@ -905,6 +1024,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
905 exposure = (sd->exposure * 9267) / 10000 + 300; 1024 exposure = (sd->exposure * 9267) / 10000 + 300;
906 sensor_write1(gspca_dev, 3, exposure >> 4); 1025 sensor_write1(gspca_dev, 3, exposure >> 4);
907 sensor_write1(gspca_dev, 4, exposure & 0x0f); 1026 sensor_write1(gspca_dev, 4, exposure & 0x0f);
1027 } else if (sd->sensor_type == 2) {
1028 exposure = sd->exposure;
1029 exposure >>= 3;
1030 sensor_write1(gspca_dev, 3, exposure >> 8);
1031 sensor_write1(gspca_dev, 4, exposure & 0xff);
908 } else { 1032 } else {
909 /* We have both a clock divider and an exposure register. 1033 /* We have both a clock divider and an exposure register.
910 We first calculate the clock divider, as that determines 1034 We first calculate the clock divider, as that determines
@@ -943,17 +1067,34 @@ static void setexposure(struct gspca_dev *gspca_dev)
943static void setgain(struct gspca_dev *gspca_dev) 1067static void setgain(struct gspca_dev *gspca_dev)
944{ 1068{
945 struct sd *sd = (struct sd *) gspca_dev; 1069 struct sd *sd = (struct sd *) gspca_dev;
1070 u8 gainreg;
946 1071
947 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) 1072 if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) &&
1073 (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX)))
948 return; 1074 return;
949 1075
950 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { 1076 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
951 sensor_write1(gspca_dev, 0x0e, sd->gain); 1077 sensor_write1(gspca_dev, 0x0e, sd->gain);
952 } else { 1078 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
1079 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
1080 sensor_write1(gspca_dev, gainreg, sd->gain >> 8);
1081 sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff);
1082 }
1083 else
953 sensor_write1(gspca_dev, 0x10, sd->gain); 1084 sensor_write1(gspca_dev, 0x10, sd->gain);
954 }
955} 1085}
956 1086
1087static void setcontrast(struct gspca_dev *gspca_dev)
1088{
1089 struct sd *sd = (struct sd *) gspca_dev;
1090
1091 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
1092 return;
1093
1094 sensor_write1(gspca_dev, 0x1c, sd->contrast);
1095}
1096
1097
957static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1098static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
958{ 1099{
959 struct sd *sd = (struct sd *) gspca_dev; 1100 struct sd *sd = (struct sd *) gspca_dev;
@@ -1008,6 +1149,25 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1008 return 0; 1149 return 0;
1009} 1150}
1010 1151
1152static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1153{
1154 struct sd *sd = (struct sd *) gspca_dev;
1155
1156 sd->contrast = val;
1157 if (gspca_dev->streaming)
1158 setcontrast(gspca_dev);
1159 return 0;
1160}
1161
1162
1163static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1164{
1165 struct sd *sd = (struct sd *) gspca_dev;
1166
1167 *val = sd->contrast;
1168 return 0;
1169}
1170
1011static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) 1171static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1012{ 1172{
1013 struct sd *sd = (struct sd *) gspca_dev; 1173 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index b4f965731244..bc4ced6c013b 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -38,6 +38,7 @@
38 */ 38 */
39#define MODULE_NAME "ov519" 39#define MODULE_NAME "ov519"
40 40
41#include <linux/input.h>
41#include "gspca.h" 42#include "gspca.h"
42 43
43MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 44MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
@@ -70,6 +71,9 @@ struct sd {
70 char invert_led; 71 char invert_led;
71#define BRIDGE_INVERT_LED 8 72#define BRIDGE_INVERT_LED 8
72 73
74 char snapshot_pressed;
75 char snapshot_needs_reset;
76
73 /* Determined by sensor type */ 77 /* Determined by sensor type */
74 __u8 sif; 78 __u8 sif;
75 79
@@ -99,10 +103,12 @@ struct sd {
99#define SEN_OV66308AF 5 103#define SEN_OV66308AF 5
100#define SEN_OV7610 6 104#define SEN_OV7610 6
101#define SEN_OV7620 7 105#define SEN_OV7620 7
102#define SEN_OV7640 8 106#define SEN_OV7620AE 8
103#define SEN_OV7670 9 107#define SEN_OV7640 9
104#define SEN_OV76BE 10 108#define SEN_OV7648 10
105#define SEN_OV8610 11 109#define SEN_OV7670 11
110#define SEN_OV76BE 12
111#define SEN_OV8610 13
106 112
107 u8 sensor_addr; 113 u8 sensor_addr;
108 int sensor_width; 114 int sensor_width;
@@ -139,6 +145,7 @@ static void setautobrightness(struct sd *sd);
139static void setfreq(struct sd *sd); 145static void setfreq(struct sd *sd);
140 146
141static const struct ctrl sd_ctrls[] = { 147static const struct ctrl sd_ctrls[] = {
148#define BRIGHTNESS_IDX 0
142 { 149 {
143 { 150 {
144 .id = V4L2_CID_BRIGHTNESS, 151 .id = V4L2_CID_BRIGHTNESS,
@@ -153,6 +160,7 @@ static const struct ctrl sd_ctrls[] = {
153 .set = sd_setbrightness, 160 .set = sd_setbrightness,
154 .get = sd_getbrightness, 161 .get = sd_getbrightness,
155 }, 162 },
163#define CONTRAST_IDX 1
156 { 164 {
157 { 165 {
158 .id = V4L2_CID_CONTRAST, 166 .id = V4L2_CID_CONTRAST,
@@ -167,6 +175,7 @@ static const struct ctrl sd_ctrls[] = {
167 .set = sd_setcontrast, 175 .set = sd_setcontrast,
168 .get = sd_getcontrast, 176 .get = sd_getcontrast,
169 }, 177 },
178#define COLOR_IDX 2
170 { 179 {
171 { 180 {
172 .id = V4L2_CID_SATURATION, 181 .id = V4L2_CID_SATURATION,
@@ -2554,7 +2563,7 @@ static int ov7xx0_configure(struct sd *sd)
2554 /* I don't know what's different about the 76BE yet. */ 2563 /* I don't know what's different about the 76BE yet. */
2555 if (i2c_r(sd, 0x15) & 1) { 2564 if (i2c_r(sd, 0x15) & 1) {
2556 PDEBUG(D_PROBE, "Sensor is an OV7620AE"); 2565 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
2557 sd->sensor = SEN_OV7620; 2566 sd->sensor = SEN_OV7620AE;
2558 } else { 2567 } else {
2559 PDEBUG(D_PROBE, "Sensor is an OV76BE"); 2568 PDEBUG(D_PROBE, "Sensor is an OV76BE");
2560 sd->sensor = SEN_OV76BE; 2569 sd->sensor = SEN_OV76BE;
@@ -2588,7 +2597,7 @@ static int ov7xx0_configure(struct sd *sd)
2588 break; 2597 break;
2589 case 0x48: 2598 case 0x48:
2590 PDEBUG(D_PROBE, "Sensor is an OV7648"); 2599 PDEBUG(D_PROBE, "Sensor is an OV7648");
2591 sd->sensor = SEN_OV7640; /* FIXME */ 2600 sd->sensor = SEN_OV7648;
2592 break; 2601 break;
2593 default: 2602 default:
2594 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); 2603 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
@@ -2680,6 +2689,36 @@ static void ov51x_led_control(struct sd *sd, int on)
2680 } 2689 }
2681} 2690}
2682 2691
2692static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2693{
2694 struct sd *sd = (struct sd *) gspca_dev;
2695
2696 if (!sd->snapshot_needs_reset)
2697 return;
2698
2699 /* Note it is important that we clear sd->snapshot_needs_reset,
2700 before actually clearing the snapshot state in the bridge
2701 otherwise we might race with the pkt_scan interrupt handler */
2702 sd->snapshot_needs_reset = 0;
2703
2704 switch (sd->bridge) {
2705 case BRIDGE_OV511:
2706 case BRIDGE_OV511PLUS:
2707 reg_w(sd, R51x_SYS_SNAP, 0x02);
2708 reg_w(sd, R51x_SYS_SNAP, 0x00);
2709 break;
2710 case BRIDGE_OV518:
2711 case BRIDGE_OV518PLUS:
2712 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2713 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2714 break;
2715 case BRIDGE_OV519:
2716 reg_w(sd, R51x_SYS_RESET, 0x40);
2717 reg_w(sd, R51x_SYS_RESET, 0x00);
2718 break;
2719 }
2720}
2721
2683static int ov51x_upload_quan_tables(struct sd *sd) 2722static int ov51x_upload_quan_tables(struct sd *sd)
2684{ 2723{
2685 const unsigned char yQuanTable511[] = { 2724 const unsigned char yQuanTable511[] = {
@@ -3115,7 +3154,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
3115 (1 << OV7670_FREQ_IDX); 3154 (1 << OV7670_FREQ_IDX);
3116 } 3155 }
3117 sd->quality = QUALITY_DEF; 3156 sd->quality = QUALITY_DEF;
3118 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) 3157 if (sd->sensor == SEN_OV7640 ||
3158 sd->sensor == SEN_OV7648)
3159 gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) |
3160 (1 << CONTRAST_IDX);
3161 if (sd->sensor == SEN_OV7670)
3119 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; 3162 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
3120 /* OV8610 Frequency filter control should work but needs testing */ 3163 /* OV8610 Frequency filter control should work but needs testing */
3121 if (sd->sensor == SEN_OV8610) 3164 if (sd->sensor == SEN_OV8610)
@@ -3169,10 +3212,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
3169 return -EIO; 3212 return -EIO;
3170 break; 3213 break;
3171 case SEN_OV7620: 3214 case SEN_OV7620:
3215 case SEN_OV7620AE:
3172 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) 3216 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
3173 return -EIO; 3217 return -EIO;
3174 break; 3218 break;
3175 case SEN_OV7640: 3219 case SEN_OV7640:
3220 case SEN_OV7648:
3176 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) 3221 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
3177 return -EIO; 3222 return -EIO;
3178 break; 3223 break;
@@ -3246,7 +3291,9 @@ static int ov511_mode_init_regs(struct sd *sd)
3246 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed 3291 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3247 for more sensors we need to do this for them too */ 3292 for more sensors we need to do this for them too */
3248 case SEN_OV7620: 3293 case SEN_OV7620:
3294 case SEN_OV7620AE:
3249 case SEN_OV7640: 3295 case SEN_OV7640:
3296 case SEN_OV7648:
3250 case SEN_OV76BE: 3297 case SEN_OV76BE:
3251 if (sd->gspca_dev.width == 320) 3298 if (sd->gspca_dev.width == 320)
3252 interlaced = 1; 3299 interlaced = 1;
@@ -3377,7 +3424,7 @@ static int ov518_mode_init_regs(struct sd *sd)
3377 3424
3378 if (sd->bridge == BRIDGE_OV518PLUS) { 3425 if (sd->bridge == BRIDGE_OV518PLUS) {
3379 switch (sd->sensor) { 3426 switch (sd->sensor) {
3380 case SEN_OV7620: 3427 case SEN_OV7620AE:
3381 if (sd->gspca_dev.width == 320) { 3428 if (sd->gspca_dev.width == 320) {
3382 reg_w(sd, 0x20, 0x00); 3429 reg_w(sd, 0x20, 0x00);
3383 reg_w(sd, 0x21, 0x19); 3430 reg_w(sd, 0x21, 0x19);
@@ -3386,6 +3433,10 @@ static int ov518_mode_init_regs(struct sd *sd)
3386 reg_w(sd, 0x21, 0x1f); 3433 reg_w(sd, 0x21, 0x1f);
3387 } 3434 }
3388 break; 3435 break;
3436 case SEN_OV7620:
3437 reg_w(sd, 0x20, 0x00);
3438 reg_w(sd, 0x21, 0x19);
3439 break;
3389 default: 3440 default:
3390 reg_w(sd, 0x21, 0x19); 3441 reg_w(sd, 0x21, 0x19);
3391 } 3442 }
@@ -3488,7 +3539,8 @@ static int ov519_mode_init_regs(struct sd *sd)
3488 if (write_regvals(sd, mode_init_519, 3539 if (write_regvals(sd, mode_init_519,
3489 ARRAY_SIZE(mode_init_519))) 3540 ARRAY_SIZE(mode_init_519)))
3490 return -EIO; 3541 return -EIO;
3491 if (sd->sensor == SEN_OV7640) { 3542 if (sd->sensor == SEN_OV7640 ||
3543 sd->sensor == SEN_OV7648) {
3492 /* Select 8-bit input mode */ 3544 /* Select 8-bit input mode */
3493 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); 3545 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
3494 } 3546 }
@@ -3503,6 +3555,9 @@ static int ov519_mode_init_regs(struct sd *sd)
3503 if (sd->sensor == SEN_OV7670 && 3555 if (sd->sensor == SEN_OV7670 &&
3504 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) 3556 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3505 reg_w(sd, OV519_R12_X_OFFSETL, 0x04); 3557 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
3558 else if (sd->sensor == SEN_OV7648 &&
3559 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3560 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
3506 else 3561 else
3507 reg_w(sd, OV519_R12_X_OFFSETL, 0x00); 3562 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
3508 reg_w(sd, OV519_R13_X_OFFSETH, 0x00); 3563 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
@@ -3520,6 +3575,7 @@ static int ov519_mode_init_regs(struct sd *sd)
3520 sd->clockdiv = 0; 3575 sd->clockdiv = 0;
3521 switch (sd->sensor) { 3576 switch (sd->sensor) {
3522 case SEN_OV7640: 3577 case SEN_OV7640:
3578 case SEN_OV7648:
3523 switch (sd->frame_rate) { 3579 switch (sd->frame_rate) {
3524 default: 3580 default:
3525/* case 30: */ 3581/* case 30: */
@@ -3649,6 +3705,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3649 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ 3705 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3650 break; 3706 break;
3651 case SEN_OV7620: 3707 case SEN_OV7620:
3708 case SEN_OV7620AE:
3652 case SEN_OV76BE: 3709 case SEN_OV76BE:
3653 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3710 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3654 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); 3711 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
@@ -3663,13 +3720,16 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
3663 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); 3720 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3664 break; 3721 break;
3665 case SEN_OV7640: 3722 case SEN_OV7640:
3723 case SEN_OV7648:
3666 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 3724 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3667 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); 3725 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3668/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ 3726 /* Setting this undocumented bit in qvga mode removes a very
3669/* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ 3727 annoying vertical shaking of the image */
3670/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ 3728 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3671/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ 3729 /* Unknown */
3672/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ 3730 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3731 /* Allow higher automatic gain (to allow higher framerates) */
3732 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3673 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ 3733 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
3674 break; 3734 break;
3675 case SEN_OV7670: 3735 case SEN_OV7670:
@@ -3795,11 +3855,13 @@ static int set_ov_sensor_window(struct sd *sd)
3795 } 3855 }
3796 break; 3856 break;
3797 case SEN_OV7620: 3857 case SEN_OV7620:
3858 case SEN_OV7620AE:
3798 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ 3859 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
3799 hwebase = 0x2f; 3860 hwebase = 0x2f;
3800 vwsbase = vwebase = 0x05; 3861 vwsbase = vwebase = 0x05;
3801 break; 3862 break;
3802 case SEN_OV7640: 3863 case SEN_OV7640:
3864 case SEN_OV7648:
3803 hwsbase = 0x1a; 3865 hwsbase = 0x1a;
3804 hwebase = 0x1a; 3866 hwebase = 0x1a;
3805 vwsbase = vwebase = 0x03; 3867 vwsbase = vwebase = 0x03;
@@ -3893,6 +3955,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
3893 setautobrightness(sd); 3955 setautobrightness(sd);
3894 setfreq(sd); 3956 setfreq(sd);
3895 3957
3958 /* Force clear snapshot state in case the snapshot button was
3959 pressed while we weren't streaming */
3960 sd->snapshot_needs_reset = 1;
3961 sd_reset_snapshot(gspca_dev);
3962 sd->snapshot_pressed = 0;
3963
3896 ret = ov51x_restart(sd); 3964 ret = ov51x_restart(sd);
3897 if (ret < 0) 3965 if (ret < 0)
3898 goto out; 3966 goto out;
@@ -3919,6 +3987,34 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
3919 w9968cf_stop0(sd); 3987 w9968cf_stop0(sd);
3920} 3988}
3921 3989
3990static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
3991{
3992 struct sd *sd = (struct sd *) gspca_dev;
3993
3994 if (sd->snapshot_pressed != state) {
3995#ifdef CONFIG_INPUT
3996 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
3997 input_sync(gspca_dev->input_dev);
3998#endif
3999 if (state)
4000 sd->snapshot_needs_reset = 1;
4001
4002 sd->snapshot_pressed = state;
4003 } else {
4004 /* On the ov511 / ov519 we need to reset the button state
4005 multiple times, as resetting does not work as long as the
4006 button stays pressed */
4007 switch (sd->bridge) {
4008 case BRIDGE_OV511:
4009 case BRIDGE_OV511PLUS:
4010 case BRIDGE_OV519:
4011 if (state)
4012 sd->snapshot_needs_reset = 1;
4013 break;
4014 }
4015 }
4016}
4017
3922static void ov511_pkt_scan(struct gspca_dev *gspca_dev, 4018static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
3923 u8 *in, /* isoc packet */ 4019 u8 *in, /* isoc packet */
3924 int len) /* iso packet length */ 4020 int len) /* iso packet length */
@@ -3940,6 +4036,7 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
3940 */ 4036 */
3941 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) && 4037 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
3942 (in[8] & 0x08)) { 4038 (in[8] & 0x08)) {
4039 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
3943 if (in[8] & 0x80) { 4040 if (in[8] & 0x80) {
3944 /* Frame end */ 4041 /* Frame end */
3945 if ((in[9] + 1) * 8 != gspca_dev->width || 4042 if ((in[9] + 1) * 8 != gspca_dev->width ||
@@ -3977,6 +4074,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
3977 /* A false positive here is likely, until OVT gives me 4074 /* A false positive here is likely, until OVT gives me
3978 * the definitive SOF/EOF format */ 4075 * the definitive SOF/EOF format */
3979 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { 4076 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
4077 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
3980 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 4078 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
3981 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); 4079 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
3982 sd->packet_nr = 0; 4080 sd->packet_nr = 0;
@@ -4024,6 +4122,9 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
4024 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { 4122 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4025 switch (data[3]) { 4123 switch (data[3]) {
4026 case 0x50: /* start of frame */ 4124 case 0x50: /* start of frame */
4125 /* Don't check the button state here, as the state
4126 usually (always ?) changes at EOF and checking it
4127 here leads to unnecessary snapshot state resets. */
4027#define HDRSZ 16 4128#define HDRSZ 16
4028 data += HDRSZ; 4129 data += HDRSZ;
4029 len -= HDRSZ; 4130 len -= HDRSZ;
@@ -4035,6 +4136,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
4035 gspca_dev->last_packet_type = DISCARD_PACKET; 4136 gspca_dev->last_packet_type = DISCARD_PACKET;
4036 return; 4137 return;
4037 case 0x51: /* end of frame */ 4138 case 0x51: /* end of frame */
4139 ov51x_handle_button(gspca_dev, data[11] & 1);
4038 if (data[9] != 0) 4140 if (data[9] != 0)
4039 gspca_dev->last_packet_type = DISCARD_PACKET; 4141 gspca_dev->last_packet_type = DISCARD_PACKET;
4040 gspca_frame_add(gspca_dev, LAST_PACKET, 4142 gspca_frame_add(gspca_dev, LAST_PACKET,
@@ -4103,9 +4205,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
4103 case SEN_OV6630: 4205 case SEN_OV6630:
4104 case SEN_OV66308AF: 4206 case SEN_OV66308AF:
4105 case SEN_OV7640: 4207 case SEN_OV7640:
4208 case SEN_OV7648:
4106 i2c_w(sd, OV7610_REG_BRT, val); 4209 i2c_w(sd, OV7610_REG_BRT, val);
4107 break; 4210 break;
4108 case SEN_OV7620: 4211 case SEN_OV7620:
4212 case SEN_OV7620AE:
4109 /* 7620 doesn't like manual changes when in auto mode */ 4213 /* 7620 doesn't like manual changes when in auto mode */
4110 if (!sd->autobrightness) 4214 if (!sd->autobrightness)
4111 i2c_w(sd, OV7610_REG_BRT, val); 4215 i2c_w(sd, OV7610_REG_BRT, val);
@@ -4142,7 +4246,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4142 i2c_w(sd, 0x64, ctab[val >> 5]); 4246 i2c_w(sd, 0x64, ctab[val >> 5]);
4143 break; 4247 break;
4144 } 4248 }
4145 case SEN_OV7620: { 4249 case SEN_OV7620:
4250 case SEN_OV7620AE: {
4146 static const __u8 ctab[] = { 4251 static const __u8 ctab[] = {
4147 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, 4252 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4148 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff 4253 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
@@ -4152,10 +4257,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4152 i2c_w(sd, 0x64, ctab[val >> 4]); 4257 i2c_w(sd, 0x64, ctab[val >> 4]);
4153 break; 4258 break;
4154 } 4259 }
4155 case SEN_OV7640:
4156 /* Use gain control instead. */
4157 i2c_w(sd, OV7610_REG_GAIN, val >> 2);
4158 break;
4159 case SEN_OV7670: 4260 case SEN_OV7670:
4160 /* check that this isn't just the same as ov7610 */ 4261 /* check that this isn't just the same as ov7610 */
4161 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 4262 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
@@ -4179,6 +4280,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
4179 i2c_w(sd, OV7610_REG_SAT, val); 4280 i2c_w(sd, OV7610_REG_SAT, val);
4180 break; 4281 break;
4181 case SEN_OV7620: 4282 case SEN_OV7620:
4283 case SEN_OV7620AE:
4182 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ 4284 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4183/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); 4285/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4184 if (rc < 0) 4286 if (rc < 0)
@@ -4186,6 +4288,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
4186 i2c_w(sd, OV7610_REG_SAT, val); 4288 i2c_w(sd, OV7610_REG_SAT, val);
4187 break; 4289 break;
4188 case SEN_OV7640: 4290 case SEN_OV7640:
4291 case SEN_OV7648:
4189 i2c_w(sd, OV7610_REG_SAT, val & 0xf0); 4292 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4190 break; 4293 break;
4191 case SEN_OV7670: 4294 case SEN_OV7670:
@@ -4198,7 +4301,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
4198 4301
4199static void setautobrightness(struct sd *sd) 4302static void setautobrightness(struct sd *sd)
4200{ 4303{
4201 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 || 4304 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
4305 sd->sensor == SEN_OV7670 ||
4202 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) 4306 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4203 return; 4307 return;
4204 4308
@@ -4475,9 +4579,13 @@ static const struct sd_desc sd_desc = {
4475 .stopN = sd_stopN, 4579 .stopN = sd_stopN,
4476 .stop0 = sd_stop0, 4580 .stop0 = sd_stop0,
4477 .pkt_scan = sd_pkt_scan, 4581 .pkt_scan = sd_pkt_scan,
4582 .dq_callback = sd_reset_snapshot,
4478 .querymenu = sd_querymenu, 4583 .querymenu = sd_querymenu,
4479 .get_jcomp = sd_get_jcomp, 4584 .get_jcomp = sd_get_jcomp,
4480 .set_jcomp = sd_set_jcomp, 4585 .set_jcomp = sd_set_jcomp,
4586#ifdef CONFIG_INPUT
4587 .other_input = 1,
4588#endif
4481}; 4589};
4482 4590
4483/* -- module initialisation -- */ 4591/* -- module initialisation -- */
@@ -4494,7 +4602,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
4494 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, 4602 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4495 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, 4603 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4496 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, 4604 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
4497 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, 4605 {USB_DEVICE(0x054c, 0x0155),
4606 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4498 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, 4607 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
4499 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, 4608 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4500 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, 4609 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 0a6b8f07a69d..957e05e2d08f 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534-ov772x gspca driver
3 * 3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
@@ -68,12 +68,7 @@ struct sd {
68 s8 sharpness; 68 s8 sharpness;
69 u8 hflip; 69 u8 hflip;
70 u8 vflip; 70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
73 71
74 u8 sensor;
75#define SENSOR_OV772X 0
76#define SENSOR_OV965X 1
77}; 72};
78 73
79/* V4L2 controls supported by the driver */ 74/* V4L2 controls supported by the driver */
@@ -101,12 +96,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 96static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 97static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 98static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
108 99
109static struct ctrl sd_ctrls_ov772x[] = { 100static const struct ctrl sd_ctrls[] = {
110 { /* 0 */ 101 { /* 0 */
111 { 102 {
112 .id = V4L2_CID_BRIGHTNESS, 103 .id = V4L2_CID_BRIGHTNESS,
@@ -115,8 +106,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
115 .minimum = 0, 106 .minimum = 0,
116 .maximum = 255, 107 .maximum = 255,
117 .step = 1, 108 .step = 1,
118#define BRIGHTNESS_77_DEF 20 109#define BRIGHTNESS_DEF 20
119 .default_value = BRIGHTNESS_77_DEF, 110 .default_value = BRIGHTNESS_DEF,
120 }, 111 },
121 .set = sd_setbrightness, 112 .set = sd_setbrightness,
122 .get = sd_getbrightness, 113 .get = sd_getbrightness,
@@ -129,8 +120,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
129 .minimum = 0, 120 .minimum = 0,
130 .maximum = 255, 121 .maximum = 255,
131 .step = 1, 122 .step = 1,
132#define CONTRAST_77_DEF 37 123#define CONTRAST_DEF 37
133 .default_value = CONTRAST_77_DEF, 124 .default_value = CONTRAST_DEF,
134 }, 125 },
135 .set = sd_setcontrast, 126 .set = sd_setcontrast,
136 .get = sd_getcontrast, 127 .get = sd_getcontrast,
@@ -157,8 +148,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
157 .minimum = 0, 148 .minimum = 0,
158 .maximum = 255, 149 .maximum = 255,
159 .step = 1, 150 .step = 1,
160#define EXPO_77_DEF 120 151#define EXPO_DEF 120
161 .default_value = EXPO_77_DEF, 152 .default_value = EXPO_DEF,
162 }, 153 },
163 .set = sd_setexposure, 154 .set = sd_setexposure,
164 .get = sd_getexposure, 155 .get = sd_getexposure,
@@ -213,13 +204,13 @@ static struct ctrl sd_ctrls_ov772x[] = {
213 .minimum = 0, 204 .minimum = 0,
214 .maximum = 1, 205 .maximum = 1,
215 .step = 1, 206 .step = 1,
216#define AUTOGAIN_77_DEF 0 207#define AUTOGAIN_DEF 0
217 .default_value = AUTOGAIN_77_DEF, 208 .default_value = AUTOGAIN_DEF,
218 }, 209 },
219 .set = sd_setautogain, 210 .set = sd_setautogain,
220 .get = sd_getautogain, 211 .get = sd_getautogain,
221 }, 212 },
222#define AWB_77_IDX 8 213#define AWB_IDX 8
223 { /* 8 */ 214 { /* 8 */
224 { 215 {
225 .id = V4L2_CID_AUTO_WHITE_BALANCE, 216 .id = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -242,8 +233,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
242 .minimum = 0, 233 .minimum = 0,
243 .maximum = 63, 234 .maximum = 63,
244 .step = 1, 235 .step = 1,
245#define SHARPNESS_77_DEF 0 236#define SHARPNESS_DEF 0
246 .default_value = SHARPNESS_77_DEF, 237 .default_value = SHARPNESS_DEF,
247 }, 238 },
248 .set = sd_setsharpness, 239 .set = sd_setsharpness,
249 .get = sd_getsharpness, 240 .get = sd_getsharpness,
@@ -277,107 +268,6 @@ static struct ctrl sd_ctrls_ov772x[] = {
277 .get = sd_getvflip, 268 .get = sd_getvflip,
278 }, 269 },
279}; 270};
280static struct ctrl sd_ctrls_ov965x[] = {
281 { /* 0 */
282 {
283 .id = V4L2_CID_BRIGHTNESS,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "Brightness",
286 .minimum = 0,
287 .maximum = 15,
288 .step = 1,
289#define BRIGHTNESS_96_DEF 7
290 .default_value = BRIGHTNESS_96_DEF,
291 },
292 .set = sd_setbrightness,
293 .get = sd_getbrightness,
294 },
295 { /* 1 */
296 {
297 .id = V4L2_CID_CONTRAST,
298 .type = V4L2_CTRL_TYPE_INTEGER,
299 .name = "Contrast",
300 .minimum = 0,
301 .maximum = 15,
302 .step = 1,
303#define CONTRAST_96_DEF 3
304 .default_value = CONTRAST_96_DEF,
305 },
306 .set = sd_setcontrast,
307 .get = sd_getcontrast,
308 },
309 { /* 2 */
310 {
311 .id = V4L2_CID_AUTOGAIN,
312 .type = V4L2_CTRL_TYPE_BOOLEAN,
313 .name = "Autogain",
314 .minimum = 0,
315 .maximum = 1,
316 .step = 1,
317#define AUTOGAIN_96_DEF 1
318 .default_value = AUTOGAIN_96_DEF,
319 },
320 .set = sd_setautogain,
321 .get = sd_getautogain,
322 },
323#define EXPO_96_IDX 3
324 { /* 3 */
325 {
326 .id = V4L2_CID_EXPOSURE,
327 .type = V4L2_CTRL_TYPE_INTEGER,
328 .name = "Exposure",
329 .minimum = 0,
330 .maximum = 3,
331 .step = 1,
332#define EXPO_96_DEF 0
333 .default_value = EXPO_96_DEF,
334 },
335 .set = sd_setexposure,
336 .get = sd_getexposure,
337 },
338 { /* 4 */
339 {
340 .id = V4L2_CID_SHARPNESS,
341 .type = V4L2_CTRL_TYPE_INTEGER,
342 .name = "Sharpness",
343 .minimum = -1, /* -1 = auto */
344 .maximum = 4,
345 .step = 1,
346#define SHARPNESS_96_DEF -1
347 .default_value = SHARPNESS_96_DEF,
348 },
349 .set = sd_setsharpness,
350 .get = sd_getsharpness,
351 },
352 { /* 5 */
353 {
354 .id = V4L2_CID_SATURATION,
355 .type = V4L2_CTRL_TYPE_INTEGER,
356 .name = "Saturation",
357 .minimum = 0,
358 .maximum = 4,
359 .step = 1,
360#define SATUR_DEF 2
361 .default_value = SATUR_DEF,
362 },
363 .set = sd_setsatur,
364 .get = sd_getsatur,
365 },
366 {
367 {
368 .id = V4L2_CID_POWER_LINE_FREQUENCY,
369 .type = V4L2_CTRL_TYPE_MENU,
370 .name = "Light frequency filter",
371 .minimum = 0,
372 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
373 .step = 1,
374#define FREQ_DEF 0
375 .default_value = FREQ_DEF,
376 },
377 .set = sd_setfreq,
378 .get = sd_getfreq,
379 },
380};
381 271
382static const struct v4l2_pix_format ov772x_mode[] = { 272static const struct v4l2_pix_format ov772x_mode[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 273 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
@@ -392,35 +282,21 @@ static const struct v4l2_pix_format ov772x_mode[] = {
392 .priv = 0}, 282 .priv = 0},
393}; 283};
394 284
395static const struct v4l2_pix_format ov965x_mode[] = { 285static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
396 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 286static const u8 vga_rates[] = {60, 50, 40, 30, 15};
397 .bytesperline = 320, 287
398 .sizeimage = 320 * 240 * 3 / 8 + 590, 288static const struct framerates ov772x_framerates[] = {
399 .colorspace = V4L2_COLORSPACE_JPEG, 289 { /* 320x240 */
400 .priv = 4}, 290 .rates = qvga_rates,
401 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 291 .nrates = ARRAY_SIZE(qvga_rates),
402 .bytesperline = 640, 292 },
403 .sizeimage = 640 * 480 * 3 / 8 + 590, 293 { /* 640x480 */
404 .colorspace = V4L2_COLORSPACE_JPEG, 294 .rates = vga_rates,
405 .priv = 3}, 295 .nrates = ARRAY_SIZE(vga_rates),
406 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 296 },
407 .bytesperline = 800,
408 .sizeimage = 800 * 600 * 3 / 8 + 590,
409 .colorspace = V4L2_COLORSPACE_JPEG,
410 .priv = 2},
411 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
412 .bytesperline = 1024,
413 .sizeimage = 1024 * 768 * 3 / 8 + 590,
414 .colorspace = V4L2_COLORSPACE_JPEG,
415 .priv = 1},
416 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
417 .bytesperline = 1280,
418 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
419 .colorspace = V4L2_COLORSPACE_JPEG,
420 .priv = 0},
421}; 297};
422 298
423static const u8 bridge_init_ov772x[][2] = { 299static const u8 bridge_init[][2] = {
424 { 0xc2, 0x0c }, 300 { 0xc2, 0x0c },
425 { 0x88, 0xf8 }, 301 { 0x88, 0xf8 },
426 { 0xc3, 0x69 }, 302 { 0xc3, 0x69 },
@@ -478,7 +354,7 @@ static const u8 bridge_init_ov772x[][2] = {
478 { 0xc1, 0x3c }, 354 { 0xc1, 0x3c },
479 { 0xc2, 0x0c }, 355 { 0xc2, 0x0c },
480}; 356};
481static const u8 sensor_init_ov772x[][2] = { 357static const u8 sensor_init[][2] = {
482 { 0x12, 0x80 }, 358 { 0x12, 0x80 },
483 { 0x11, 0x01 }, 359 { 0x11, 0x01 },
484/*fixme: better have a delay?*/ 360/*fixme: better have a delay?*/
@@ -571,7 +447,7 @@ static const u8 sensor_init_ov772x[][2] = {
571 { 0x8e, 0x00 }, /* De-noise threshold */ 447 { 0x8e, 0x00 }, /* De-noise threshold */
572 { 0x0c, 0xd0 } 448 { 0x0c, 0xd0 }
573}; 449};
574static const u8 bridge_start_ov772x_vga[][2] = { 450static const u8 bridge_start_vga[][2] = {
575 {0x1c, 0x00}, 451 {0x1c, 0x00},
576 {0x1d, 0x40}, 452 {0x1d, 0x40},
577 {0x1d, 0x02}, 453 {0x1d, 0x02},
@@ -582,7 +458,7 @@ static const u8 bridge_start_ov772x_vga[][2] = {
582 {0xc0, 0x50}, 458 {0xc0, 0x50},
583 {0xc1, 0x3c}, 459 {0xc1, 0x3c},
584}; 460};
585static const u8 sensor_start_ov772x_vga[][2] = { 461static const u8 sensor_start_vga[][2] = {
586 {0x12, 0x00}, 462 {0x12, 0x00},
587 {0x17, 0x26}, 463 {0x17, 0x26},
588 {0x18, 0xa0}, 464 {0x18, 0xa0},
@@ -592,7 +468,7 @@ static const u8 sensor_start_ov772x_vga[][2] = {
592 {0x2c, 0xf0}, 468 {0x2c, 0xf0},
593 {0x65, 0x20}, 469 {0x65, 0x20},
594}; 470};
595static const u8 bridge_start_ov772x_qvga[][2] = { 471static const u8 bridge_start_qvga[][2] = {
596 {0x1c, 0x00}, 472 {0x1c, 0x00},
597 {0x1d, 0x40}, 473 {0x1d, 0x40},
598 {0x1d, 0x02}, 474 {0x1d, 0x02},
@@ -603,7 +479,7 @@ static const u8 bridge_start_ov772x_qvga[][2] = {
603 {0xc0, 0x28}, 479 {0xc0, 0x28},
604 {0xc1, 0x1e}, 480 {0xc1, 0x1e},
605}; 481};
606static const u8 sensor_start_ov772x_qvga[][2] = { 482static const u8 sensor_start_qvga[][2] = {
607 {0x12, 0x40}, 483 {0x12, 0x40},
608 {0x17, 0x3f}, 484 {0x17, 0x3f},
609 {0x18, 0x50}, 485 {0x18, 0x50},
@@ -614,571 +490,6 @@ static const u8 sensor_start_ov772x_qvga[][2] = {
614 {0x65, 0x2f}, 490 {0x65, 0x2f},
615}; 491};
616 492
617static const u8 bridge_init_ov965x[][2] = {
618 {0x88, 0xf8},
619 {0x89, 0xff},
620 {0x76, 0x03},
621 {0x92, 0x03},
622 {0x95, 0x10},
623 {0xe2, 0x00},
624 {0xe7, 0x3e},
625 {0x8d, 0x1c},
626 {0x8e, 0x00},
627 {0x8f, 0x00},
628 {0x1f, 0x00},
629 {0xc3, 0xf9},
630 {0x89, 0xff},
631 {0x88, 0xf8},
632 {0x76, 0x03},
633 {0x92, 0x01},
634 {0x93, 0x18},
635 {0x1c, 0x0a},
636 {0x1d, 0x48},
637 {0xc0, 0x50},
638 {0xc1, 0x3c},
639 {0x34, 0x05},
640 {0xc2, 0x0c},
641 {0xc3, 0xf9},
642 {0x34, 0x05},
643 {0xe7, 0x2e},
644 {0x31, 0xf9},
645 {0x35, 0x02},
646 {0xd9, 0x10},
647 {0x25, 0x42},
648 {0x94, 0x11},
649};
650
651static const u8 sensor_init_ov965x[][2] = {
652 {0x12, 0x80}, /* com7 - SSCB reset */
653 {0x00, 0x00}, /* gain */
654 {0x01, 0x80}, /* blue */
655 {0x02, 0x80}, /* red */
656 {0x03, 0x1b}, /* vref */
657 {0x04, 0x03}, /* com1 - exposure low bits */
658 {0x0b, 0x57}, /* ver */
659 {0x0e, 0x61}, /* com5 */
660 {0x0f, 0x42}, /* com6 */
661 {0x11, 0x00}, /* clkrc */
662 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
663 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
664 {0x14, 0x28}, /* com9 */
665 {0x16, 0x24}, /* reg16 */
666 {0x17, 0x1d}, /* hstart*/
667 {0x18, 0xbd}, /* hstop */
668 {0x19, 0x01}, /* vstrt */
669 {0x1a, 0x81}, /* vstop*/
670 {0x1e, 0x04}, /* mvfp */
671 {0x24, 0x3c}, /* aew */
672 {0x25, 0x36}, /* aeb */
673 {0x26, 0x71}, /* vpt */
674 {0x27, 0x08}, /* bbias */
675 {0x28, 0x08}, /* gbbias */
676 {0x29, 0x15}, /* gr com */
677 {0x2a, 0x00}, /* exhch */
678 {0x2b, 0x00}, /* exhcl */
679 {0x2c, 0x08}, /* rbias */
680 {0x32, 0xff}, /* href */
681 {0x33, 0x00}, /* chlf */
682 {0x34, 0x3f}, /* aref1 */
683 {0x35, 0x00}, /* aref2 */
684 {0x36, 0xf8}, /* aref3 */
685 {0x38, 0x72}, /* adc2 */
686 {0x39, 0x57}, /* aref4 */
687 {0x3a, 0x80}, /* tslb - yuyv */
688 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
689 {0x3d, 0x99}, /* com13 */
690 {0x3f, 0xc1}, /* edge */
691 {0x40, 0xc0}, /* com15 */
692 {0x41, 0x40}, /* com16 */
693 {0x42, 0xc0}, /* com17 */
694 {0x43, 0x0a}, /* rsvd */
695 {0x44, 0xf0},
696 {0x45, 0x46},
697 {0x46, 0x62},
698 {0x47, 0x2a},
699 {0x48, 0x3c},
700 {0x4a, 0xfc},
701 {0x4b, 0xfc},
702 {0x4c, 0x7f},
703 {0x4d, 0x7f},
704 {0x4e, 0x7f},
705 {0x4f, 0x98}, /* matrix */
706 {0x50, 0x98},
707 {0x51, 0x00},
708 {0x52, 0x28},
709 {0x53, 0x70},
710 {0x54, 0x98},
711 {0x58, 0x1a}, /* matrix coef sign */
712 {0x59, 0x85}, /* AWB control */
713 {0x5a, 0xa9},
714 {0x5b, 0x64},
715 {0x5c, 0x84},
716 {0x5d, 0x53},
717 {0x5e, 0x0e},
718 {0x5f, 0xf0}, /* AWB blue limit */
719 {0x60, 0xf0}, /* AWB red limit */
720 {0x61, 0xf0}, /* AWB green limit */
721 {0x62, 0x00}, /* lcc1 */
722 {0x63, 0x00}, /* lcc2 */
723 {0x64, 0x02}, /* lcc3 */
724 {0x65, 0x16}, /* lcc4 */
725 {0x66, 0x01}, /* lcc5 */
726 {0x69, 0x02}, /* hv */
727 {0x6b, 0x5a}, /* dbvl */
728 {0x6c, 0x04},
729 {0x6d, 0x55},
730 {0x6e, 0x00},
731 {0x6f, 0x9d},
732 {0x70, 0x21}, /* dnsth */
733 {0x71, 0x78},
734 {0x72, 0x00}, /* poidx */
735 {0x73, 0x01}, /* pckdv */
736 {0x74, 0x3a}, /* xindx */
737 {0x75, 0x35}, /* yindx */
738 {0x76, 0x01},
739 {0x77, 0x02},
740 {0x7a, 0x12}, /* gamma curve */
741 {0x7b, 0x08},
742 {0x7c, 0x16},
743 {0x7d, 0x30},
744 {0x7e, 0x5e},
745 {0x7f, 0x72},
746 {0x80, 0x82},
747 {0x81, 0x8e},
748 {0x82, 0x9a},
749 {0x83, 0xa4},
750 {0x84, 0xac},
751 {0x85, 0xb8},
752 {0x86, 0xc3},
753 {0x87, 0xd6},
754 {0x88, 0xe6},
755 {0x89, 0xf2},
756 {0x8a, 0x03},
757 {0x8c, 0x89}, /* com19 */
758 {0x14, 0x28}, /* com9 */
759 {0x90, 0x7d},
760 {0x91, 0x7b},
761 {0x9d, 0x03}, /* lcc6 */
762 {0x9e, 0x04}, /* lcc7 */
763 {0x9f, 0x7a},
764 {0xa0, 0x79},
765 {0xa1, 0x40}, /* aechm */
766 {0xa4, 0x50}, /* com21 */
767 {0xa5, 0x68}, /* com26 */
768 {0xa6, 0x4a}, /* AWB green */
769 {0xa8, 0xc1}, /* refa8 */
770 {0xa9, 0xef}, /* refa9 */
771 {0xaa, 0x92},
772 {0xab, 0x04},
773 {0xac, 0x80}, /* black level control */
774 {0xad, 0x80},
775 {0xae, 0x80},
776 {0xaf, 0x80},
777 {0xb2, 0xf2},
778 {0xb3, 0x20},
779 {0xb4, 0x20}, /* ctrlb4 */
780 {0xb5, 0x00},
781 {0xb6, 0xaf},
782 {0xbb, 0xae},
783 {0xbc, 0x7f}, /* ADC channel offsets */
784 {0xdb, 0x7f},
785 {0xbe, 0x7f},
786 {0xbf, 0x7f},
787 {0xc0, 0xe2},
788 {0xc1, 0xc0},
789 {0xc2, 0x01},
790 {0xc3, 0x4e},
791 {0xc6, 0x85},
792 {0xc7, 0x80}, /* com24 */
793 {0xc9, 0xe0},
794 {0xca, 0xe8},
795 {0xcb, 0xf0},
796 {0xcc, 0xd8},
797 {0xcd, 0xf1},
798 {0x4f, 0x98}, /* matrix */
799 {0x50, 0x98},
800 {0x51, 0x00},
801 {0x52, 0x28},
802 {0x53, 0x70},
803 {0x54, 0x98},
804 {0x58, 0x1a},
805 {0xff, 0x41}, /* read 41, write ff 00 */
806 {0x41, 0x40}, /* com16 */
807
808 {0xc5, 0x03}, /* 60 Hz banding filter */
809 {0x6a, 0x02}, /* 50 Hz banding filter */
810
811 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
812 {0x36, 0xfa}, /* aref3 */
813 {0x69, 0x0a}, /* hv */
814 {0x8c, 0x89}, /* com22 */
815 {0x14, 0x28}, /* com9 */
816 {0x3e, 0x0c},
817 {0x41, 0x40}, /* com16 */
818 {0x72, 0x00},
819 {0x73, 0x00},
820 {0x74, 0x3a},
821 {0x75, 0x35},
822 {0x76, 0x01},
823 {0xc7, 0x80},
824 {0x03, 0x12}, /* vref */
825 {0x17, 0x16}, /* hstart */
826 {0x18, 0x02}, /* hstop */
827 {0x19, 0x01}, /* vstrt */
828 {0x1a, 0x3d}, /* vstop */
829 {0x32, 0xff}, /* href */
830 {0xc0, 0xaa},
831};
832
833static const u8 bridge_init_ov965x_2[][2] = {
834 {0x94, 0xaa},
835 {0xf1, 0x60},
836 {0xe5, 0x04},
837 {0xc0, 0x50},
838 {0xc1, 0x3c},
839 {0x8c, 0x00},
840 {0x8d, 0x1c},
841 {0x34, 0x05},
842
843 {0xc2, 0x0c},
844 {0xc3, 0xf9},
845 {0xda, 0x01},
846 {0x50, 0x00},
847 {0x51, 0xa0},
848 {0x52, 0x3c},
849 {0x53, 0x00},
850 {0x54, 0x00},
851 {0x55, 0x00},
852 {0x57, 0x00},
853 {0x5c, 0x00},
854 {0x5a, 0xa0},
855 {0x5b, 0x78},
856 {0x35, 0x02},
857 {0xd9, 0x10},
858 {0x94, 0x11},
859};
860
861static const u8 sensor_init_ov965x_2[][2] = {
862 {0x3b, 0xc4},
863 {0x1e, 0x04}, /* mvfp */
864 {0x13, 0xe0}, /* com8 */
865 {0x00, 0x00}, /* gain */
866 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
867 {0x11, 0x03}, /* clkrc */
868 {0x6b, 0x5a}, /* dblv */
869 {0x6a, 0x05},
870 {0xc5, 0x07},
871 {0xa2, 0x4b},
872 {0xa3, 0x3e},
873 {0x2d, 0x00},
874 {0xff, 0x42}, /* read 42, write ff 00 */
875 {0x42, 0xc0}, /* com17 */
876 {0x2d, 0x00},
877 {0xff, 0x42}, /* read 42, write ff 00 */
878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
880 {0x3f, 0x01},
881 {0xff, 0x42}, /* read 42, write ff 00 */
882 {0x42, 0xc1}, /* com17 */
883/* saturation */
884 {0x4f, 0x98}, /* matrix */
885 {0x50, 0x98},
886 {0x51, 0x00},
887 {0x52, 0x28},
888 {0x53, 0x70},
889 {0x54, 0x98},
890 {0x58, 0x1a},
891 {0xff, 0x41}, /* read 41, write ff 00 */
892 {0x41, 0x40}, /* com16 */
893/* contrast */
894 {0x56, 0x40},
895/* brightness */
896 {0x55, 0x8f},
897/* expo */
898 {0x10, 0x25}, /* aech - exposure high bits */
899 {0xff, 0x13}, /* read 13, write ff 00 */
900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
901};
902
903static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */
904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
905 {0x36, 0xfa}, /* aref3 */
906 {0x69, 0x0a}, /* hv */
907 {0x8c, 0x89}, /* com22 */
908 {0x14, 0x28}, /* com9 */
909 {0x3e, 0x0c}, /* com14 */
910 {0x41, 0x40}, /* com16 */
911 {0x72, 0x00},
912 {0x73, 0x00},
913 {0x74, 0x3a},
914 {0x75, 0x35},
915 {0x76, 0x01},
916 {0xc7, 0x80}, /* com24 */
917 {0x03, 0x12}, /* vref */
918 {0x17, 0x16}, /* hstart */
919 {0x18, 0x02}, /* hstop */
920 {0x19, 0x01}, /* vstrt */
921 {0x1a, 0x3d}, /* vstop */
922 {0x32, 0xff}, /* href */
923 {0xc0, 0xaa},
924};
925
926static const u8 sensor_start_ov965x_1_svga[][2] = {
927 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
928 {0x36, 0xf8}, /* aref3 */
929 {0x69, 0x02}, /* hv */
930 {0x8c, 0x0d}, /* com22 */
931 {0x3e, 0x0c}, /* com14 */
932 {0x41, 0x40}, /* com16 */
933 {0x72, 0x00},
934 {0x73, 0x01},
935 {0x74, 0x3a},
936 {0x75, 0x35},
937 {0x76, 0x01},
938 {0xc7, 0x80}, /* com24 */
939 {0x03, 0x1b}, /* vref */
940 {0x17, 0x1d}, /* hstart */
941 {0x18, 0xbd}, /* hstop */
942 {0x19, 0x01}, /* vstrt */
943 {0x1a, 0x81}, /* vstop */
944 {0x32, 0xff}, /* href */
945 {0xc0, 0xe2},
946};
947
948static const u8 sensor_start_ov965x_1_xga[][2] = {
949 {0x12, 0x02}, /* com7 */
950 {0x36, 0xf8}, /* aref3 */
951 {0x69, 0x02}, /* hv */
952 {0x8c, 0x89}, /* com22 */
953 {0x14, 0x28}, /* com9 */
954 {0x3e, 0x0c}, /* com14 */
955 {0x41, 0x40}, /* com16 */
956 {0x72, 0x00},
957 {0x73, 0x01},
958 {0x74, 0x3a},
959 {0x75, 0x35},
960 {0x76, 0x01},
961 {0xc7, 0x80}, /* com24 */
962 {0x03, 0x1b}, /* vref */
963 {0x17, 0x1d}, /* hstart */
964 {0x18, 0xbd}, /* hstop */
965 {0x19, 0x01}, /* vstrt */
966 {0x1a, 0x81}, /* vstop */
967 {0x32, 0xff}, /* href */
968 {0xc0, 0xe2},
969};
970
971static const u8 sensor_start_ov965x_1_sxga[][2] = {
972 {0x12, 0x02}, /* com7 */
973 {0x36, 0xf8}, /* aref3 */
974 {0x69, 0x02}, /* hv */
975 {0x8c, 0x89}, /* com22 */
976 {0x14, 0x28}, /* com9 */
977 {0x3e, 0x0c}, /* com14 */
978 {0x41, 0x40}, /* com16 */
979 {0x72, 0x00},
980 {0x73, 0x01},
981 {0x74, 0x3a},
982 {0x75, 0x35},
983 {0x76, 0x01},
984 {0xc7, 0x80}, /* com24 */
985 {0x03, 0x1b}, /* vref */
986 {0x17, 0x1d}, /* hstart */
987 {0x18, 0x02}, /* hstop */
988 {0x19, 0x01}, /* vstrt */
989 {0x1a, 0x81}, /* vstop */
990 {0x32, 0xff}, /* href */
991 {0xc0, 0xe2},
992};
993
994static const u8 bridge_start_ov965x_qvga[][2] = {
995 {0x94, 0xaa},
996 {0xf1, 0x60},
997 {0xe5, 0x04},
998 {0xc0, 0x50},
999 {0xc1, 0x3c},
1000 {0x8c, 0x00},
1001 {0x8d, 0x1c},
1002 {0x34, 0x05},
1003
1004 {0xc2, 0x4c},
1005 {0xc3, 0xf9},
1006 {0xda, 0x00},
1007 {0x50, 0x00},
1008 {0x51, 0xa0},
1009 {0x52, 0x78},
1010 {0x53, 0x00},
1011 {0x54, 0x00},
1012 {0x55, 0x00},
1013 {0x57, 0x00},
1014 {0x5c, 0x00},
1015 {0x5a, 0x50},
1016 {0x5b, 0x3c},
1017 {0x35, 0x02},
1018 {0xd9, 0x10},
1019 {0x94, 0x11},
1020};
1021
1022static const u8 bridge_start_ov965x_vga[][2] = {
1023 {0x94, 0xaa},
1024 {0xf1, 0x60},
1025 {0xe5, 0x04},
1026 {0xc0, 0x50},
1027 {0xc1, 0x3c},
1028 {0x8c, 0x00},
1029 {0x8d, 0x1c},
1030 {0x34, 0x05},
1031 {0xc2, 0x0c},
1032 {0xc3, 0xf9},
1033 {0xda, 0x01},
1034 {0x50, 0x00},
1035 {0x51, 0xa0},
1036 {0x52, 0x3c},
1037 {0x53, 0x00},
1038 {0x54, 0x00},
1039 {0x55, 0x00},
1040 {0x57, 0x00},
1041 {0x5c, 0x00},
1042 {0x5a, 0xa0},
1043 {0x5b, 0x78},
1044 {0x35, 0x02},
1045 {0xd9, 0x10},
1046 {0x94, 0x11},
1047};
1048
1049static const u8 bridge_start_ov965x_svga[][2] = {
1050 {0x94, 0xaa},
1051 {0xf1, 0x60},
1052 {0xe5, 0x04},
1053 {0xc0, 0xa0},
1054 {0xc1, 0x80},
1055 {0x8c, 0x00},
1056 {0x8d, 0x1c},
1057 {0x34, 0x05},
1058 {0xc2, 0x4c},
1059 {0xc3, 0xf9},
1060 {0x50, 0x00},
1061 {0x51, 0x40},
1062 {0x52, 0x00},
1063 {0x53, 0x00},
1064 {0x54, 0x00},
1065 {0x55, 0x88},
1066 {0x57, 0x00},
1067 {0x5c, 0x00},
1068 {0x5a, 0xc8},
1069 {0x5b, 0x96},
1070 {0x35, 0x02},
1071 {0xd9, 0x10},
1072 {0xda, 0x00},
1073 {0x94, 0x11},
1074};
1075
1076static const u8 bridge_start_ov965x_xga[][2] = {
1077 {0x94, 0xaa},
1078 {0xf1, 0x60},
1079 {0xe5, 0x04},
1080 {0xc0, 0xa0},
1081 {0xc1, 0x80},
1082 {0x8c, 0x00},
1083 {0x8d, 0x1c},
1084 {0x34, 0x05},
1085 {0xc2, 0x4c},
1086 {0xc3, 0xf9},
1087 {0x50, 0x00},
1088 {0x51, 0x40},
1089 {0x52, 0x00},
1090 {0x53, 0x00},
1091 {0x54, 0x00},
1092 {0x55, 0x88},
1093 {0x57, 0x00},
1094 {0x5c, 0x01},
1095 {0x5a, 0x00},
1096 {0x5b, 0xc0},
1097 {0x35, 0x02},
1098 {0xd9, 0x10},
1099 {0xda, 0x01},
1100 {0x94, 0x11},
1101};
1102
1103static const u8 bridge_start_ov965x_sxga[][2] = {
1104 {0x94, 0xaa},
1105 {0xf1, 0x60},
1106 {0xe5, 0x04},
1107 {0xc0, 0xa0},
1108 {0xc1, 0x80},
1109 {0x8c, 0x00},
1110 {0x8d, 0x1c},
1111 {0x34, 0x05},
1112 {0xc2, 0x0c},
1113 {0xc3, 0xf9},
1114 {0xda, 0x00},
1115 {0x35, 0x02},
1116 {0xd9, 0x10},
1117 {0x94, 0x11},
1118};
1119
1120static const u8 sensor_start_ov965x_2_qvga[][2] = {
1121 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
1122 {0x1e, 0x04}, /* mvfp */
1123 {0x13, 0xe0}, /* com8 */
1124 {0x00, 0x00},
1125 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1126 {0x11, 0x01}, /* clkrc */
1127 {0x6b, 0x5a}, /* dblv */
1128 {0x6a, 0x02}, /* 50 Hz banding filter */
1129 {0xc5, 0x03}, /* 60 Hz banding filter */
1130 {0xa2, 0x96}, /* bd50 */
1131 {0xa3, 0x7d}, /* bd60 */
1132
1133 {0xff, 0x13}, /* read 13, write ff 00 */
1134 {0x13, 0xe7},
1135 {0x3a, 0x80}, /* tslb - yuyv */
1136};
1137
1138static const u8 sensor_start_ov965x_2_vga[][2] = {
1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1140 {0x1e, 0x04}, /* mvfp */
1141 {0x13, 0xe0}, /* com8 */
1142 {0x00, 0x00},
1143 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1144 {0x11, 0x03}, /* clkrc */
1145 {0x6b, 0x5a}, /* dblv */
1146 {0x6a, 0x05}, /* 50 Hz banding filter */
1147 {0xc5, 0x07}, /* 60 Hz banding filter */
1148 {0xa2, 0x4b}, /* bd50 */
1149 {0xa3, 0x3e}, /* bd60 */
1150
1151 {0x2d, 0x00}, /* advfl */
1152};
1153
1154static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1156 {0x1e, 0x04}, /* mvfp */
1157 {0x13, 0xe0}, /* com8 */
1158 {0x00, 0x00},
1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1160 {0x11, 0x01}, /* clkrc */
1161 {0x6b, 0x5a}, /* dblv */
1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
1164 {0xa2, 0x4e}, /* bd50 */
1165 {0xa3, 0x41}, /* bd60 */
1166};
1167
1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
1169 {0x13, 0xe0}, /* com8 */
1170 {0x00, 0x00},
1171 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1172 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1173 {0x1e, 0x04}, /* mvfp */
1174 {0x11, 0x01}, /* clkrc */
1175 {0x6b, 0x5a}, /* dblv */
1176 {0x6a, 0x0c}, /* 50 Hz banding filter */
1177 {0xc5, 0x0f}, /* 60 Hz banding filter */
1178 {0xa2, 0x4e}, /* bd50 */
1179 {0xa3, 0x41}, /* bd60 */
1180};
1181
1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 493static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
1183{ 494{
1184 struct usb_device *udev = gspca_dev->dev; 495 struct usb_device *udev = gspca_dev->dev;
@@ -1360,14 +671,14 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps); 671 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1361} 672}
1362 673
1363static void setbrightness_77(struct gspca_dev *gspca_dev) 674static void setbrightness(struct gspca_dev *gspca_dev)
1364{ 675{
1365 struct sd *sd = (struct sd *) gspca_dev; 676 struct sd *sd = (struct sd *) gspca_dev;
1366 677
1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness); 678 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1368} 679}
1369 680
1370static void setcontrast_77(struct gspca_dev *gspca_dev) 681static void setcontrast(struct gspca_dev *gspca_dev)
1371{ 682{
1372 struct sd *sd = (struct sd *) gspca_dev; 683 struct sd *sd = (struct sd *) gspca_dev;
1373 684
@@ -1401,7 +712,7 @@ static void setgain(struct gspca_dev *gspca_dev)
1401 sccb_reg_write(gspca_dev, 0x00, val); 712 sccb_reg_write(gspca_dev, 0x00, val);
1402} 713}
1403 714
1404static void setexposure_77(struct gspca_dev *gspca_dev) 715static void setexposure(struct gspca_dev *gspca_dev)
1405{ 716{
1406 struct sd *sd = (struct sd *) gspca_dev; 717 struct sd *sd = (struct sd *) gspca_dev;
1407 u8 val; 718 u8 val;
@@ -1432,7 +743,7 @@ static void sethue(struct gspca_dev *gspca_dev)
1432 sccb_reg_write(gspca_dev, 0x01, sd->hue); 743 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1433} 744}
1434 745
1435static void setautogain_77(struct gspca_dev *gspca_dev) 746static void setautogain(struct gspca_dev *gspca_dev)
1436{ 747{
1437 struct sd *sd = (struct sd *) gspca_dev; 748 struct sd *sd = (struct sd *) gspca_dev;
1438 749
@@ -1457,7 +768,7 @@ static void setawb(struct gspca_dev *gspca_dev)
1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ 768 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1458} 769}
1459 770
1460static void setsharpness_77(struct gspca_dev *gspca_dev) 771static void setsharpness(struct gspca_dev *gspca_dev)
1461{ 772{
1462 struct sd *sd = (struct sd *) gspca_dev; 773 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 val; 774 u8 val;
@@ -1491,132 +802,6 @@ static void setvflip(struct gspca_dev *gspca_dev)
1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f); 802 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1492} 803}
1493 804
1494/* ov965x specific controls */
1495static void setbrightness_96(struct gspca_dev *gspca_dev)
1496{
1497 struct sd *sd = (struct sd *) gspca_dev;
1498 u8 val;
1499
1500 val = sd->brightness;
1501 if (val < 8)
1502 val = 15 - val; /* f .. 8 */
1503 else
1504 val = val - 8; /* 0 .. 7 */
1505 sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
1506 0x0f | (val << 4));
1507}
1508
1509static void setcontrast_96(struct gspca_dev *gspca_dev)
1510{
1511 struct sd *sd = (struct sd *) gspca_dev;
1512
1513 sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1514 sd->contrast << 4);
1515}
1516
1517static void setexposure_96(struct gspca_dev *gspca_dev)
1518{
1519 struct sd *sd = (struct sd *) gspca_dev;
1520 u8 val;
1521 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1522
1523 sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */
1524 expo[sd->exposure]);
1525 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1526 sccb_reg_write(gspca_dev, 0xff, 0x00);
1527 sccb_reg_write(gspca_dev, 0x13, val);
1528 val = sccb_reg_read(gspca_dev, 0xa1); /* aech */
1529 sccb_reg_write(gspca_dev, 0xff, 0x00);
1530 sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
1531}
1532
1533static void setsharpness_96(struct gspca_dev *gspca_dev)
1534{
1535 struct sd *sd = (struct sd *) gspca_dev;
1536 s8 val;
1537
1538 val = sd->sharpness;
1539 if (val < 0) { /* auto */
1540 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1541 sccb_reg_write(gspca_dev, 0xff, 0x00);
1542 sccb_reg_write(gspca_dev, 0x42, val | 0x40);
1543 /* Edge enhancement strength auto adjust */
1544 return;
1545 }
1546 if (val != 0)
1547 val = 1 << (val - 1);
1548 sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
1549 val);
1550 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1551 sccb_reg_write(gspca_dev, 0xff, 0x00);
1552 sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
1553}
1554
1555static void setautogain_96(struct gspca_dev *gspca_dev)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558 u8 val;
1559
1560/*fixme: should adjust agc/awb/aec by different controls */
1561 val = sd->autogain;
1562 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1563 sccb_reg_write(gspca_dev, 0xff, 0x00);
1564 if (sd->autogain)
1565 val |= 0x05; /* agc & aec */
1566 else
1567 val &= 0xfa;
1568 sccb_reg_write(gspca_dev, 0x13, val);
1569}
1570
1571static void setsatur(struct gspca_dev *gspca_dev)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 u8 val1, val2, val3;
1575 static const u8 matrix[5][2] = {
1576 {0x14, 0x38},
1577 {0x1e, 0x54},
1578 {0x28, 0x70},
1579 {0x32, 0x8c},
1580 {0x48, 0x90}
1581 };
1582
1583 val1 = matrix[sd->satur][0];
1584 val2 = matrix[sd->satur][1];
1585 val3 = val1 + val2;
1586 sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1587 sccb_reg_write(gspca_dev, 0x50, val3);
1588 sccb_reg_write(gspca_dev, 0x51, 0x00);
1589 sccb_reg_write(gspca_dev, 0x52, val1);
1590 sccb_reg_write(gspca_dev, 0x53, val2);
1591 sccb_reg_write(gspca_dev, 0x54, val3);
1592 sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1593 val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */
1594 sccb_reg_write(gspca_dev, 0xff, 0x00);
1595 sccb_reg_write(gspca_dev, 0x41, val1);
1596}
1597
1598static void setfreq(struct gspca_dev *gspca_dev)
1599{
1600 struct sd *sd = (struct sd *) gspca_dev;
1601 u8 val;
1602
1603 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1604 sccb_reg_write(gspca_dev, 0xff, 0x00);
1605 if (sd->lightfreq == 0) {
1606 sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
1607 return;
1608 }
1609 sccb_reg_write(gspca_dev, 0x13, val | 0x20);
1610
1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1612 sccb_reg_write(gspca_dev, 0xff, 0x00);
1613 if (sd->lightfreq == 1)
1614 val |= 0x01;
1615 else
1616 val &= 0xfe;
1617 sccb_reg_write(gspca_dev, 0x42, val);
1618}
1619
1620/* this function is called at probe time */ 805/* this function is called at probe time */
1621static int sd_config(struct gspca_dev *gspca_dev, 806static int sd_config(struct gspca_dev *gspca_dev,
1622 const struct usb_device_id *id) 807 const struct usb_device_id *id)
@@ -1624,77 +809,50 @@ static int sd_config(struct gspca_dev *gspca_dev,
1624 struct sd *sd = (struct sd *) gspca_dev; 809 struct sd *sd = (struct sd *) gspca_dev;
1625 struct cam *cam; 810 struct cam *cam;
1626 811
1627 sd->sensor = id->driver_info;
1628
1629 cam = &gspca_dev->cam; 812 cam = &gspca_dev->cam;
1630 813
1631 if (sd->sensor == SENSOR_OV772X) { 814 cam->cam_mode = ov772x_mode;
1632 cam->cam_mode = ov772x_mode; 815 cam->nmodes = ARRAY_SIZE(ov772x_mode);
1633 cam->nmodes = ARRAY_SIZE(ov772x_mode); 816 cam->mode_framerates = ov772x_framerates;
1634 817
1635 cam->bulk = 1; 818 cam->bulk = 1;
1636 cam->bulk_size = 16384; 819 cam->bulk_size = 16384;
1637 cam->bulk_nurbs = 2; 820 cam->bulk_nurbs = 2;
1638 } else { /* ov965x */
1639 cam->cam_mode = ov965x_mode;
1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1641 }
1642 821
1643 sd->frame_rate = 30; 822 sd->frame_rate = 30;
1644 823
1645 if (sd->sensor == SENSOR_OV772X) { 824 sd->brightness = BRIGHTNESS_DEF;
1646 sd->brightness = BRIGHTNESS_77_DEF; 825 sd->contrast = CONTRAST_DEF;
1647 sd->contrast = CONTRAST_77_DEF; 826 sd->gain = GAIN_DEF;
1648 sd->gain = GAIN_DEF; 827 sd->exposure = EXPO_DEF;
1649 sd->exposure = EXPO_77_DEF; 828 sd->redblc = RED_BALANCE_DEF;
1650 sd->redblc = RED_BALANCE_DEF; 829 sd->blueblc = BLUE_BALANCE_DEF;
1651 sd->blueblc = BLUE_BALANCE_DEF; 830 sd->hue = HUE_DEF;
1652 sd->hue = HUE_DEF; 831#if AUTOGAIN_DEF != 0
1653#if AUTOGAIN_77_DEF != 0 832 sd->autogain = AUTOGAIN_DEF;
1654 sd->autogain = AUTOGAIN_77_DEF;
1655#else 833#else
1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); 834 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
1657#endif 835#endif
1658#if AWB_DEF != 0 836#if AWB_DEF != 0
1659 sd->awb = AWB_DEF 837 sd->awb = AWB_DEF
1660#endif 838#endif
1661#if SHARPNESS_77_DEF != 0 839#if SHARPNESS_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF; 840 sd->sharpness = SHARPNESS_DEF;
1663#endif 841#endif
1664#if HFLIP_DEF != 0 842#if HFLIP_DEF != 0
1665 sd->hflip = HFLIP_DEF; 843 sd->hflip = HFLIP_DEF;
1666#endif 844#endif
1667#if VFLIP_DEF != 0 845#if VFLIP_DEF != 0
1668 sd->vflip = VFLIP_DEF; 846 sd->vflip = VFLIP_DEF;
1669#endif
1670 } else {
1671 sd->brightness = BRIGHTNESS_96_DEF;
1672 sd->contrast = CONTRAST_96_DEF;
1673#if AUTOGAIN_96_DEF != 0
1674 sd->autogain = AUTOGAIN_96_DEF;
1675 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
1676#endif 847#endif
1677#if EXPO_96_DEF != 0 848
1678 sd->exposure = EXPO_96_DEF;
1679#endif
1680#if SHARPNESS_96_DEF != 0
1681 sd->sharpness = SHARPNESS_96_DEF;
1682#endif
1683 sd->satur = SATUR_DEF;
1684 sd->lightfreq = FREQ_DEF;
1685 }
1686 return 0; 849 return 0;
1687} 850}
1688 851
1689/* this function is called at probe and resume time */ 852/* this function is called at probe and resume time */
1690static int sd_init(struct gspca_dev *gspca_dev) 853static int sd_init(struct gspca_dev *gspca_dev)
1691{ 854{
1692 struct sd *sd = (struct sd *) gspca_dev;
1693 u16 sensor_id; 855 u16 sensor_id;
1694 static const u8 sensor_addr[2] = {
1695 0x42, /* 0 SENSOR_OV772X */
1696 0x60, /* 1 SENSOR_OV965X */
1697 };
1698 856
1699 /* reset bridge */ 857 /* reset bridge */
1700 ov534_reg_write(gspca_dev, 0xe7, 0x3a); 858 ov534_reg_write(gspca_dev, 0xe7, 0x3a);
@@ -1702,8 +860,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1702 msleep(100); 860 msleep(100);
1703 861
1704 /* initialize the sensor address */ 862 /* initialize the sensor address */
1705 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 863 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42);
1706 sensor_addr[sd->sensor]);
1707 864
1708 /* reset sensor */ 865 /* reset sensor */
1709 sccb_reg_write(gspca_dev, 0x12, 0x80); 866 sccb_reg_write(gspca_dev, 0x12, 0x80);
@@ -1717,64 +874,46 @@ static int sd_init(struct gspca_dev *gspca_dev)
1717 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); 874 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1718 875
1719 /* initialize */ 876 /* initialize */
1720 switch (sd->sensor) { 877 reg_w_array(gspca_dev, bridge_init,
1721 case SENSOR_OV772X: 878 ARRAY_SIZE(bridge_init));
1722 reg_w_array(gspca_dev, bridge_init_ov772x, 879 ov534_set_led(gspca_dev, 1);
1723 ARRAY_SIZE(bridge_init_ov772x)); 880 sccb_w_array(gspca_dev, sensor_init,
1724 ov534_set_led(gspca_dev, 1); 881 ARRAY_SIZE(sensor_init));
1725 sccb_w_array(gspca_dev, sensor_init_ov772x, 882 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1726 ARRAY_SIZE(sensor_init_ov772x)); 883 ov534_set_led(gspca_dev, 0);
1727 ov534_reg_write(gspca_dev, 0xe0, 0x09); 884 set_frame_rate(gspca_dev);
1728 ov534_set_led(gspca_dev, 0);
1729 set_frame_rate(gspca_dev);
1730 break;
1731 default:
1732/* case SENSOR_OV965X: */
1733 reg_w_array(gspca_dev, bridge_init_ov965x,
1734 ARRAY_SIZE(bridge_init_ov965x));
1735 sccb_w_array(gspca_dev, sensor_init_ov965x,
1736 ARRAY_SIZE(sensor_init_ov965x));
1737 reg_w_array(gspca_dev, bridge_init_ov965x_2,
1738 ARRAY_SIZE(bridge_init_ov965x_2));
1739 sccb_w_array(gspca_dev, sensor_init_ov965x_2,
1740 ARRAY_SIZE(sensor_init_ov965x_2));
1741 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1742 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1743 ov534_set_led(gspca_dev, 0);
1744 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1745 }
1746 885
1747 return 0; 886 return 0;
1748} 887}
1749 888
1750static int sd_start_ov772x(struct gspca_dev *gspca_dev) 889static int sd_start(struct gspca_dev *gspca_dev)
1751{ 890{
1752 int mode; 891 int mode;
1753 892
1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 893 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1755 if (mode != 0) { /* 320x240 */ 894 if (mode != 0) { /* 320x240 */
1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga, 895 reg_w_array(gspca_dev, bridge_start_qvga,
1757 ARRAY_SIZE(bridge_start_ov772x_qvga)); 896 ARRAY_SIZE(bridge_start_qvga));
1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga, 897 sccb_w_array(gspca_dev, sensor_start_qvga,
1759 ARRAY_SIZE(sensor_start_ov772x_qvga)); 898 ARRAY_SIZE(sensor_start_qvga));
1760 } else { /* 640x480 */ 899 } else { /* 640x480 */
1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga, 900 reg_w_array(gspca_dev, bridge_start_vga,
1762 ARRAY_SIZE(bridge_start_ov772x_vga)); 901 ARRAY_SIZE(bridge_start_vga));
1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga, 902 sccb_w_array(gspca_dev, sensor_start_vga,
1764 ARRAY_SIZE(sensor_start_ov772x_vga)); 903 ARRAY_SIZE(sensor_start_vga));
1765 } 904 }
1766 set_frame_rate(gspca_dev); 905 set_frame_rate(gspca_dev);
1767 906
1768 setautogain_77(gspca_dev); 907 setautogain(gspca_dev);
1769 setawb(gspca_dev); 908 setawb(gspca_dev);
1770 setgain(gspca_dev); 909 setgain(gspca_dev);
1771 setredblc(gspca_dev); 910 setredblc(gspca_dev);
1772 setblueblc(gspca_dev); 911 setblueblc(gspca_dev);
1773 sethue(gspca_dev); 912 sethue(gspca_dev);
1774 setexposure_77(gspca_dev); 913 setexposure(gspca_dev);
1775 setbrightness_77(gspca_dev); 914 setbrightness(gspca_dev);
1776 setcontrast_77(gspca_dev); 915 setcontrast(gspca_dev);
1777 setsharpness_77(gspca_dev); 916 setsharpness(gspca_dev);
1778 setvflip(gspca_dev); 917 setvflip(gspca_dev);
1779 sethflip(gspca_dev); 918 sethflip(gspca_dev);
1780 919
@@ -1783,81 +922,12 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev)
1783 return 0; 922 return 0;
1784} 923}
1785 924
1786static int sd_start_ov965x(struct gspca_dev *gspca_dev) 925static void sd_stopN(struct gspca_dev *gspca_dev)
1787{
1788 int mode;
1789
1790 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1791 switch (mode) {
1792 default:
1793/* case 4: * 320x240 */
1794 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1795 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1796 reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
1797 ARRAY_SIZE(bridge_start_ov965x_qvga));
1798 sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
1799 ARRAY_SIZE(sensor_start_ov965x_2_qvga));
1800 break;
1801 case 3: /* 640x480 */
1802 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1803 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1804 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
1805 ARRAY_SIZE(bridge_start_ov965x_vga));
1806 sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
1807 ARRAY_SIZE(sensor_start_ov965x_2_vga));
1808 break;
1809 case 2: /* 800x600 */
1810 sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
1811 ARRAY_SIZE(sensor_start_ov965x_1_svga));
1812 reg_w_array(gspca_dev, bridge_start_ov965x_svga,
1813 ARRAY_SIZE(bridge_start_ov965x_svga));
1814 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1815 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1816 break;
1817 case 1: /* 1024x768 */
1818 sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
1819 ARRAY_SIZE(sensor_start_ov965x_1_xga));
1820 reg_w_array(gspca_dev, bridge_start_ov965x_xga,
1821 ARRAY_SIZE(bridge_start_ov965x_xga));
1822 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1823 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1824 break;
1825 case 0: /* 1280x1024 */
1826 sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
1827 ARRAY_SIZE(sensor_start_ov965x_1_sxga));
1828 reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
1829 ARRAY_SIZE(bridge_start_ov965x_sxga));
1830 sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
1831 ARRAY_SIZE(sensor_start_ov965x_2_sxga));
1832 break;
1833 }
1834 setfreq(gspca_dev);
1835 setautogain_96(gspca_dev);
1836 setbrightness_96(gspca_dev);
1837 setcontrast_96(gspca_dev);
1838 setexposure_96(gspca_dev);
1839 setsharpness_96(gspca_dev);
1840 setsatur(gspca_dev);
1841
1842 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1843 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1844 ov534_set_led(gspca_dev, 1);
1845 return 0;
1846}
1847
1848static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
1849{ 926{
1850 ov534_reg_write(gspca_dev, 0xe0, 0x09); 927 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev, 0); 928 ov534_set_led(gspca_dev, 0);
1852} 929}
1853 930
1854static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
1855{
1856 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1857 ov534_set_led(gspca_dev, 0);
1858 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1859}
1860
1861/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 931/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1862#define UVC_STREAM_EOH (1 << 7) 932#define UVC_STREAM_EOH (1 << 7)
1863#define UVC_STREAM_ERR (1 << 6) 933#define UVC_STREAM_ERR (1 << 6)
@@ -1875,11 +945,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1875 __u32 this_pts; 945 __u32 this_pts;
1876 u16 this_fid; 946 u16 this_fid;
1877 int remaining_len = len; 947 int remaining_len = len;
1878 int payload_len;
1879 948
1880 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
1881 do { 949 do {
1882 len = min(remaining_len, payload_len); 950 len = min(remaining_len, 2048);
1883 951
1884 /* Payloads are prefixed with a UVC-style header. We 952 /* Payloads are prefixed with a UVC-style header. We
1885 consider a frame to start when the FID toggles, or the PTS 953 consider a frame to start when the FID toggles, or the PTS
@@ -1918,7 +986,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1918 data + 12, len - 12); 986 data + 12, len - 12);
1919 /* If this packet is marked as EOF, end the frame */ 987 /* If this packet is marked as EOF, end the frame */
1920 } else if (data[1] & UVC_STREAM_EOF) { 988 } else if (data[1] & UVC_STREAM_EOF) {
989 struct gspca_frame *frame;
990
1921 sd->last_pts = 0; 991 sd->last_pts = 0;
992 frame = gspca_get_i_frame(gspca_dev);
993 if (frame == NULL)
994 goto discard;
995 if (frame->data_end - frame->data + (len - 12) !=
996 gspca_dev->width * gspca_dev->height * 2) {
997 PDEBUG(D_PACK, "wrong sized frame");
998 goto discard;
999 }
1922 gspca_frame_add(gspca_dev, LAST_PACKET, 1000 gspca_frame_add(gspca_dev, LAST_PACKET,
1923 data + 12, len - 12); 1001 data + 12, len - 12);
1924 } else { 1002 } else {
@@ -1965,12 +1043,8 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1965 struct sd *sd = (struct sd *) gspca_dev; 1043 struct sd *sd = (struct sd *) gspca_dev;
1966 1044
1967 sd->exposure = val; 1045 sd->exposure = val;
1968 if (gspca_dev->streaming) { 1046 if (gspca_dev->streaming)
1969 if (sd->sensor == SENSOR_OV772X) 1047 setexposure(gspca_dev);
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1974 return 0; 1048 return 0;
1975} 1049}
1976 1050
@@ -1987,12 +1061,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1987 struct sd *sd = (struct sd *) gspca_dev; 1061 struct sd *sd = (struct sd *) gspca_dev;
1988 1062
1989 sd->brightness = val; 1063 sd->brightness = val;
1990 if (gspca_dev->streaming) { 1064 if (gspca_dev->streaming)
1991 if (sd->sensor == SENSOR_OV772X) 1065 setbrightness(gspca_dev);
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1996 return 0; 1066 return 0;
1997} 1067}
1998 1068
@@ -2009,12 +1079,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2009 struct sd *sd = (struct sd *) gspca_dev; 1079 struct sd *sd = (struct sd *) gspca_dev;
2010 1080
2011 sd->contrast = val; 1081 sd->contrast = val;
2012 if (gspca_dev->streaming) { 1082 if (gspca_dev->streaming)
2013 if (sd->sensor == SENSOR_OV772X) 1083 setcontrast(gspca_dev);
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
2018 return 0; 1084 return 0;
2019} 1085}
2020 1086
@@ -2026,41 +1092,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2026 return 0; 1092 return 0;
2027} 1093}
2028 1094
2029static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
2030{
2031 struct sd *sd = (struct sd *) gspca_dev;
2032
2033 sd->satur = val;
2034 if (gspca_dev->streaming)
2035 setsatur(gspca_dev);
2036 return 0;
2037}
2038
2039static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
2040{
2041 struct sd *sd = (struct sd *) gspca_dev;
2042
2043 *val = sd->satur;
2044 return 0;
2045}
2046static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2047{
2048 struct sd *sd = (struct sd *) gspca_dev;
2049
2050 sd->lightfreq = val;
2051 if (gspca_dev->streaming)
2052 setfreq(gspca_dev);
2053 return 0;
2054}
2055
2056static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2057{
2058 struct sd *sd = (struct sd *) gspca_dev;
2059
2060 *val = sd->lightfreq;
2061 return 0;
2062}
2063
2064static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) 1095static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
2065{ 1096{
2066 struct sd *sd = (struct sd *) gspca_dev; 1097 struct sd *sd = (struct sd *) gspca_dev;
@@ -2122,22 +1153,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2122 sd->autogain = val; 1153 sd->autogain = val;
2123 1154
2124 if (gspca_dev->streaming) { 1155 if (gspca_dev->streaming) {
2125 if (sd->sensor == SENSOR_OV772X) { 1156
2126 1157 /* the auto white balance control works only
2127 /* the auto white balance control works only 1158 * when auto gain is set */
2128 * when auto gain is set */ 1159 if (val)
2129 if (val) 1160 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX);
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX); 1161 else
2131 else 1162 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); 1163 setautogain(gspca_dev);
2133 setautogain_77(gspca_dev);
2134 } else {
2135 if (val)
2136 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
2137 else
2138 gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
2139 setautogain_96(gspca_dev);
2140 }
2141 } 1164 }
2142 return 0; 1165 return 0;
2143} 1166}
@@ -2173,12 +1196,8 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2173 struct sd *sd = (struct sd *) gspca_dev; 1196 struct sd *sd = (struct sd *) gspca_dev;
2174 1197
2175 sd->sharpness = val; 1198 sd->sharpness = val;
2176 if (gspca_dev->streaming) { 1199 if (gspca_dev->streaming)
2177 if (sd->sensor == SENSOR_OV772X) 1200 setsharpness(gspca_dev);
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
2182 return 0; 1201 return 0;
2183} 1202}
2184 1203
@@ -2257,7 +1276,7 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2257 1276
2258 /* Set requested framerate */ 1277 /* Set requested framerate */
2259 sd->frame_rate = tpf->denominator / tpf->numerator; 1278 sd->frame_rate = tpf->denominator / tpf->numerator;
2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X) 1279 if (gspca_dev->streaming)
2261 set_frame_rate(gspca_dev); 1280 set_frame_rate(gspca_dev);
2262 1281
2263 /* Return the actual framerate */ 1282 /* Return the actual framerate */
@@ -2267,57 +1286,23 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2267 return 0; 1286 return 0;
2268} 1287}
2269 1288
2270static int sd_querymenu(struct gspca_dev *gspca_dev,
2271 struct v4l2_querymenu *menu)
2272{
2273 switch (menu->id) {
2274 case V4L2_CID_POWER_LINE_FREQUENCY:
2275 switch (menu->index) {
2276 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2277 strcpy((char *) menu->name, "NoFliker");
2278 return 0;
2279 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2280 strcpy((char *) menu->name, "50 Hz");
2281 return 0;
2282 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2283 strcpy((char *) menu->name, "60 Hz");
2284 return 0;
2285 }
2286 break;
2287 }
2288 return -EINVAL;
2289}
2290
2291/* sub-driver description */ 1289/* sub-driver description */
2292static const struct sd_desc sd_desc_ov772x = { 1290static const struct sd_desc sd_desc = {
2293 .name = MODULE_NAME, 1291 .name = MODULE_NAME,
2294 .ctrls = sd_ctrls_ov772x, 1292 .ctrls = sd_ctrls,
2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x), 1293 .nctrls = ARRAY_SIZE(sd_ctrls),
2296 .config = sd_config, 1294 .config = sd_config,
2297 .init = sd_init, 1295 .init = sd_init,
2298 .start = sd_start_ov772x, 1296 .start = sd_start,
2299 .stopN = sd_stopN_ov772x, 1297 .stopN = sd_stopN,
2300 .pkt_scan = sd_pkt_scan, 1298 .pkt_scan = sd_pkt_scan,
2301 .get_streamparm = sd_get_streamparm, 1299 .get_streamparm = sd_get_streamparm,
2302 .set_streamparm = sd_set_streamparm, 1300 .set_streamparm = sd_set_streamparm,
2303}; 1301};
2304 1302
2305static const struct sd_desc sd_desc_ov965x = {
2306 .name = MODULE_NAME,
2307 .ctrls = sd_ctrls_ov965x,
2308 .nctrls = ARRAY_SIZE(sd_ctrls_ov965x),
2309 .config = sd_config,
2310 .init = sd_init,
2311 .start = sd_start_ov965x,
2312 .stopN = sd_stopN_ov965x,
2313 .pkt_scan = sd_pkt_scan,
2314 .querymenu = sd_querymenu,
2315};
2316
2317/* -- module initialisation -- */ 1303/* -- module initialisation -- */
2318static const __devinitdata struct usb_device_id device_table[] = { 1304static const __devinitdata struct usb_device_id device_table[] = {
2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, 1305 {USB_DEVICE(0x1415, 0x2000)},
2320 {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
2321 {} 1306 {}
2322}; 1307};
2323 1308
@@ -2326,11 +1311,7 @@ MODULE_DEVICE_TABLE(usb, device_table);
2326/* -- device connect -- */ 1311/* -- device connect -- */
2327static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 1312static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
2328{ 1313{
2329 return gspca_dev_probe(intf, id, 1314 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE); 1315 THIS_MODULE);
2335} 1316}
2336 1317
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
new file mode 100644
index 000000000000..bbe5a030e3b4
--- /dev/null
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -0,0 +1,1477 @@
1/*
2 * ov534-ov965x gspca driver
3 *
4 * Copyright (C) 2009-2010 Jean-Francois Moine http://moinejf.free.fr
5 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
6 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
7 *
8 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#define MODULE_NAME "ov534_9"
28
29#include "gspca.h"
30
31#define OV534_REG_ADDRESS 0xf1 /* sensor address */
32#define OV534_REG_SUBADDR 0xf2
33#define OV534_REG_WRITE 0xf3
34#define OV534_REG_READ 0xf4
35#define OV534_REG_OPERATION 0xf5
36#define OV534_REG_STATUS 0xf6
37
38#define OV534_OP_WRITE_3 0x37
39#define OV534_OP_WRITE_2 0x33
40#define OV534_OP_READ_2 0xf9
41
42#define CTRL_TIMEOUT 500
43
44MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
45MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
46MODULE_LICENSE("GPL");
47
48/* specific webcam descriptor */
49struct sd {
50 struct gspca_dev gspca_dev; /* !! must be the first item */
51 __u32 last_pts;
52 u8 last_fid;
53
54 u8 brightness;
55 u8 contrast;
56 u8 autogain;
57 u8 exposure;
58 s8 sharpness;
59 u8 satur;
60 u8 freq;
61};
62
63/* V4L2 controls supported by the driver */
64static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
78
79static const struct ctrl sd_ctrls[] = {
80 { /* 0 */
81 {
82 .id = V4L2_CID_BRIGHTNESS,
83 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "Brightness",
85 .minimum = 0,
86 .maximum = 15,
87 .step = 1,
88#define BRIGHTNESS_DEF 7
89 .default_value = BRIGHTNESS_DEF,
90 },
91 .set = sd_setbrightness,
92 .get = sd_getbrightness,
93 },
94 { /* 1 */
95 {
96 .id = V4L2_CID_CONTRAST,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Contrast",
99 .minimum = 0,
100 .maximum = 15,
101 .step = 1,
102#define CONTRAST_DEF 3
103 .default_value = CONTRAST_DEF,
104 },
105 .set = sd_setcontrast,
106 .get = sd_getcontrast,
107 },
108 { /* 2 */
109 {
110 .id = V4L2_CID_AUTOGAIN,
111 .type = V4L2_CTRL_TYPE_BOOLEAN,
112 .name = "Autogain",
113 .minimum = 0,
114 .maximum = 1,
115 .step = 1,
116#define AUTOGAIN_DEF 1
117 .default_value = AUTOGAIN_DEF,
118 },
119 .set = sd_setautogain,
120 .get = sd_getautogain,
121 },
122#define EXPO_IDX 3
123 { /* 3 */
124 {
125 .id = V4L2_CID_EXPOSURE,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Exposure",
128 .minimum = 0,
129 .maximum = 3,
130 .step = 1,
131#define EXPO_DEF 0
132 .default_value = EXPO_DEF,
133 },
134 .set = sd_setexposure,
135 .get = sd_getexposure,
136 },
137 { /* 4 */
138 {
139 .id = V4L2_CID_SHARPNESS,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Sharpness",
142 .minimum = -1, /* -1 = auto */
143 .maximum = 4,
144 .step = 1,
145#define SHARPNESS_DEF -1
146 .default_value = SHARPNESS_DEF,
147 },
148 .set = sd_setsharpness,
149 .get = sd_getsharpness,
150 },
151 { /* 5 */
152 {
153 .id = V4L2_CID_SATURATION,
154 .type = V4L2_CTRL_TYPE_INTEGER,
155 .name = "Saturation",
156 .minimum = 0,
157 .maximum = 4,
158 .step = 1,
159#define SATUR_DEF 2
160 .default_value = SATUR_DEF,
161 },
162 .set = sd_setsatur,
163 .get = sd_getsatur,
164 },
165 {
166 {
167 .id = V4L2_CID_POWER_LINE_FREQUENCY,
168 .type = V4L2_CTRL_TYPE_MENU,
169 .name = "Light frequency filter",
170 .minimum = 0,
171 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
172 .step = 1,
173#define FREQ_DEF 0
174 .default_value = FREQ_DEF,
175 },
176 .set = sd_setfreq,
177 .get = sd_getfreq,
178 },
179};
180
181static const struct v4l2_pix_format ov965x_mode[] = {
182#define QVGA_MODE 0
183 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184 .bytesperline = 320,
185 .sizeimage = 320 * 240 * 3 / 8 + 590,
186 .colorspace = V4L2_COLORSPACE_JPEG},
187#define VGA_MODE 1
188 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
189 .bytesperline = 640,
190 .sizeimage = 640 * 480 * 3 / 8 + 590,
191 .colorspace = V4L2_COLORSPACE_JPEG},
192#define SVGA_MODE 2
193 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
194 .bytesperline = 800,
195 .sizeimage = 800 * 600 * 3 / 8 + 590,
196 .colorspace = V4L2_COLORSPACE_JPEG},
197#define XGA_MODE 3
198 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199 .bytesperline = 1024,
200 .sizeimage = 1024 * 768 * 3 / 8 + 590,
201 .colorspace = V4L2_COLORSPACE_JPEG},
202#define SXGA_MODE 4
203 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
204 .bytesperline = 1280,
205 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
206 .colorspace = V4L2_COLORSPACE_JPEG},
207};
208
209static const u8 bridge_init[][2] = {
210 {0x88, 0xf8},
211 {0x89, 0xff},
212 {0x76, 0x03},
213 {0x92, 0x03},
214 {0x95, 0x10},
215 {0xe2, 0x00},
216 {0xe7, 0x3e},
217 {0x8d, 0x1c},
218 {0x8e, 0x00},
219 {0x8f, 0x00},
220 {0x1f, 0x00},
221 {0xc3, 0xf9},
222 {0x89, 0xff},
223 {0x88, 0xf8},
224 {0x76, 0x03},
225 {0x92, 0x01},
226 {0x93, 0x18},
227 {0x1c, 0x0a},
228 {0x1d, 0x48},
229 {0xc0, 0x50},
230 {0xc1, 0x3c},
231 {0x34, 0x05},
232 {0xc2, 0x0c},
233 {0xc3, 0xf9},
234 {0x34, 0x05},
235 {0xe7, 0x2e},
236 {0x31, 0xf9},
237 {0x35, 0x02},
238 {0xd9, 0x10},
239 {0x25, 0x42},
240 {0x94, 0x11},
241};
242
243static const u8 sensor_init[][2] = {
244 {0x12, 0x80}, /* com7 - SSCB reset */
245 {0x00, 0x00}, /* gain */
246 {0x01, 0x80}, /* blue */
247 {0x02, 0x80}, /* red */
248 {0x03, 0x1b}, /* vref */
249 {0x04, 0x03}, /* com1 - exposure low bits */
250 {0x0b, 0x57}, /* ver */
251 {0x0e, 0x61}, /* com5 */
252 {0x0f, 0x42}, /* com6 */
253 {0x11, 0x00}, /* clkrc */
254 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
255 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
256 {0x14, 0x28}, /* com9 */
257 {0x16, 0x24}, /* reg16 */
258 {0x17, 0x1d}, /* hstart*/
259 {0x18, 0xbd}, /* hstop */
260 {0x19, 0x01}, /* vstrt */
261 {0x1a, 0x81}, /* vstop*/
262 {0x1e, 0x04}, /* mvfp */
263 {0x24, 0x3c}, /* aew */
264 {0x25, 0x36}, /* aeb */
265 {0x26, 0x71}, /* vpt */
266 {0x27, 0x08}, /* bbias */
267 {0x28, 0x08}, /* gbbias */
268 {0x29, 0x15}, /* gr com */
269 {0x2a, 0x00}, /* exhch */
270 {0x2b, 0x00}, /* exhcl */
271 {0x2c, 0x08}, /* rbias */
272 {0x32, 0xff}, /* href */
273 {0x33, 0x00}, /* chlf */
274 {0x34, 0x3f}, /* aref1 */
275 {0x35, 0x00}, /* aref2 */
276 {0x36, 0xf8}, /* aref3 */
277 {0x38, 0x72}, /* adc2 */
278 {0x39, 0x57}, /* aref4 */
279 {0x3a, 0x80}, /* tslb - yuyv */
280 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
281 {0x3d, 0x99}, /* com13 */
282 {0x3f, 0xc1}, /* edge */
283 {0x40, 0xc0}, /* com15 */
284 {0x41, 0x40}, /* com16 */
285 {0x42, 0xc0}, /* com17 */
286 {0x43, 0x0a}, /* rsvd */
287 {0x44, 0xf0},
288 {0x45, 0x46},
289 {0x46, 0x62},
290 {0x47, 0x2a},
291 {0x48, 0x3c},
292 {0x4a, 0xfc},
293 {0x4b, 0xfc},
294 {0x4c, 0x7f},
295 {0x4d, 0x7f},
296 {0x4e, 0x7f},
297 {0x4f, 0x98}, /* matrix */
298 {0x50, 0x98},
299 {0x51, 0x00},
300 {0x52, 0x28},
301 {0x53, 0x70},
302 {0x54, 0x98},
303 {0x58, 0x1a}, /* matrix coef sign */
304 {0x59, 0x85}, /* AWB control */
305 {0x5a, 0xa9},
306 {0x5b, 0x64},
307 {0x5c, 0x84},
308 {0x5d, 0x53},
309 {0x5e, 0x0e},
310 {0x5f, 0xf0}, /* AWB blue limit */
311 {0x60, 0xf0}, /* AWB red limit */
312 {0x61, 0xf0}, /* AWB green limit */
313 {0x62, 0x00}, /* lcc1 */
314 {0x63, 0x00}, /* lcc2 */
315 {0x64, 0x02}, /* lcc3 */
316 {0x65, 0x16}, /* lcc4 */
317 {0x66, 0x01}, /* lcc5 */
318 {0x69, 0x02}, /* hv */
319 {0x6b, 0x5a}, /* dbvl */
320 {0x6c, 0x04},
321 {0x6d, 0x55},
322 {0x6e, 0x00},
323 {0x6f, 0x9d},
324 {0x70, 0x21}, /* dnsth */
325 {0x71, 0x78},
326 {0x72, 0x00}, /* poidx */
327 {0x73, 0x01}, /* pckdv */
328 {0x74, 0x3a}, /* xindx */
329 {0x75, 0x35}, /* yindx */
330 {0x76, 0x01},
331 {0x77, 0x02},
332 {0x7a, 0x12}, /* gamma curve */
333 {0x7b, 0x08},
334 {0x7c, 0x16},
335 {0x7d, 0x30},
336 {0x7e, 0x5e},
337 {0x7f, 0x72},
338 {0x80, 0x82},
339 {0x81, 0x8e},
340 {0x82, 0x9a},
341 {0x83, 0xa4},
342 {0x84, 0xac},
343 {0x85, 0xb8},
344 {0x86, 0xc3},
345 {0x87, 0xd6},
346 {0x88, 0xe6},
347 {0x89, 0xf2},
348 {0x8a, 0x03},
349 {0x8c, 0x89}, /* com19 */
350 {0x14, 0x28}, /* com9 */
351 {0x90, 0x7d},
352 {0x91, 0x7b},
353 {0x9d, 0x03}, /* lcc6 */
354 {0x9e, 0x04}, /* lcc7 */
355 {0x9f, 0x7a},
356 {0xa0, 0x79},
357 {0xa1, 0x40}, /* aechm */
358 {0xa4, 0x50}, /* com21 */
359 {0xa5, 0x68}, /* com26 */
360 {0xa6, 0x4a}, /* AWB green */
361 {0xa8, 0xc1}, /* refa8 */
362 {0xa9, 0xef}, /* refa9 */
363 {0xaa, 0x92},
364 {0xab, 0x04},
365 {0xac, 0x80}, /* black level control */
366 {0xad, 0x80},
367 {0xae, 0x80},
368 {0xaf, 0x80},
369 {0xb2, 0xf2},
370 {0xb3, 0x20},
371 {0xb4, 0x20}, /* ctrlb4 */
372 {0xb5, 0x00},
373 {0xb6, 0xaf},
374 {0xbb, 0xae},
375 {0xbc, 0x7f}, /* ADC channel offsets */
376 {0xdb, 0x7f},
377 {0xbe, 0x7f},
378 {0xbf, 0x7f},
379 {0xc0, 0xe2},
380 {0xc1, 0xc0},
381 {0xc2, 0x01},
382 {0xc3, 0x4e},
383 {0xc6, 0x85},
384 {0xc7, 0x80}, /* com24 */
385 {0xc9, 0xe0},
386 {0xca, 0xe8},
387 {0xcb, 0xf0},
388 {0xcc, 0xd8},
389 {0xcd, 0xf1},
390 {0x4f, 0x98}, /* matrix */
391 {0x50, 0x98},
392 {0x51, 0x00},
393 {0x52, 0x28},
394 {0x53, 0x70},
395 {0x54, 0x98},
396 {0x58, 0x1a},
397 {0xff, 0x41}, /* read 41, write ff 00 */
398 {0x41, 0x40}, /* com16 */
399
400 {0xc5, 0x03}, /* 60 Hz banding filter */
401 {0x6a, 0x02}, /* 50 Hz banding filter */
402
403 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
404 {0x36, 0xfa}, /* aref3 */
405 {0x69, 0x0a}, /* hv */
406 {0x8c, 0x89}, /* com22 */
407 {0x14, 0x28}, /* com9 */
408 {0x3e, 0x0c},
409 {0x41, 0x40}, /* com16 */
410 {0x72, 0x00},
411 {0x73, 0x00},
412 {0x74, 0x3a},
413 {0x75, 0x35},
414 {0x76, 0x01},
415 {0xc7, 0x80},
416 {0x03, 0x12}, /* vref */
417 {0x17, 0x16}, /* hstart */
418 {0x18, 0x02}, /* hstop */
419 {0x19, 0x01}, /* vstrt */
420 {0x1a, 0x3d}, /* vstop */
421 {0x32, 0xff}, /* href */
422 {0xc0, 0xaa},
423};
424
425static const u8 bridge_init_2[][2] = {
426 {0x94, 0xaa},
427 {0xf1, 0x60},
428 {0xe5, 0x04},
429 {0xc0, 0x50},
430 {0xc1, 0x3c},
431 {0x8c, 0x00},
432 {0x8d, 0x1c},
433 {0x34, 0x05},
434
435 {0xc2, 0x0c},
436 {0xc3, 0xf9},
437 {0xda, 0x01},
438 {0x50, 0x00},
439 {0x51, 0xa0},
440 {0x52, 0x3c},
441 {0x53, 0x00},
442 {0x54, 0x00},
443 {0x55, 0x00},
444 {0x57, 0x00},
445 {0x5c, 0x00},
446 {0x5a, 0xa0},
447 {0x5b, 0x78},
448 {0x35, 0x02},
449 {0xd9, 0x10},
450 {0x94, 0x11},
451};
452
453static const u8 sensor_init_2[][2] = {
454 {0x3b, 0xc4},
455 {0x1e, 0x04}, /* mvfp */
456 {0x13, 0xe0}, /* com8 */
457 {0x00, 0x00}, /* gain */
458 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
459 {0x11, 0x03}, /* clkrc */
460 {0x6b, 0x5a}, /* dblv */
461 {0x6a, 0x05},
462 {0xc5, 0x07},
463 {0xa2, 0x4b},
464 {0xa3, 0x3e},
465 {0x2d, 0x00},
466 {0xff, 0x42}, /* read 42, write ff 00 */
467 {0x42, 0xc0}, /* com17 */
468 {0x2d, 0x00},
469 {0xff, 0x42}, /* read 42, write ff 00 */
470 {0x42, 0xc1}, /* com17 */
471/* sharpness */
472 {0x3f, 0x01},
473 {0xff, 0x42}, /* read 42, write ff 00 */
474 {0x42, 0xc1}, /* com17 */
475/* saturation */
476 {0x4f, 0x98}, /* matrix */
477 {0x50, 0x98},
478 {0x51, 0x00},
479 {0x52, 0x28},
480 {0x53, 0x70},
481 {0x54, 0x98},
482 {0x58, 0x1a},
483 {0xff, 0x41}, /* read 41, write ff 00 */
484 {0x41, 0x40}, /* com16 */
485/* contrast */
486 {0x56, 0x40},
487/* brightness */
488 {0x55, 0x8f},
489/* expo */
490 {0x10, 0x25}, /* aech - exposure high bits */
491 {0xff, 0x13}, /* read 13, write ff 00 */
492 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
493};
494
495static const u8 sensor_start_1_vga[][2] = { /* same for qvga */
496 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
497 {0x36, 0xfa}, /* aref3 */
498 {0x69, 0x0a}, /* hv */
499 {0x8c, 0x89}, /* com22 */
500 {0x14, 0x28}, /* com9 */
501 {0x3e, 0x0c}, /* com14 */
502 {0x41, 0x40}, /* com16 */
503 {0x72, 0x00},
504 {0x73, 0x00},
505 {0x74, 0x3a},
506 {0x75, 0x35},
507 {0x76, 0x01},
508 {0xc7, 0x80}, /* com24 */
509 {0x03, 0x12}, /* vref */
510 {0x17, 0x16}, /* hstart */
511 {0x18, 0x02}, /* hstop */
512 {0x19, 0x01}, /* vstrt */
513 {0x1a, 0x3d}, /* vstop */
514 {0x32, 0xff}, /* href */
515 {0xc0, 0xaa},
516};
517
518static const u8 sensor_start_1_svga[][2] = {
519 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
520 {0x36, 0xf8}, /* aref3 */
521 {0x69, 0x02}, /* hv */
522 {0x8c, 0x0d}, /* com22 */
523 {0x3e, 0x0c}, /* com14 */
524 {0x41, 0x40}, /* com16 */
525 {0x72, 0x00},
526 {0x73, 0x01},
527 {0x74, 0x3a},
528 {0x75, 0x35},
529 {0x76, 0x01},
530 {0xc7, 0x80}, /* com24 */
531 {0x03, 0x1b}, /* vref */
532 {0x17, 0x1d}, /* hstart */
533 {0x18, 0xbd}, /* hstop */
534 {0x19, 0x01}, /* vstrt */
535 {0x1a, 0x81}, /* vstop */
536 {0x32, 0xff}, /* href */
537 {0xc0, 0xe2},
538};
539
540static const u8 sensor_start_1_xga[][2] = {
541 {0x12, 0x02}, /* com7 */
542 {0x36, 0xf8}, /* aref3 */
543 {0x69, 0x02}, /* hv */
544 {0x8c, 0x89}, /* com22 */
545 {0x14, 0x28}, /* com9 */
546 {0x3e, 0x0c}, /* com14 */
547 {0x41, 0x40}, /* com16 */
548 {0x72, 0x00},
549 {0x73, 0x01},
550 {0x74, 0x3a},
551 {0x75, 0x35},
552 {0x76, 0x01},
553 {0xc7, 0x80}, /* com24 */
554 {0x03, 0x1b}, /* vref */
555 {0x17, 0x1d}, /* hstart */
556 {0x18, 0xbd}, /* hstop */
557 {0x19, 0x01}, /* vstrt */
558 {0x1a, 0x81}, /* vstop */
559 {0x32, 0xff}, /* href */
560 {0xc0, 0xe2},
561};
562
563static const u8 sensor_start_1_sxga[][2] = {
564 {0x12, 0x02}, /* com7 */
565 {0x36, 0xf8}, /* aref3 */
566 {0x69, 0x02}, /* hv */
567 {0x8c, 0x89}, /* com22 */
568 {0x14, 0x28}, /* com9 */
569 {0x3e, 0x0c}, /* com14 */
570 {0x41, 0x40}, /* com16 */
571 {0x72, 0x00},
572 {0x73, 0x01},
573 {0x74, 0x3a},
574 {0x75, 0x35},
575 {0x76, 0x01},
576 {0xc7, 0x80}, /* com24 */
577 {0x03, 0x1b}, /* vref */
578 {0x17, 0x1d}, /* hstart */
579 {0x18, 0x02}, /* hstop */
580 {0x19, 0x01}, /* vstrt */
581 {0x1a, 0x81}, /* vstop */
582 {0x32, 0xff}, /* href */
583 {0xc0, 0xe2},
584};
585
586static const u8 bridge_start_qvga[][2] = {
587 {0x94, 0xaa},
588 {0xf1, 0x60},
589 {0xe5, 0x04},
590 {0xc0, 0x50},
591 {0xc1, 0x3c},
592 {0x8c, 0x00},
593 {0x8d, 0x1c},
594 {0x34, 0x05},
595
596 {0xc2, 0x4c},
597 {0xc3, 0xf9},
598 {0xda, 0x00},
599 {0x50, 0x00},
600 {0x51, 0xa0},
601 {0x52, 0x78},
602 {0x53, 0x00},
603 {0x54, 0x00},
604 {0x55, 0x00},
605 {0x57, 0x00},
606 {0x5c, 0x00},
607 {0x5a, 0x50},
608 {0x5b, 0x3c},
609 {0x35, 0x02},
610 {0xd9, 0x10},
611 {0x94, 0x11},
612};
613
614static const u8 bridge_start_vga[][2] = {
615 {0x94, 0xaa},
616 {0xf1, 0x60},
617 {0xe5, 0x04},
618 {0xc0, 0x50},
619 {0xc1, 0x3c},
620 {0x8c, 0x00},
621 {0x8d, 0x1c},
622 {0x34, 0x05},
623 {0xc2, 0x0c},
624 {0xc3, 0xf9},
625 {0xda, 0x01},
626 {0x50, 0x00},
627 {0x51, 0xa0},
628 {0x52, 0x3c},
629 {0x53, 0x00},
630 {0x54, 0x00},
631 {0x55, 0x00},
632 {0x57, 0x00},
633 {0x5c, 0x00},
634 {0x5a, 0xa0},
635 {0x5b, 0x78},
636 {0x35, 0x02},
637 {0xd9, 0x10},
638 {0x94, 0x11},
639};
640
641static const u8 bridge_start_svga[][2] = {
642 {0x94, 0xaa},
643 {0xf1, 0x60},
644 {0xe5, 0x04},
645 {0xc0, 0xa0},
646 {0xc1, 0x80},
647 {0x8c, 0x00},
648 {0x8d, 0x1c},
649 {0x34, 0x05},
650 {0xc2, 0x4c},
651 {0xc3, 0xf9},
652 {0x50, 0x00},
653 {0x51, 0x40},
654 {0x52, 0x00},
655 {0x53, 0x00},
656 {0x54, 0x00},
657 {0x55, 0x88},
658 {0x57, 0x00},
659 {0x5c, 0x00},
660 {0x5a, 0xc8},
661 {0x5b, 0x96},
662 {0x35, 0x02},
663 {0xd9, 0x10},
664 {0xda, 0x00},
665 {0x94, 0x11},
666};
667
668static const u8 bridge_start_xga[][2] = {
669 {0x94, 0xaa},
670 {0xf1, 0x60},
671 {0xe5, 0x04},
672 {0xc0, 0xa0},
673 {0xc1, 0x80},
674 {0x8c, 0x00},
675 {0x8d, 0x1c},
676 {0x34, 0x05},
677 {0xc2, 0x4c},
678 {0xc3, 0xf9},
679 {0x50, 0x00},
680 {0x51, 0x40},
681 {0x52, 0x00},
682 {0x53, 0x00},
683 {0x54, 0x00},
684 {0x55, 0x88},
685 {0x57, 0x00},
686 {0x5c, 0x01},
687 {0x5a, 0x00},
688 {0x5b, 0xc0},
689 {0x35, 0x02},
690 {0xd9, 0x10},
691 {0xda, 0x01},
692 {0x94, 0x11},
693};
694
695static const u8 bridge_start_sxga[][2] = {
696 {0x94, 0xaa},
697 {0xf1, 0x60},
698 {0xe5, 0x04},
699 {0xc0, 0xa0},
700 {0xc1, 0x80},
701 {0x8c, 0x00},
702 {0x8d, 0x1c},
703 {0x34, 0x05},
704 {0xc2, 0x0c},
705 {0xc3, 0xf9},
706 {0xda, 0x00},
707 {0x35, 0x02},
708 {0xd9, 0x10},
709 {0x94, 0x11},
710};
711
712static const u8 sensor_start_2_qvga[][2] = {
713 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
714 {0x1e, 0x04}, /* mvfp */
715 {0x13, 0xe0}, /* com8 */
716 {0x00, 0x00},
717 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
718 {0x11, 0x01}, /* clkrc */
719 {0x6b, 0x5a}, /* dblv */
720 {0x6a, 0x02}, /* 50 Hz banding filter */
721 {0xc5, 0x03}, /* 60 Hz banding filter */
722 {0xa2, 0x96}, /* bd50 */
723 {0xa3, 0x7d}, /* bd60 */
724
725 {0xff, 0x13}, /* read 13, write ff 00 */
726 {0x13, 0xe7},
727 {0x3a, 0x80}, /* tslb - yuyv */
728};
729
730static const u8 sensor_start_2_vga[][2] = {
731 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
732 {0x1e, 0x04}, /* mvfp */
733 {0x13, 0xe0}, /* com8 */
734 {0x00, 0x00},
735 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
736 {0x11, 0x03}, /* clkrc */
737 {0x6b, 0x5a}, /* dblv */
738 {0x6a, 0x05}, /* 50 Hz banding filter */
739 {0xc5, 0x07}, /* 60 Hz banding filter */
740 {0xa2, 0x4b}, /* bd50 */
741 {0xa3, 0x3e}, /* bd60 */
742
743 {0x2d, 0x00}, /* advfl */
744};
745
746static const u8 sensor_start_2_svga[][2] = { /* same for xga */
747 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
748 {0x1e, 0x04}, /* mvfp */
749 {0x13, 0xe0}, /* com8 */
750 {0x00, 0x00},
751 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
752 {0x11, 0x01}, /* clkrc */
753 {0x6b, 0x5a}, /* dblv */
754 {0x6a, 0x0c}, /* 50 Hz banding filter */
755 {0xc5, 0x0f}, /* 60 Hz banding filter */
756 {0xa2, 0x4e}, /* bd50 */
757 {0xa3, 0x41}, /* bd60 */
758};
759
760static const u8 sensor_start_2_sxga[][2] = {
761 {0x13, 0xe0}, /* com8 */
762 {0x00, 0x00},
763 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
764 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
765 {0x1e, 0x04}, /* mvfp */
766 {0x11, 0x01}, /* clkrc */
767 {0x6b, 0x5a}, /* dblv */
768 {0x6a, 0x0c}, /* 50 Hz banding filter */
769 {0xc5, 0x0f}, /* 60 Hz banding filter */
770 {0xa2, 0x4e}, /* bd50 */
771 {0xa3, 0x41}, /* bd60 */
772};
773
774static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
775{
776 struct usb_device *udev = gspca_dev->dev;
777 int ret;
778
779 if (gspca_dev->usb_err < 0)
780 return;
781 gspca_dev->usb_buf[0] = val;
782 ret = usb_control_msg(udev,
783 usb_sndctrlpipe(udev, 0),
784 0x01,
785 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
786 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
787 if (ret < 0) {
788 PDEBUG(D_ERR, "reg_w failed %d", ret);
789 gspca_dev->usb_err = ret;
790 }
791}
792
793static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
794{
795 PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
796 reg_w_i(gspca_dev, reg, val);
797}
798
799static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
800{
801 struct usb_device *udev = gspca_dev->dev;
802 int ret;
803
804 if (gspca_dev->usb_err < 0)
805 return 0;
806 ret = usb_control_msg(udev,
807 usb_rcvctrlpipe(udev, 0),
808 0x01,
809 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
810 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
811 PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
812 if (ret < 0) {
813 PDEBUG(D_ERR, "reg_r err %d", ret);
814 gspca_dev->usb_err = ret;
815 }
816 return gspca_dev->usb_buf[0];
817}
818
819static int sccb_check_status(struct gspca_dev *gspca_dev)
820{
821 u8 data;
822 int i;
823
824 for (i = 0; i < 5; i++) {
825 data = reg_r(gspca_dev, OV534_REG_STATUS);
826
827 switch (data) {
828 case 0x00:
829 return 1;
830 case 0x04:
831 return 0;
832 case 0x03:
833 break;
834 default:
835 PDEBUG(D_USBI|D_USBO,
836 "sccb status 0x%02x, attempt %d/5",
837 data, i + 1);
838 }
839 }
840 return 0;
841}
842
843static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
844{
845 PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
846 reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
847 reg_w_i(gspca_dev, OV534_REG_WRITE, val);
848 reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
849
850 if (!sccb_check_status(gspca_dev))
851 PDEBUG(D_ERR, "sccb_write failed");
852}
853
854static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
855{
856 reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
857 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
858 if (!sccb_check_status(gspca_dev))
859 PDEBUG(D_ERR, "sccb_read failed 1");
860
861 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
862 if (!sccb_check_status(gspca_dev))
863 PDEBUG(D_ERR, "sccb_read failed 2");
864
865 return reg_r(gspca_dev, OV534_REG_READ);
866}
867
868/* output a bridge sequence (reg - val) */
869static void reg_w_array(struct gspca_dev *gspca_dev,
870 const u8 (*data)[2], int len)
871{
872 while (--len >= 0) {
873 reg_w(gspca_dev, (*data)[0], (*data)[1]);
874 data++;
875 }
876}
877
878/* output a sensor sequence (reg - val) */
879static void sccb_w_array(struct gspca_dev *gspca_dev,
880 const u8 (*data)[2], int len)
881{
882 while (--len >= 0) {
883 if ((*data)[0] != 0xff) {
884 sccb_write(gspca_dev, (*data)[0], (*data)[1]);
885 } else {
886 sccb_read(gspca_dev, (*data)[1]);
887 sccb_write(gspca_dev, 0xff, 0x00);
888 }
889 data++;
890 }
891}
892
893/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
894 * (direction and output)? */
895static void set_led(struct gspca_dev *gspca_dev, int status)
896{
897 u8 data;
898
899 PDEBUG(D_CONF, "led status: %d", status);
900
901 data = reg_r(gspca_dev, 0x21);
902 data |= 0x80;
903 reg_w(gspca_dev, 0x21, data);
904
905 data = reg_r(gspca_dev, 0x23);
906 if (status)
907 data |= 0x80;
908 else
909 data &= ~0x80;
910
911 reg_w(gspca_dev, 0x23, data);
912
913 if (!status) {
914 data = reg_r(gspca_dev, 0x21);
915 data &= ~0x80;
916 reg_w(gspca_dev, 0x21, data);
917 }
918}
919
920static void setbrightness(struct gspca_dev *gspca_dev)
921{
922 struct sd *sd = (struct sd *) gspca_dev;
923 u8 val;
924
925 val = sd->brightness;
926 if (val < 8)
927 val = 15 - val; /* f .. 8 */
928 else
929 val = val - 8; /* 0 .. 7 */
930 sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
931 0x0f | (val << 4));
932}
933
934static void setcontrast(struct gspca_dev *gspca_dev)
935{
936 struct sd *sd = (struct sd *) gspca_dev;
937
938 sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
939 sd->contrast << 4);
940}
941
942static void setautogain(struct gspca_dev *gspca_dev)
943{
944 struct sd *sd = (struct sd *) gspca_dev;
945 u8 val;
946
947/*fixme: should adjust agc/awb/aec by different controls */
948 val = sd->autogain;
949 val = sccb_read(gspca_dev, 0x13); /* com8 */
950 sccb_write(gspca_dev, 0xff, 0x00);
951 if (sd->autogain)
952 val |= 0x05; /* agc & aec */
953 else
954 val &= 0xfa;
955 sccb_write(gspca_dev, 0x13, val);
956}
957
958static void setexposure(struct gspca_dev *gspca_dev)
959{
960 struct sd *sd = (struct sd *) gspca_dev;
961 u8 val;
962 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
963
964 sccb_write(gspca_dev, 0x10, /* aec[9:2] */
965 expo[sd->exposure]);
966
967 val = sccb_read(gspca_dev, 0x13); /* com8 */
968 sccb_write(gspca_dev, 0xff, 0x00);
969 sccb_write(gspca_dev, 0x13, val);
970
971 val = sccb_read(gspca_dev, 0xa1); /* aech */
972 sccb_write(gspca_dev, 0xff, 0x00);
973 sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
974}
975
976static void setsharpness(struct gspca_dev *gspca_dev)
977{
978 struct sd *sd = (struct sd *) gspca_dev;
979 s8 val;
980
981 val = sd->sharpness;
982 if (val < 0) { /* auto */
983 val = sccb_read(gspca_dev, 0x42); /* com17 */
984 sccb_write(gspca_dev, 0xff, 0x00);
985 sccb_write(gspca_dev, 0x42, val | 0x40);
986 /* Edge enhancement strength auto adjust */
987 return;
988 }
989 if (val != 0)
990 val = 1 << (val - 1);
991 sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
992 val);
993 val = sccb_read(gspca_dev, 0x42); /* com17 */
994 sccb_write(gspca_dev, 0xff, 0x00);
995 sccb_write(gspca_dev, 0x42, val & 0xbf);
996}
997
998static void setsatur(struct gspca_dev *gspca_dev)
999{
1000 struct sd *sd = (struct sd *) gspca_dev;
1001 u8 val1, val2, val3;
1002 static const u8 matrix[5][2] = {
1003 {0x14, 0x38},
1004 {0x1e, 0x54},
1005 {0x28, 0x70},
1006 {0x32, 0x8c},
1007 {0x48, 0x90}
1008 };
1009
1010 val1 = matrix[sd->satur][0];
1011 val2 = matrix[sd->satur][1];
1012 val3 = val1 + val2;
1013 sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1014 sccb_write(gspca_dev, 0x50, val3);
1015 sccb_write(gspca_dev, 0x51, 0x00);
1016 sccb_write(gspca_dev, 0x52, val1);
1017 sccb_write(gspca_dev, 0x53, val2);
1018 sccb_write(gspca_dev, 0x54, val3);
1019 sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1020
1021 val1 = sccb_read(gspca_dev, 0x41); /* com16 */
1022 sccb_write(gspca_dev, 0xff, 0x00);
1023 sccb_write(gspca_dev, 0x41, val1);
1024}
1025
1026static void setfreq(struct gspca_dev *gspca_dev)
1027{
1028 struct sd *sd = (struct sd *) gspca_dev;
1029 u8 val;
1030
1031 val = sccb_read(gspca_dev, 0x13); /* com8 */
1032 sccb_write(gspca_dev, 0xff, 0x00);
1033 if (sd->freq == 0) {
1034 sccb_write(gspca_dev, 0x13, val & 0xdf);
1035 return;
1036 }
1037 sccb_write(gspca_dev, 0x13, val | 0x20);
1038
1039 val = sccb_read(gspca_dev, 0x42); /* com17 */
1040 sccb_write(gspca_dev, 0xff, 0x00);
1041 if (sd->freq == 1)
1042 val |= 0x01;
1043 else
1044 val &= 0xfe;
1045 sccb_write(gspca_dev, 0x42, val);
1046}
1047
1048/* this function is called at probe time */
1049static int sd_config(struct gspca_dev *gspca_dev,
1050 const struct usb_device_id *id)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
1053 struct cam *cam;
1054
1055 cam = &gspca_dev->cam;
1056
1057 cam->cam_mode = ov965x_mode;
1058 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1059
1060 sd->brightness = BRIGHTNESS_DEF;
1061 sd->contrast = CONTRAST_DEF;
1062#if AUTOGAIN_DEF != 0
1063 sd->autogain = AUTOGAIN_DEF;
1064 gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1065#endif
1066#if EXPO_DEF != 0
1067 sd->exposure = EXPO_DEF;
1068#endif
1069#if SHARPNESS_DEF != 0
1070 sd->sharpness = SHARPNESS_DEF;
1071#endif
1072 sd->satur = SATUR_DEF;
1073 sd->freq = FREQ_DEF;
1074
1075 return 0;
1076}
1077
1078/* this function is called at probe and resume time */
1079static int sd_init(struct gspca_dev *gspca_dev)
1080{
1081 u16 sensor_id;
1082
1083 /* reset bridge */
1084 reg_w(gspca_dev, 0xe7, 0x3a);
1085 reg_w(gspca_dev, 0xe0, 0x08);
1086 msleep(100);
1087
1088 /* initialize the sensor address */
1089 reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
1090
1091 /* reset sensor */
1092 sccb_write(gspca_dev, 0x12, 0x80);
1093 msleep(10);
1094
1095 /* probe the sensor */
1096 sccb_read(gspca_dev, 0x0a);
1097 sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
1098 sccb_read(gspca_dev, 0x0b);
1099 sensor_id |= sccb_read(gspca_dev, 0x0b);
1100 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1101
1102 /* initialize */
1103 reg_w_array(gspca_dev, bridge_init,
1104 ARRAY_SIZE(bridge_init));
1105 sccb_w_array(gspca_dev, sensor_init,
1106 ARRAY_SIZE(sensor_init));
1107 reg_w_array(gspca_dev, bridge_init_2,
1108 ARRAY_SIZE(bridge_init_2));
1109 sccb_w_array(gspca_dev, sensor_init_2,
1110 ARRAY_SIZE(sensor_init_2));
1111 reg_w(gspca_dev, 0xe0, 0x00);
1112 reg_w(gspca_dev, 0xe0, 0x01);
1113 set_led(gspca_dev, 0);
1114 reg_w(gspca_dev, 0xe0, 0x00);
1115
1116 return gspca_dev->usb_err;
1117}
1118
1119static int sd_start(struct gspca_dev *gspca_dev)
1120{
1121 switch (gspca_dev->curr_mode) {
1122 case QVGA_MODE: /* 320x240 */
1123 sccb_w_array(gspca_dev, sensor_start_1_vga,
1124 ARRAY_SIZE(sensor_start_1_vga));
1125 reg_w_array(gspca_dev, bridge_start_qvga,
1126 ARRAY_SIZE(bridge_start_qvga));
1127 sccb_w_array(gspca_dev, sensor_start_2_qvga,
1128 ARRAY_SIZE(sensor_start_2_qvga));
1129 break;
1130 case VGA_MODE: /* 640x480 */
1131 sccb_w_array(gspca_dev, sensor_start_1_vga,
1132 ARRAY_SIZE(sensor_start_1_vga));
1133 reg_w_array(gspca_dev, bridge_start_vga,
1134 ARRAY_SIZE(bridge_start_vga));
1135 sccb_w_array(gspca_dev, sensor_start_2_vga,
1136 ARRAY_SIZE(sensor_start_2_vga));
1137 break;
1138 case SVGA_MODE: /* 800x600 */
1139 sccb_w_array(gspca_dev, sensor_start_1_svga,
1140 ARRAY_SIZE(sensor_start_1_svga));
1141 reg_w_array(gspca_dev, bridge_start_svga,
1142 ARRAY_SIZE(bridge_start_svga));
1143 sccb_w_array(gspca_dev, sensor_start_2_svga,
1144 ARRAY_SIZE(sensor_start_2_svga));
1145 break;
1146 case XGA_MODE: /* 1024x768 */
1147 sccb_w_array(gspca_dev, sensor_start_1_xga,
1148 ARRAY_SIZE(sensor_start_1_xga));
1149 reg_w_array(gspca_dev, bridge_start_xga,
1150 ARRAY_SIZE(bridge_start_xga));
1151 sccb_w_array(gspca_dev, sensor_start_2_svga,
1152 ARRAY_SIZE(sensor_start_2_svga));
1153 break;
1154 default:
1155/* case SXGA_MODE: * 1280x1024 */
1156 sccb_w_array(gspca_dev, sensor_start_1_sxga,
1157 ARRAY_SIZE(sensor_start_1_sxga));
1158 reg_w_array(gspca_dev, bridge_start_sxga,
1159 ARRAY_SIZE(bridge_start_sxga));
1160 sccb_w_array(gspca_dev, sensor_start_2_sxga,
1161 ARRAY_SIZE(sensor_start_2_sxga));
1162 break;
1163 }
1164 setfreq(gspca_dev);
1165 setautogain(gspca_dev);
1166 setbrightness(gspca_dev);
1167 setcontrast(gspca_dev);
1168 setexposure(gspca_dev);
1169 setsharpness(gspca_dev);
1170 setsatur(gspca_dev);
1171
1172 reg_w(gspca_dev, 0xe0, 0x00);
1173 reg_w(gspca_dev, 0xe0, 0x00);
1174 set_led(gspca_dev, 1);
1175 return gspca_dev->usb_err;
1176}
1177
1178static void sd_stopN(struct gspca_dev *gspca_dev)
1179{
1180 reg_w(gspca_dev, 0xe0, 0x01);
1181 set_led(gspca_dev, 0);
1182 reg_w(gspca_dev, 0xe0, 0x00);
1183}
1184
1185/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1186#define UVC_STREAM_EOH (1 << 7)
1187#define UVC_STREAM_ERR (1 << 6)
1188#define UVC_STREAM_STI (1 << 5)
1189#define UVC_STREAM_RES (1 << 4)
1190#define UVC_STREAM_SCR (1 << 3)
1191#define UVC_STREAM_PTS (1 << 2)
1192#define UVC_STREAM_EOF (1 << 1)
1193#define UVC_STREAM_FID (1 << 0)
1194
1195static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1196 u8 *data, int len)
1197{
1198 struct sd *sd = (struct sd *) gspca_dev;
1199 __u32 this_pts;
1200 u8 this_fid;
1201 int remaining_len = len;
1202
1203 do {
1204 len = min(remaining_len, 2040);
1205
1206 /* Payloads are prefixed with a UVC-style header. We
1207 consider a frame to start when the FID toggles, or the PTS
1208 changes. A frame ends when EOF is set, and we've received
1209 the correct number of bytes. */
1210
1211 /* Verify UVC header. Header length is always 12 */
1212 if (data[0] != 12 || len < 12) {
1213 PDEBUG(D_PACK, "bad header");
1214 goto discard;
1215 }
1216
1217 /* Check errors */
1218 if (data[1] & UVC_STREAM_ERR) {
1219 PDEBUG(D_PACK, "payload error");
1220 goto discard;
1221 }
1222
1223 /* Extract PTS and FID */
1224 if (!(data[1] & UVC_STREAM_PTS)) {
1225 PDEBUG(D_PACK, "PTS not present");
1226 goto discard;
1227 }
1228 this_pts = (data[5] << 24) | (data[4] << 16)
1229 | (data[3] << 8) | data[2];
1230 this_fid = data[1] & UVC_STREAM_FID;
1231
1232 /* If PTS or FID has changed, start a new frame. */
1233 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1234 if (gspca_dev->last_packet_type == INTER_PACKET)
1235 gspca_frame_add(gspca_dev, LAST_PACKET,
1236 NULL, 0);
1237 sd->last_pts = this_pts;
1238 sd->last_fid = this_fid;
1239 gspca_frame_add(gspca_dev, FIRST_PACKET,
1240 data + 12, len - 12);
1241 /* If this packet is marked as EOF, end the frame */
1242 } else if (data[1] & UVC_STREAM_EOF) {
1243 sd->last_pts = 0;
1244 gspca_frame_add(gspca_dev, LAST_PACKET,
1245 data + 12, len - 12);
1246 } else {
1247
1248 /* Add the data from this payload */
1249 gspca_frame_add(gspca_dev, INTER_PACKET,
1250 data + 12, len - 12);
1251 }
1252
1253 /* Done this payload */
1254 goto scan_next;
1255
1256discard:
1257 /* Discard data until a new frame starts. */
1258 gspca_dev->last_packet_type = DISCARD_PACKET;
1259
1260scan_next:
1261 remaining_len -= len;
1262 data += len;
1263 } while (remaining_len > 0);
1264}
1265
1266/* controls */
1267static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1268{
1269 struct sd *sd = (struct sd *) gspca_dev;
1270
1271 sd->brightness = val;
1272 if (gspca_dev->streaming)
1273 setbrightness(gspca_dev);
1274 return gspca_dev->usb_err;
1275}
1276
1277static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1278{
1279 struct sd *sd = (struct sd *) gspca_dev;
1280
1281 *val = sd->brightness;
1282 return 0;
1283}
1284
1285static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1286{
1287 struct sd *sd = (struct sd *) gspca_dev;
1288
1289 sd->contrast = val;
1290 if (gspca_dev->streaming)
1291 setcontrast(gspca_dev);
1292 return gspca_dev->usb_err;
1293}
1294
1295static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1296{
1297 struct sd *sd = (struct sd *) gspca_dev;
1298
1299 *val = sd->contrast;
1300 return 0;
1301}
1302
1303static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1304{
1305 struct sd *sd = (struct sd *) gspca_dev;
1306
1307 sd->autogain = val;
1308
1309 if (gspca_dev->streaming) {
1310 if (val)
1311 gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1312 else
1313 gspca_dev->ctrl_inac &= ~(1 << EXPO_IDX);
1314 setautogain(gspca_dev);
1315 }
1316 return gspca_dev->usb_err;
1317}
1318
1319static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1320{
1321 struct sd *sd = (struct sd *) gspca_dev;
1322
1323 *val = sd->autogain;
1324 return 0;
1325}
1326
1327static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1328{
1329 struct sd *sd = (struct sd *) gspca_dev;
1330
1331 sd->exposure = val;
1332 if (gspca_dev->streaming)
1333 setexposure(gspca_dev);
1334 return gspca_dev->usb_err;
1335}
1336
1337static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1338{
1339 struct sd *sd = (struct sd *) gspca_dev;
1340
1341 *val = sd->exposure;
1342 return 0;
1343}
1344
1345static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1346{
1347 struct sd *sd = (struct sd *) gspca_dev;
1348
1349 sd->sharpness = val;
1350 if (gspca_dev->streaming)
1351 setsharpness(gspca_dev);
1352 return gspca_dev->usb_err;
1353}
1354
1355static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1356{
1357 struct sd *sd = (struct sd *) gspca_dev;
1358
1359 *val = sd->sharpness;
1360 return 0;
1361}
1362
1363static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
1366
1367 sd->satur = val;
1368 if (gspca_dev->streaming)
1369 setsatur(gspca_dev);
1370 return gspca_dev->usb_err;
1371}
1372
1373static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
1374{
1375 struct sd *sd = (struct sd *) gspca_dev;
1376
1377 *val = sd->satur;
1378 return 0;
1379}
1380static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1381{
1382 struct sd *sd = (struct sd *) gspca_dev;
1383
1384 sd->freq = val;
1385 if (gspca_dev->streaming)
1386 setfreq(gspca_dev);
1387 return gspca_dev->usb_err;
1388}
1389
1390static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1391{
1392 struct sd *sd = (struct sd *) gspca_dev;
1393
1394 *val = sd->freq;
1395 return 0;
1396}
1397
1398static int sd_querymenu(struct gspca_dev *gspca_dev,
1399 struct v4l2_querymenu *menu)
1400{
1401 switch (menu->id) {
1402 case V4L2_CID_POWER_LINE_FREQUENCY:
1403 switch (menu->index) {
1404 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1405 strcpy((char *) menu->name, "NoFliker");
1406 return 0;
1407 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1408 strcpy((char *) menu->name, "50 Hz");
1409 return 0;
1410 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1411 strcpy((char *) menu->name, "60 Hz");
1412 return 0;
1413 }
1414 break;
1415 }
1416 return -EINVAL;
1417}
1418
1419/* sub-driver description */
1420static const struct sd_desc sd_desc = {
1421 .name = MODULE_NAME,
1422 .ctrls = sd_ctrls,
1423 .nctrls = ARRAY_SIZE(sd_ctrls),
1424 .config = sd_config,
1425 .init = sd_init,
1426 .start = sd_start,
1427 .stopN = sd_stopN,
1428 .pkt_scan = sd_pkt_scan,
1429 .querymenu = sd_querymenu,
1430};
1431
1432/* -- module initialisation -- */
1433static const __devinitdata struct usb_device_id device_table[] = {
1434 {USB_DEVICE(0x06f8, 0x3003)},
1435 {}
1436};
1437
1438MODULE_DEVICE_TABLE(usb, device_table);
1439
1440/* -- device connect -- */
1441static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1442{
1443 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1444 THIS_MODULE);
1445}
1446
1447static struct usb_driver sd_driver = {
1448 .name = MODULE_NAME,
1449 .id_table = device_table,
1450 .probe = sd_probe,
1451 .disconnect = gspca_disconnect,
1452#ifdef CONFIG_PM
1453 .suspend = gspca_suspend,
1454 .resume = gspca_resume,
1455#endif
1456};
1457
1458/* -- module insert / remove -- */
1459static int __init sd_mod_init(void)
1460{
1461 int ret;
1462
1463 ret = usb_register(&sd_driver);
1464 if (ret < 0)
1465 return ret;
1466 PDEBUG(D_PROBE, "registered");
1467 return 0;
1468}
1469
1470static void __exit sd_mod_exit(void)
1471{
1472 usb_deregister(&sd_driver);
1473 PDEBUG(D_PROBE, "deregistered");
1474}
1475
1476module_init(sd_mod_init);
1477module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 4706a823add0..0c87c3490b1e 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -25,6 +25,7 @@
25 25
26#define MODULE_NAME "pac207" 26#define MODULE_NAME "pac207"
27 27
28#include <linux/input.h>
28#include "gspca.h" 29#include "gspca.h"
29 30
30MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>"); 31MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
@@ -77,7 +78,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
79 80
80static struct ctrl sd_ctrls[] = { 81static const struct ctrl sd_ctrls[] = {
81#define SD_BRIGHTNESS 0 82#define SD_BRIGHTNESS 0
82 { 83 {
83 { 84 {
@@ -495,6 +496,25 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
495 return 0; 496 return 0;
496} 497}
497 498
499#ifdef CONFIG_INPUT
500static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
501 u8 *data, /* interrupt packet data */
502 int len) /* interrput packet length */
503{
504 int ret = -EINVAL;
505
506 if (len == 2 && data[0] == 0x5a && data[1] == 0x5a) {
507 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
508 input_sync(gspca_dev->input_dev);
509 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
510 input_sync(gspca_dev->input_dev);
511 ret = 0;
512 }
513
514 return ret;
515}
516#endif
517
498/* sub-driver description */ 518/* sub-driver description */
499static const struct sd_desc sd_desc = { 519static const struct sd_desc sd_desc = {
500 .name = MODULE_NAME, 520 .name = MODULE_NAME,
@@ -506,6 +526,9 @@ static const struct sd_desc sd_desc = {
506 .stopN = sd_stopN, 526 .stopN = sd_stopN,
507 .dq_callback = pac207_do_auto_gain, 527 .dq_callback = pac207_do_auto_gain,
508 .pkt_scan = sd_pkt_scan, 528 .pkt_scan = sd_pkt_scan,
529#ifdef CONFIG_INPUT
530 .int_pkt_scan = sd_int_pkt_scan,
531#endif
509}; 532};
510 533
511/* -- module initialisation -- */ 534/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index de0b66c4b56e..2a68220d1ada 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -4,7 +4,9 @@
4 * 4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 * 6 *
7 * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu> 7 * Separated from Pixart PAC7311 library by Márton Németh
8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
9 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
8 * 10 *
9 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -22,33 +24,26 @@
22 */ 24 */
23 25
24/* Some documentation about various registers as determined by trial and error. 26/* Some documentation about various registers as determined by trial and error.
25 When the register addresses differ between the 7202 and the 7311 the 2
26 different addresses are written as 7302addr/7311addr, when one of the 2
27 addresses is a - sign that register description is not valid for the
28 matching IC.
29 27
30 Register page 1: 28 Register page 1:
31 29
32 Address Description 30 Address Description
33 -/0x08 Unknown compressor related, must always be 8 except when not
34 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
35 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
36 bits 345 seem to toggle per color gains on/off (inverted)
37 0x78 Global control, bit 6 controls the LED (inverted) 31 0x78 Global control, bit 6 controls the LED (inverted)
38 -/0x80 JPEG compression ratio ? Best not touched
39 32
40 Register page 3/4: 33 Register page 3:
41 34
42 Address Description 35 Address Description
43 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on 36 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
44 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 37 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
45 -/0x0f Master gain 1-245, low value = high gain 38 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
46 0x10/- Master gain 0-31 39 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
47 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) 40 63 -> ~27 fps, the 2 msb's must always be 1 !!
41 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
42 1 -> ~30 fps, 2 -> ~20 fps
43 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
44 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
45 0x10 Master gain 0-31
48 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
49 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
50 completely disable the analog amplification block. Set to 0x68
51 for max gain, 0x14 for minimal gain.
52 47
53 The registers are accessed in the following functions: 48 The registers are accessed in the following functions:
54 49
@@ -68,6 +63,7 @@
68 63
69#define MODULE_NAME "pac7302" 64#define MODULE_NAME "pac7302"
70 65
66#include <linux/input.h>
71#include <media/v4l2-chip-ident.h> 67#include <media/v4l2-chip-ident.h>
72#include "gspca.h" 68#include "gspca.h"
73 69
@@ -86,8 +82,8 @@ struct sd {
86 unsigned char red_balance; 82 unsigned char red_balance;
87 unsigned char blue_balance; 83 unsigned char blue_balance;
88 unsigned char gain; 84 unsigned char gain;
89 unsigned char exposure;
90 unsigned char autogain; 85 unsigned char autogain;
86 unsigned short exposure;
91 __u8 hflip; 87 __u8 hflip;
92 __u8 vflip; 88 __u8 vflip;
93 u8 flags; 89 u8 flags;
@@ -124,8 +120,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
124static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 120static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
125static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 121static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
126 122
127static struct ctrl sd_ctrls[] = { 123static const struct ctrl sd_ctrls[] = {
128/* This control is pac7302 only */
129 { 124 {
130 { 125 {
131 .id = V4L2_CID_BRIGHTNESS, 126 .id = V4L2_CID_BRIGHTNESS,
@@ -141,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_setbrightness, 136 .set = sd_setbrightness,
142 .get = sd_getbrightness, 137 .get = sd_getbrightness,
143 }, 138 },
144/* This control is for both the 7302 and the 7311 */
145 { 139 {
146 { 140 {
147 .id = V4L2_CID_CONTRAST, 141 .id = V4L2_CID_CONTRAST,
@@ -157,7 +151,6 @@ static struct ctrl sd_ctrls[] = {
157 .set = sd_setcontrast, 151 .set = sd_setcontrast,
158 .get = sd_getcontrast, 152 .get = sd_getcontrast,
159 }, 153 },
160/* This control is pac7302 only */
161 { 154 {
162 { 155 {
163 .id = V4L2_CID_SATURATION, 156 .id = V4L2_CID_SATURATION,
@@ -215,7 +208,6 @@ static struct ctrl sd_ctrls[] = {
215 .set = sd_setbluebalance, 208 .set = sd_setbluebalance,
216 .get = sd_getbluebalance, 209 .get = sd_getbluebalance,
217 }, 210 },
218/* All controls below are for both the 7302 and the 7311 */
219 { 211 {
220 { 212 {
221 .id = V4L2_CID_GAIN, 213 .id = V4L2_CID_GAIN,
@@ -238,11 +230,10 @@ static struct ctrl sd_ctrls[] = {
238 .type = V4L2_CTRL_TYPE_INTEGER, 230 .type = V4L2_CTRL_TYPE_INTEGER,
239 .name = "Exposure", 231 .name = "Exposure",
240 .minimum = 0, 232 .minimum = 0,
241#define EXPOSURE_MAX 255 233 .maximum = 1023,
242 .maximum = EXPOSURE_MAX,
243 .step = 1, 234 .step = 1,
244#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 235#define EXPOSURE_DEF 66 /* 33 ms / 30 fps */
245#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 236#define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
246 .default_value = EXPOSURE_DEF, 237 .default_value = EXPOSURE_DEF,
247 }, 238 },
248 .set = sd_setexposure, 239 .set = sd_setexposure,
@@ -301,7 +292,6 @@ static const struct v4l2_pix_format vga_mode[] = {
301}; 292};
302 293
303#define LOAD_PAGE3 255 294#define LOAD_PAGE3 255
304#define LOAD_PAGE4 254
305#define END_OF_SEQUENCE 0 295#define END_OF_SEQUENCE 0
306 296
307/* pac 7302 */ 297/* pac 7302 */
@@ -379,7 +369,7 @@ static const __u8 start_7302[] = {
379#define SKIP 0xaa 369#define SKIP 0xaa
380/* page 3 - the value SKIP says skip the index - see reg_w_page() */ 370/* page 3 - the value SKIP says skip the index - see reg_w_page() */
381static const __u8 page3_7302[] = { 371static const __u8 page3_7302[] = {
382 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, 372 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
383 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 373 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
384 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 374 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, 375 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
@@ -388,7 +378,7 @@ static const __u8 page3_7302[] = {
388 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, 378 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
389 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 379 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, 380 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, 381 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
392 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 382 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, 383 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -401,12 +391,14 @@ static const __u8 page3_7302[] = {
401 0x00 391 0x00
402}; 392};
403 393
404static int reg_w_buf(struct gspca_dev *gspca_dev, 394static void reg_w_buf(struct gspca_dev *gspca_dev,
405 __u8 index, 395 __u8 index,
406 const char *buffer, int len) 396 const char *buffer, int len)
407{ 397{
408 int ret; 398 int ret;
409 399
400 if (gspca_dev->usb_err < 0)
401 return;
410 memcpy(gspca_dev->usb_buf, buffer, len); 402 memcpy(gspca_dev->usb_buf, buffer, len);
411 ret = usb_control_msg(gspca_dev->dev, 403 ret = usb_control_msg(gspca_dev->dev,
412 usb_sndctrlpipe(gspca_dev->dev, 0), 404 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -415,20 +407,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
415 0, /* value */ 407 0, /* value */
416 index, gspca_dev->usb_buf, len, 408 index, gspca_dev->usb_buf, len,
417 500); 409 500);
418 if (ret < 0) 410 if (ret < 0) {
419 PDEBUG(D_ERR, "reg_w_buf(): " 411 PDEBUG(D_ERR, "reg_w_buf(): "
420 "Failed to write registers to index 0x%x, error %i", 412 "Failed to write registers to index 0x%x, error %i",
421 index, ret); 413 index, ret);
422 return ret; 414 gspca_dev->usb_err = ret;
415 }
423} 416}
424 417
425 418
426static int reg_w(struct gspca_dev *gspca_dev, 419static void reg_w(struct gspca_dev *gspca_dev,
427 __u8 index, 420 __u8 index,
428 __u8 value) 421 __u8 value)
429{ 422{
430 int ret; 423 int ret;
431 424
425 if (gspca_dev->usb_err < 0)
426 return;
432 gspca_dev->usb_buf[0] = value; 427 gspca_dev->usb_buf[0] = value;
433 ret = usb_control_msg(gspca_dev->dev, 428 ret = usb_control_msg(gspca_dev->dev,
434 usb_sndctrlpipe(gspca_dev->dev, 0), 429 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -436,32 +431,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
436 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 431 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
437 0, index, gspca_dev->usb_buf, 1, 432 0, index, gspca_dev->usb_buf, 1,
438 500); 433 500);
439 if (ret < 0) 434 if (ret < 0) {
440 PDEBUG(D_ERR, "reg_w(): " 435 PDEBUG(D_ERR, "reg_w(): "
441 "Failed to write register to index 0x%x, value 0x%x, error %i", 436 "Failed to write register to index 0x%x, value 0x%x, error %i",
442 index, value, ret); 437 index, value, ret);
443 return ret; 438 gspca_dev->usb_err = ret;
439 }
444} 440}
445 441
446static int reg_w_seq(struct gspca_dev *gspca_dev, 442static void reg_w_seq(struct gspca_dev *gspca_dev,
447 const __u8 *seq, int len) 443 const __u8 *seq, int len)
448{ 444{
449 int ret = 0;
450 while (--len >= 0) { 445 while (--len >= 0) {
451 if (0 <= ret) 446 reg_w(gspca_dev, seq[0], seq[1]);
452 ret = reg_w(gspca_dev, seq[0], seq[1]);
453 seq += 2; 447 seq += 2;
454 } 448 }
455 return ret;
456} 449}
457 450
458/* load the beginning of a page */ 451/* load the beginning of a page */
459static int reg_w_page(struct gspca_dev *gspca_dev, 452static void reg_w_page(struct gspca_dev *gspca_dev,
460 const __u8 *page, int len) 453 const __u8 *page, int len)
461{ 454{
462 int index; 455 int index;
463 int ret = 0; 456 int ret = 0;
464 457
458 if (gspca_dev->usb_err < 0)
459 return;
465 for (index = 0; index < len; index++) { 460 for (index = 0; index < len; index++) {
466 if (page[index] == SKIP) /* skip this index */ 461 if (page[index] == SKIP) /* skip this index */
467 continue; 462 continue;
@@ -477,56 +472,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
477 "Failed to write register to index 0x%x, " 472 "Failed to write register to index 0x%x, "
478 "value 0x%x, error %i", 473 "value 0x%x, error %i",
479 index, page[index], ret); 474 index, page[index], ret);
475 gspca_dev->usb_err = ret;
480 break; 476 break;
481 } 477 }
482 } 478 }
483 return ret;
484} 479}
485 480
486/* output a variable sequence */ 481/* output a variable sequence */
487static int reg_w_var(struct gspca_dev *gspca_dev, 482static void reg_w_var(struct gspca_dev *gspca_dev,
488 const __u8 *seq, 483 const __u8 *seq,
489 const __u8 *page3, unsigned int page3_len, 484 const __u8 *page3, unsigned int page3_len)
490 const __u8 *page4, unsigned int page4_len)
491{ 485{
492 int index, len; 486 int index, len;
493 int ret = 0;
494 487
495 for (;;) { 488 for (;;) {
496 index = *seq++; 489 index = *seq++;
497 len = *seq++; 490 len = *seq++;
498 switch (len) { 491 switch (len) {
499 case END_OF_SEQUENCE: 492 case END_OF_SEQUENCE:
500 return ret; 493 return;
501 case LOAD_PAGE4:
502 ret = reg_w_page(gspca_dev, page4, page4_len);
503 break;
504 case LOAD_PAGE3: 494 case LOAD_PAGE3:
505 ret = reg_w_page(gspca_dev, page3, page3_len); 495 reg_w_page(gspca_dev, page3, page3_len);
506 break; 496 break;
507 default: 497 default:
508 if (len > USB_BUF_SZ) { 498 if (len > USB_BUF_SZ) {
509 PDEBUG(D_ERR|D_STREAM, 499 PDEBUG(D_ERR|D_STREAM,
510 "Incorrect variable sequence"); 500 "Incorrect variable sequence");
511 return -EINVAL; 501 return;
512 } 502 }
513 while (len > 0) { 503 while (len > 0) {
514 if (len < 8) { 504 if (len < 8) {
515 ret = reg_w_buf(gspca_dev, 505 reg_w_buf(gspca_dev,
516 index, seq, len); 506 index, seq, len);
517 if (ret < 0)
518 return ret;
519 seq += len; 507 seq += len;
520 break; 508 break;
521 } 509 }
522 ret = reg_w_buf(gspca_dev, index, seq, 8); 510 reg_w_buf(gspca_dev, index, seq, 8);
523 seq += 8; 511 seq += 8;
524 index += 8; 512 index += 8;
525 len -= 8; 513 len -= 8;
526 } 514 }
527 } 515 }
528 if (ret < 0)
529 return ret;
530 } 516 }
531 /* not reached */ 517 /* not reached */
532} 518}
@@ -560,11 +546,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
560} 546}
561 547
562/* This function is used by pac7302 only */ 548/* This function is used by pac7302 only */
563static int setbrightcont(struct gspca_dev *gspca_dev) 549static void setbrightcont(struct gspca_dev *gspca_dev)
564{ 550{
565 struct sd *sd = (struct sd *) gspca_dev; 551 struct sd *sd = (struct sd *) gspca_dev;
566 int i, v; 552 int i, v;
567 int ret;
568 static const __u8 max[10] = 553 static const __u8 max[10] =
569 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 554 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
570 0xd4, 0xec}; 555 0xd4, 0xec};
@@ -572,7 +557,7 @@ static int setbrightcont(struct gspca_dev *gspca_dev)
572 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 557 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
573 0x11, 0x0b}; 558 0x11, 0x0b};
574 559
575 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 560 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
576 for (i = 0; i < 10; i++) { 561 for (i = 0; i < 10; i++) {
577 v = max[i]; 562 v = max[i];
578 v += (sd->brightness - BRIGHTNESS_MAX) 563 v += (sd->brightness - BRIGHTNESS_MAX)
@@ -582,136 +567,121 @@ static int setbrightcont(struct gspca_dev *gspca_dev)
582 v = 0; 567 v = 0;
583 else if (v > 0xff) 568 else if (v > 0xff)
584 v = 0xff; 569 v = 0xff;
585 if (0 <= ret) 570 reg_w(gspca_dev, 0xa2 + i, v);
586 ret = reg_w(gspca_dev, 0xa2 + i, v);
587 } 571 }
588 if (0 <= ret) 572 reg_w(gspca_dev, 0xdc, 0x01);
589 ret = reg_w(gspca_dev, 0xdc, 0x01);
590 return ret;
591} 573}
592 574
593/* This function is used by pac7302 only */ 575/* This function is used by pac7302 only */
594static int setcolors(struct gspca_dev *gspca_dev) 576static void setcolors(struct gspca_dev *gspca_dev)
595{ 577{
596 struct sd *sd = (struct sd *) gspca_dev; 578 struct sd *sd = (struct sd *) gspca_dev;
597 int i, v; 579 int i, v;
598 int ret;
599 static const int a[9] = 580 static const int a[9] =
600 {217, -212, 0, -101, 170, -67, -38, -315, 355}; 581 {217, -212, 0, -101, 170, -67, -38, -315, 355};
601 static const int b[9] = 582 static const int b[9] =
602 {19, 106, 0, 19, 106, 1, 19, 106, 1}; 583 {19, 106, 0, 19, 106, 1, 19, 106, 1};
603 584
604 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 585 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
605 if (0 <= ret) 586 reg_w(gspca_dev, 0x11, 0x01);
606 ret = reg_w(gspca_dev, 0x11, 0x01); 587 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
607 if (0 <= ret)
608 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
609 for (i = 0; i < 9; i++) { 588 for (i = 0; i < 9; i++) {
610 v = a[i] * sd->colors / COLOR_MAX + b[i]; 589 v = a[i] * sd->colors / COLOR_MAX + b[i];
611 if (0 <= ret) 590 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
612 ret = reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 591 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
613 if (0 <= ret)
614 ret = reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
615 } 592 }
616 if (0 <= ret) 593 reg_w(gspca_dev, 0xdc, 0x01);
617 ret = reg_w(gspca_dev, 0xdc, 0x01);
618 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 594 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
619 return ret;
620} 595}
621 596
622static int setwhitebalance(struct gspca_dev *gspca_dev) 597static void setwhitebalance(struct gspca_dev *gspca_dev)
623{ 598{
624 struct sd *sd = (struct sd *) gspca_dev; 599 struct sd *sd = (struct sd *) gspca_dev;
625 int ret;
626 600
627 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 601 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
628 if (0 <= ret) 602 reg_w(gspca_dev, 0xc6, sd->white_balance);
629 ret = reg_w(gspca_dev, 0xc6, sd->white_balance);
630 603
631 if (0 <= ret) 604 reg_w(gspca_dev, 0xdc, 0x01);
632 ret = reg_w(gspca_dev, 0xdc, 0x01);
633 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); 605 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
634 return ret;
635} 606}
636 607
637static int setredbalance(struct gspca_dev *gspca_dev) 608static void setredbalance(struct gspca_dev *gspca_dev)
638{ 609{
639 struct sd *sd = (struct sd *) gspca_dev; 610 struct sd *sd = (struct sd *) gspca_dev;
640 int ret;
641 611
642 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 612 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
643 if (0 <= ret) 613 reg_w(gspca_dev, 0xc5, sd->red_balance);
644 ret = reg_w(gspca_dev, 0xc5, sd->red_balance);
645 614
646 if (0 <= ret) 615 reg_w(gspca_dev, 0xdc, 0x01);
647 ret = reg_w(gspca_dev, 0xdc, 0x01);
648 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); 616 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
649 return ret;
650} 617}
651 618
652static int setbluebalance(struct gspca_dev *gspca_dev) 619static void setbluebalance(struct gspca_dev *gspca_dev)
653{ 620{
654 struct sd *sd = (struct sd *) gspca_dev; 621 struct sd *sd = (struct sd *) gspca_dev;
655 int ret;
656 622
657 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 623 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
658 if (0 <= ret) 624 reg_w(gspca_dev, 0xc7, sd->blue_balance);
659 ret = reg_w(gspca_dev, 0xc7, sd->blue_balance);
660 625
661 if (0 <= ret) 626 reg_w(gspca_dev, 0xdc, 0x01);
662 ret = reg_w(gspca_dev, 0xdc, 0x01);
663 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); 627 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
664 return ret;
665} 628}
666 629
667static int setgain(struct gspca_dev *gspca_dev) 630static void setgain(struct gspca_dev *gspca_dev)
668{ 631{
669 struct sd *sd = (struct sd *) gspca_dev; 632 struct sd *sd = (struct sd *) gspca_dev;
670 int ret;
671 633
672 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 634 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
673 if (0 <= ret) 635 reg_w(gspca_dev, 0x10, sd->gain >> 3);
674 ret = reg_w(gspca_dev, 0x10, sd->gain >> 3);
675 636
676 /* load registers to sensor (Bit 0, auto clear) */ 637 /* load registers to sensor (Bit 0, auto clear) */
677 if (0 <= ret) 638 reg_w(gspca_dev, 0x11, 0x01);
678 ret = reg_w(gspca_dev, 0x11, 0x01);
679 return ret;
680} 639}
681 640
682static int setexposure(struct gspca_dev *gspca_dev) 641static void setexposure(struct gspca_dev *gspca_dev)
683{ 642{
684 struct sd *sd = (struct sd *) gspca_dev; 643 struct sd *sd = (struct sd *) gspca_dev;
685 int ret; 644 __u8 clockdiv;
686 __u8 reg; 645 __u16 exposure;
687 646
688 /* register 2 of frame 3/4 contains the clock divider configuring the 647 /* register 2 of frame 3 contains the clock divider configuring the
689 no fps according to the formula: 60 / reg. sd->exposure is the 648 no fps according to the formula: 90 / reg. sd->exposure is the
690 desired exposure time in ms. */ 649 desired exposure time in 0.5 ms. */
691 reg = 120 * sd->exposure / 1000; 650 clockdiv = (90 * sd->exposure + 1999) / 2000;
692 if (reg < 2) 651
693 reg = 2; 652 /* Note clockdiv = 3 also works, but when running at 30 fps, depending
694 else if (reg > 63) 653 on the scene being recorded, the camera switches to another
695 reg = 63; 654 quantization table for certain JPEG blocks, and we don't know how
696 655 to decompress these blocks. So we cap the framerate at 15 fps */
697 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to 656 if (clockdiv < 6)
698 the nearest multiple of 3, except when between 6 and 12? */ 657 clockdiv = 6;
699 if (reg < 6 || reg > 12) 658 else if (clockdiv > 63)
700 reg = ((reg + 1) / 3) * 3; 659 clockdiv = 63;
701 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 660
702 if (0 <= ret) 661 /* reg2 MUST be a multiple of 3, except when between 6 and 12?
703 ret = reg_w(gspca_dev, 0x02, reg); 662 Always round up, otherwise we cannot get the desired frametime
663 using the partial frame time exposure control */
664 if (clockdiv < 6 || clockdiv > 12)
665 clockdiv = ((clockdiv + 2) / 3) * 3;
666
667 /* frame exposure time in ms = 1000 * clockdiv / 90 ->
668 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
669 exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
670 /* 0 = use full frametime, 448 = no exposure, reverse it */
671 exposure = 448 - exposure;
672
673 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
674 reg_w(gspca_dev, 0x02, clockdiv);
675 reg_w(gspca_dev, 0x0e, exposure & 0xff);
676 reg_w(gspca_dev, 0x0f, exposure >> 8);
704 677
705 /* load registers to sensor (Bit 0, auto clear) */ 678 /* load registers to sensor (Bit 0, auto clear) */
706 if (0 <= ret) 679 reg_w(gspca_dev, 0x11, 0x01);
707 ret = reg_w(gspca_dev, 0x11, 0x01);
708 return ret;
709} 680}
710 681
711static int sethvflip(struct gspca_dev *gspca_dev) 682static void sethvflip(struct gspca_dev *gspca_dev)
712{ 683{
713 struct sd *sd = (struct sd *) gspca_dev; 684 struct sd *sd = (struct sd *) gspca_dev;
714 int ret;
715 u8 data, hflip, vflip; 685 u8 data, hflip, vflip;
716 686
717 hflip = sd->hflip; 687 hflip = sd->hflip;
@@ -721,48 +691,37 @@ static int sethvflip(struct gspca_dev *gspca_dev)
721 if (sd->flags & FL_VFLIP) 691 if (sd->flags & FL_VFLIP)
722 vflip = !vflip; 692 vflip = !vflip;
723 693
724 ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 694 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
725 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); 695 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
726 if (0 <= ret) 696 reg_w(gspca_dev, 0x21, data);
727 ret = reg_w(gspca_dev, 0x21, data); 697
728 /* load registers to sensor (Bit 0, auto clear) */ 698 /* load registers to sensor (Bit 0, auto clear) */
729 if (0 <= ret) 699 reg_w(gspca_dev, 0x11, 0x01);
730 ret = reg_w(gspca_dev, 0x11, 0x01);
731 return ret;
732} 700}
733 701
734/* this function is called at probe and resume time for pac7302 */ 702/* this function is called at probe and resume time for pac7302 */
735static int sd_init(struct gspca_dev *gspca_dev) 703static int sd_init(struct gspca_dev *gspca_dev)
736{ 704{
737 return reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2); 705 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
706 return gspca_dev->usb_err;
738} 707}
739 708
740static int sd_start(struct gspca_dev *gspca_dev) 709static int sd_start(struct gspca_dev *gspca_dev)
741{ 710{
742 struct sd *sd = (struct sd *) gspca_dev; 711 struct sd *sd = (struct sd *) gspca_dev;
743 int ret = 0;
744 712
745 sd->sof_read = 0; 713 sd->sof_read = 0;
746 714
747 ret = reg_w_var(gspca_dev, start_7302, 715 reg_w_var(gspca_dev, start_7302,
748 page3_7302, sizeof(page3_7302), 716 page3_7302, sizeof(page3_7302));
749 NULL, 0); 717 setbrightcont(gspca_dev);
750 if (0 <= ret) 718 setcolors(gspca_dev);
751 ret = setbrightcont(gspca_dev); 719 setwhitebalance(gspca_dev);
752 if (0 <= ret) 720 setredbalance(gspca_dev);
753 ret = setcolors(gspca_dev); 721 setbluebalance(gspca_dev);
754 if (0 <= ret) 722 setgain(gspca_dev);
755 ret = setwhitebalance(gspca_dev); 723 setexposure(gspca_dev);
756 if (0 <= ret) 724 sethvflip(gspca_dev);
757 ret = setredbalance(gspca_dev);
758 if (0 <= ret)
759 ret = setbluebalance(gspca_dev);
760 if (0 <= ret)
761 ret = setgain(gspca_dev);
762 if (0 <= ret)
763 ret = setexposure(gspca_dev);
764 if (0 <= ret)
765 ret = sethvflip(gspca_dev);
766 725
767 /* only resolution 640x480 is supported for pac7302 */ 726 /* only resolution 640x480 is supported for pac7302 */
768 727
@@ -771,34 +730,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
771 atomic_set(&sd->avg_lum, -1); 730 atomic_set(&sd->avg_lum, -1);
772 731
773 /* start stream */ 732 /* start stream */
774 if (0 <= ret) 733 reg_w(gspca_dev, 0xff, 0x01);
775 ret = reg_w(gspca_dev, 0xff, 0x01); 734 reg_w(gspca_dev, 0x78, 0x01);
776 if (0 <= ret)
777 ret = reg_w(gspca_dev, 0x78, 0x01);
778 735
779 return ret; 736 return gspca_dev->usb_err;
780} 737}
781 738
782static void sd_stopN(struct gspca_dev *gspca_dev) 739static void sd_stopN(struct gspca_dev *gspca_dev)
783{ 740{
784 int ret;
785 741
786 /* stop stream */ 742 /* stop stream */
787 ret = reg_w(gspca_dev, 0xff, 0x01); 743 reg_w(gspca_dev, 0xff, 0x01);
788 if (0 <= ret) 744 reg_w(gspca_dev, 0x78, 0x00);
789 ret = reg_w(gspca_dev, 0x78, 0x00);
790} 745}
791 746
792/* called on streamoff with alt 0 and on disconnect for pac7302 */ 747/* called on streamoff with alt 0 and on disconnect for pac7302 */
793static void sd_stop0(struct gspca_dev *gspca_dev) 748static void sd_stop0(struct gspca_dev *gspca_dev)
794{ 749{
795 int ret;
796
797 if (!gspca_dev->present) 750 if (!gspca_dev->present)
798 return; 751 return;
799 ret = reg_w(gspca_dev, 0xff, 0x01); 752 reg_w(gspca_dev, 0xff, 0x01);
800 if (0 <= ret) 753 reg_w(gspca_dev, 0x78, 0x40);
801 ret = reg_w(gspca_dev, 0x78, 0x40);
802} 754}
803 755
804/* Include pac common sof detection functions */ 756/* Include pac common sof detection functions */
@@ -808,22 +760,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
808{ 760{
809 struct sd *sd = (struct sd *) gspca_dev; 761 struct sd *sd = (struct sd *) gspca_dev;
810 int avg_lum = atomic_read(&sd->avg_lum); 762 int avg_lum = atomic_read(&sd->avg_lum);
811 int desired_lum, deadzone; 763 int desired_lum;
764 const int deadzone = 30;
812 765
813 if (avg_lum == -1) 766 if (avg_lum == -1)
814 return; 767 return;
815 768
816 desired_lum = 270 + sd->brightness * 4; 769 desired_lum = 270 + sd->brightness;
817 /* Hack hack, with the 7202 the first exposure step is
818 pretty large, so if we're about to make the first
819 exposure increase make the deadzone large to avoid
820 oscilating */
821 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
822 sd->exposure > EXPOSURE_DEF &&
823 sd->exposure < 42)
824 deadzone = 90;
825 else
826 deadzone = 30;
827 770
828 if (sd->autogain_ignore_frames > 0) 771 if (sd->autogain_ignore_frames > 0)
829 sd->autogain_ignore_frames--; 772 sd->autogain_ignore_frames--;
@@ -947,7 +890,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
947 sd->brightness = val; 890 sd->brightness = val;
948 if (gspca_dev->streaming) 891 if (gspca_dev->streaming)
949 setbrightcont(gspca_dev); 892 setbrightcont(gspca_dev);
950 return 0; 893 return gspca_dev->usb_err;
951} 894}
952 895
953static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 896static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -966,7 +909,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
966 if (gspca_dev->streaming) { 909 if (gspca_dev->streaming) {
967 setbrightcont(gspca_dev); 910 setbrightcont(gspca_dev);
968 } 911 }
969 return 0; 912 return gspca_dev->usb_err;
970} 913}
971 914
972static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 915static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -984,7 +927,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
984 sd->colors = val; 927 sd->colors = val;
985 if (gspca_dev->streaming) 928 if (gspca_dev->streaming)
986 setcolors(gspca_dev); 929 setcolors(gspca_dev);
987 return 0; 930 return gspca_dev->usb_err;
988} 931}
989 932
990static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 933static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -998,14 +941,11 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
998static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) 941static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
999{ 942{
1000 struct sd *sd = (struct sd *) gspca_dev; 943 struct sd *sd = (struct sd *) gspca_dev;
1001 int ret = 0;
1002 944
1003 sd->white_balance = val; 945 sd->white_balance = val;
1004 if (gspca_dev->streaming) 946 if (gspca_dev->streaming)
1005 ret = setwhitebalance(gspca_dev); 947 setwhitebalance(gspca_dev);
1006 if (0 <= ret) 948 return gspca_dev->usb_err;
1007 ret = 0;
1008 return ret;
1009} 949}
1010 950
1011static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) 951static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1019,14 +959,11 @@ static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1019static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) 959static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
1020{ 960{
1021 struct sd *sd = (struct sd *) gspca_dev; 961 struct sd *sd = (struct sd *) gspca_dev;
1022 int ret = 0;
1023 962
1024 sd->red_balance = val; 963 sd->red_balance = val;
1025 if (gspca_dev->streaming) 964 if (gspca_dev->streaming)
1026 ret = setredbalance(gspca_dev); 965 setredbalance(gspca_dev);
1027 if (0 <= ret) 966 return gspca_dev->usb_err;
1028 ret = 0;
1029 return ret;
1030} 967}
1031 968
1032static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) 969static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1040,14 +977,11 @@ static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
1040static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) 977static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
1041{ 978{
1042 struct sd *sd = (struct sd *) gspca_dev; 979 struct sd *sd = (struct sd *) gspca_dev;
1043 int ret = 0;
1044 980
1045 sd->blue_balance = val; 981 sd->blue_balance = val;
1046 if (gspca_dev->streaming) 982 if (gspca_dev->streaming)
1047 ret = setbluebalance(gspca_dev); 983 setbluebalance(gspca_dev);
1048 if (0 <= ret) 984 return gspca_dev->usb_err;
1049 ret = 0;
1050 return ret;
1051} 985}
1052 986
1053static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) 987static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1065,7 +999,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1065 sd->gain = val; 999 sd->gain = val;
1066 if (gspca_dev->streaming) 1000 if (gspca_dev->streaming)
1067 setgain(gspca_dev); 1001 setgain(gspca_dev);
1068 return 0; 1002 return gspca_dev->usb_err;
1069} 1003}
1070 1004
1071static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 1005static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1083,7 +1017,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1083 sd->exposure = val; 1017 sd->exposure = val;
1084 if (gspca_dev->streaming) 1018 if (gspca_dev->streaming)
1085 setexposure(gspca_dev); 1019 setexposure(gspca_dev);
1086 return 0; 1020 return gspca_dev->usb_err;
1087} 1021}
1088 1022
1089static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 1023static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1114,7 +1048,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1114 } 1048 }
1115 } 1049 }
1116 1050
1117 return 0; 1051 return gspca_dev->usb_err;
1118} 1052}
1119 1053
1120static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1054static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1132,7 +1066,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1132 sd->hflip = val; 1066 sd->hflip = val;
1133 if (gspca_dev->streaming) 1067 if (gspca_dev->streaming)
1134 sethvflip(gspca_dev); 1068 sethvflip(gspca_dev);
1135 return 0; 1069 return gspca_dev->usb_err;
1136} 1070}
1137 1071
1138static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 1072static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1150,7 +1084,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1150 sd->vflip = val; 1084 sd->vflip = val;
1151 if (gspca_dev->streaming) 1085 if (gspca_dev->streaming)
1152 sethvflip(gspca_dev); 1086 sethvflip(gspca_dev);
1153 return 0; 1087 return gspca_dev->usb_err;
1154} 1088}
1155 1089
1156static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 1090static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -1165,7 +1099,6 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1165static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1099static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1166 struct v4l2_dbg_register *reg) 1100 struct v4l2_dbg_register *reg)
1167{ 1101{
1168 int ret = -EINVAL;
1169 __u8 index; 1102 __u8 index;
1170 __u8 value; 1103 __u8 value;
1171 1104
@@ -1185,14 +1118,12 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1185 /* Note that there shall be no access to other page 1118 /* Note that there shall be no access to other page
1186 by any other function between the page swith and 1119 by any other function between the page swith and
1187 the actual register write */ 1120 the actual register write */
1188 ret = reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 1121 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
1189 if (0 <= ret) 1122 reg_w(gspca_dev, index, value);
1190 ret = reg_w(gspca_dev, index, value);
1191 1123
1192 if (0 <= ret) 1124 reg_w(gspca_dev, 0xdc, 0x01);
1193 ret = reg_w(gspca_dev, 0xdc, 0x01);
1194 } 1125 }
1195 return ret; 1126 return gspca_dev->usb_err;
1196} 1127}
1197 1128
1198static int sd_chip_ident(struct gspca_dev *gspca_dev, 1129static int sd_chip_ident(struct gspca_dev *gspca_dev,
@@ -1210,8 +1141,39 @@ static int sd_chip_ident(struct gspca_dev *gspca_dev,
1210} 1141}
1211#endif 1142#endif
1212 1143
1144#ifdef CONFIG_INPUT
1145static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1146 u8 *data, /* interrupt packet data */
1147 int len) /* interrput packet length */
1148{
1149 int ret = -EINVAL;
1150 u8 data0, data1;
1151
1152 if (len == 2) {
1153 data0 = data[0];
1154 data1 = data[1];
1155 if ((data0 == 0x00 && data1 == 0x11) ||
1156 (data0 == 0x22 && data1 == 0x33) ||
1157 (data0 == 0x44 && data1 == 0x55) ||
1158 (data0 == 0x66 && data1 == 0x77) ||
1159 (data0 == 0x88 && data1 == 0x99) ||
1160 (data0 == 0xaa && data1 == 0xbb) ||
1161 (data0 == 0xcc && data1 == 0xdd) ||
1162 (data0 == 0xee && data1 == 0xff)) {
1163 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1164 input_sync(gspca_dev->input_dev);
1165 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1166 input_sync(gspca_dev->input_dev);
1167 ret = 0;
1168 }
1169 }
1170
1171 return ret;
1172}
1173#endif
1174
1213/* sub-driver description for pac7302 */ 1175/* sub-driver description for pac7302 */
1214static struct sd_desc sd_desc = { 1176static const struct sd_desc sd_desc = {
1215 .name = MODULE_NAME, 1177 .name = MODULE_NAME,
1216 .ctrls = sd_ctrls, 1178 .ctrls = sd_ctrls,
1217 .nctrls = ARRAY_SIZE(sd_ctrls), 1179 .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -1226,6 +1188,9 @@ static struct sd_desc sd_desc = {
1226 .set_register = sd_dbg_s_register, 1188 .set_register = sd_dbg_s_register,
1227 .get_chip_ident = sd_chip_ident, 1189 .get_chip_ident = sd_chip_ident,
1228#endif 1190#endif
1191#ifdef CONFIG_INPUT
1192 .int_pkt_scan = sd_int_pkt_scan,
1193#endif
1229}; 1194};
1230 1195
1231/* -- module initialisation -- */ 1196/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 42cfcdfd8f4f..44fed9686729 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -51,6 +51,7 @@
51 51
52#define MODULE_NAME "pac7311" 52#define MODULE_NAME "pac7311"
53 53
54#include <linux/input.h>
54#include "gspca.h" 55#include "gspca.h"
55 56
56MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 57MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
@@ -88,7 +89,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 90static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
90 91
91static struct ctrl sd_ctrls[] = { 92static const struct ctrl sd_ctrls[] = {
92/* This control is for both the 7302 and the 7311 */ 93/* This control is for both the 7302 and the 7311 */
93 { 94 {
94 { 95 {
@@ -200,7 +201,6 @@ static const struct v4l2_pix_format vga_mode[] = {
200 .priv = 0}, 201 .priv = 0},
201}; 202};
202 203
203#define LOAD_PAGE3 255
204#define LOAD_PAGE4 254 204#define LOAD_PAGE4 254
205#define END_OF_SEQUENCE 0 205#define END_OF_SEQUENCE 0
206 206
@@ -259,12 +259,14 @@ static const __u8 page4_7311[] = {
259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 259 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
260}; 260};
261 261
262static int reg_w_buf(struct gspca_dev *gspca_dev, 262static void reg_w_buf(struct gspca_dev *gspca_dev,
263 __u8 index, 263 __u8 index,
264 const char *buffer, int len) 264 const char *buffer, int len)
265{ 265{
266 int ret; 266 int ret;
267 267
268 if (gspca_dev->usb_err < 0)
269 return;
268 memcpy(gspca_dev->usb_buf, buffer, len); 270 memcpy(gspca_dev->usb_buf, buffer, len);
269 ret = usb_control_msg(gspca_dev->dev, 271 ret = usb_control_msg(gspca_dev->dev,
270 usb_sndctrlpipe(gspca_dev->dev, 0), 272 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -273,20 +275,23 @@ static int reg_w_buf(struct gspca_dev *gspca_dev,
273 0, /* value */ 275 0, /* value */
274 index, gspca_dev->usb_buf, len, 276 index, gspca_dev->usb_buf, len,
275 500); 277 500);
276 if (ret < 0) 278 if (ret < 0) {
277 PDEBUG(D_ERR, "reg_w_buf(): " 279 PDEBUG(D_ERR, "reg_w_buf(): "
278 "Failed to write registers to index 0x%x, error %i", 280 "Failed to write registers to index 0x%x, error %i",
279 index, ret); 281 index, ret);
280 return ret; 282 gspca_dev->usb_err = ret;
283 }
281} 284}
282 285
283 286
284static int reg_w(struct gspca_dev *gspca_dev, 287static void reg_w(struct gspca_dev *gspca_dev,
285 __u8 index, 288 __u8 index,
286 __u8 value) 289 __u8 value)
287{ 290{
288 int ret; 291 int ret;
289 292
293 if (gspca_dev->usb_err < 0)
294 return;
290 gspca_dev->usb_buf[0] = value; 295 gspca_dev->usb_buf[0] = value;
291 ret = usb_control_msg(gspca_dev->dev, 296 ret = usb_control_msg(gspca_dev->dev,
292 usb_sndctrlpipe(gspca_dev->dev, 0), 297 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -294,32 +299,32 @@ static int reg_w(struct gspca_dev *gspca_dev,
294 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 299 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
295 0, index, gspca_dev->usb_buf, 1, 300 0, index, gspca_dev->usb_buf, 1,
296 500); 301 500);
297 if (ret < 0) 302 if (ret < 0) {
298 PDEBUG(D_ERR, "reg_w(): " 303 PDEBUG(D_ERR, "reg_w(): "
299 "Failed to write register to index 0x%x, value 0x%x, error %i", 304 "Failed to write register to index 0x%x, value 0x%x, error %i",
300 index, value, ret); 305 index, value, ret);
301 return ret; 306 gspca_dev->usb_err = ret;
307 }
302} 308}
303 309
304static int reg_w_seq(struct gspca_dev *gspca_dev, 310static void reg_w_seq(struct gspca_dev *gspca_dev,
305 const __u8 *seq, int len) 311 const __u8 *seq, int len)
306{ 312{
307 int ret = 0;
308 while (--len >= 0) { 313 while (--len >= 0) {
309 if (0 <= ret) 314 reg_w(gspca_dev, seq[0], seq[1]);
310 ret = reg_w(gspca_dev, seq[0], seq[1]);
311 seq += 2; 315 seq += 2;
312 } 316 }
313 return ret;
314} 317}
315 318
316/* load the beginning of a page */ 319/* load the beginning of a page */
317static int reg_w_page(struct gspca_dev *gspca_dev, 320static void reg_w_page(struct gspca_dev *gspca_dev,
318 const __u8 *page, int len) 321 const __u8 *page, int len)
319{ 322{
320 int index; 323 int index;
321 int ret = 0; 324 int ret = 0;
322 325
326 if (gspca_dev->usb_err < 0)
327 return;
323 for (index = 0; index < len; index++) { 328 for (index = 0; index < len; index++) {
324 if (page[index] == SKIP) /* skip this index */ 329 if (page[index] == SKIP) /* skip this index */
325 continue; 330 continue;
@@ -335,56 +340,47 @@ static int reg_w_page(struct gspca_dev *gspca_dev,
335 "Failed to write register to index 0x%x, " 340 "Failed to write register to index 0x%x, "
336 "value 0x%x, error %i", 341 "value 0x%x, error %i",
337 index, page[index], ret); 342 index, page[index], ret);
343 gspca_dev->usb_err = ret;
338 break; 344 break;
339 } 345 }
340 } 346 }
341 return ret;
342} 347}
343 348
344/* output a variable sequence */ 349/* output a variable sequence */
345static int reg_w_var(struct gspca_dev *gspca_dev, 350static void reg_w_var(struct gspca_dev *gspca_dev,
346 const __u8 *seq, 351 const __u8 *seq,
347 const __u8 *page3, unsigned int page3_len,
348 const __u8 *page4, unsigned int page4_len) 352 const __u8 *page4, unsigned int page4_len)
349{ 353{
350 int index, len; 354 int index, len;
351 int ret = 0;
352 355
353 for (;;) { 356 for (;;) {
354 index = *seq++; 357 index = *seq++;
355 len = *seq++; 358 len = *seq++;
356 switch (len) { 359 switch (len) {
357 case END_OF_SEQUENCE: 360 case END_OF_SEQUENCE:
358 return ret; 361 return;
359 case LOAD_PAGE4: 362 case LOAD_PAGE4:
360 ret = reg_w_page(gspca_dev, page4, page4_len); 363 reg_w_page(gspca_dev, page4, page4_len);
361 break;
362 case LOAD_PAGE3:
363 ret = reg_w_page(gspca_dev, page3, page3_len);
364 break; 364 break;
365 default: 365 default:
366 if (len > USB_BUF_SZ) { 366 if (len > USB_BUF_SZ) {
367 PDEBUG(D_ERR|D_STREAM, 367 PDEBUG(D_ERR|D_STREAM,
368 "Incorrect variable sequence"); 368 "Incorrect variable sequence");
369 return -EINVAL; 369 return;
370 } 370 }
371 while (len > 0) { 371 while (len > 0) {
372 if (len < 8) { 372 if (len < 8) {
373 ret = reg_w_buf(gspca_dev, 373 reg_w_buf(gspca_dev,
374 index, seq, len); 374 index, seq, len);
375 if (ret < 0)
376 return ret;
377 seq += len; 375 seq += len;
378 break; 376 break;
379 } 377 }
380 ret = reg_w_buf(gspca_dev, index, seq, 8); 378 reg_w_buf(gspca_dev, index, seq, 8);
381 seq += 8; 379 seq += 8;
382 index += 8; 380 index += 8;
383 len -= 8; 381 len -= 8;
384 } 382 }
385 } 383 }
386 if (ret < 0)
387 return ret;
388 } 384 }
389 /* not reached */ 385 /* not reached */
390} 386}
@@ -412,46 +408,36 @@ static int sd_config(struct gspca_dev *gspca_dev,
412} 408}
413 409
414/* This function is used by pac7311 only */ 410/* This function is used by pac7311 only */
415static int setcontrast(struct gspca_dev *gspca_dev) 411static void setcontrast(struct gspca_dev *gspca_dev)
416{ 412{
417 struct sd *sd = (struct sd *) gspca_dev; 413 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
419 414
420 ret = reg_w(gspca_dev, 0xff, 0x04); 415 reg_w(gspca_dev, 0xff, 0x04);
421 if (0 <= ret) 416 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
422 ret = reg_w(gspca_dev, 0x10, sd->contrast >> 4);
423 /* load registers to sensor (Bit 0, auto clear) */ 417 /* load registers to sensor (Bit 0, auto clear) */
424 if (0 <= ret) 418 reg_w(gspca_dev, 0x11, 0x01);
425 ret = reg_w(gspca_dev, 0x11, 0x01);
426 return ret;
427} 419}
428 420
429static int setgain(struct gspca_dev *gspca_dev) 421static void setgain(struct gspca_dev *gspca_dev)
430{ 422{
431 struct sd *sd = (struct sd *) gspca_dev; 423 struct sd *sd = (struct sd *) gspca_dev;
432 int gain = GAIN_MAX - sd->gain; 424 int gain = GAIN_MAX - sd->gain;
433 int ret;
434 425
435 if (gain < 1) 426 if (gain < 1)
436 gain = 1; 427 gain = 1;
437 else if (gain > 245) 428 else if (gain > 245)
438 gain = 245; 429 gain = 245;
439 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 430 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
440 if (0 <= ret) 431 reg_w(gspca_dev, 0x0e, 0x00);
441 ret = reg_w(gspca_dev, 0x0e, 0x00); 432 reg_w(gspca_dev, 0x0f, gain);
442 if (0 <= ret)
443 ret = reg_w(gspca_dev, 0x0f, gain);
444 433
445 /* load registers to sensor (Bit 0, auto clear) */ 434 /* load registers to sensor (Bit 0, auto clear) */
446 if (0 <= ret) 435 reg_w(gspca_dev, 0x11, 0x01);
447 ret = reg_w(gspca_dev, 0x11, 0x01);
448 return ret;
449} 436}
450 437
451static int setexposure(struct gspca_dev *gspca_dev) 438static void setexposure(struct gspca_dev *gspca_dev)
452{ 439{
453 struct sd *sd = (struct sd *) gspca_dev; 440 struct sd *sd = (struct sd *) gspca_dev;
454 int ret;
455 __u8 reg; 441 __u8 reg;
456 442
457 /* register 2 of frame 3/4 contains the clock divider configuring the 443 /* register 2 of frame 3/4 contains the clock divider configuring the
@@ -463,94 +449,72 @@ static int setexposure(struct gspca_dev *gspca_dev)
463 else if (reg > 63) 449 else if (reg > 63)
464 reg = 63; 450 reg = 63;
465 451
466 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 452 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
467 if (0 <= ret) 453 reg_w(gspca_dev, 0x02, reg);
468 ret = reg_w(gspca_dev, 0x02, reg); 454
469 /* Page 1 register 8 must always be 0x08 except when not in 455 /* Page 1 register 8 must always be 0x08 except when not in
470 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ 456 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
471 if (0 <= ret) 457 reg_w(gspca_dev, 0xff, 0x01);
472 ret = reg_w(gspca_dev, 0xff, 0x01);
473 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && 458 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
474 reg <= 3) { 459 reg <= 3) {
475 if (0 <= ret) 460 reg_w(gspca_dev, 0x08, 0x09);
476 ret = reg_w(gspca_dev, 0x08, 0x09);
477 } else { 461 } else {
478 if (0 <= ret) 462 reg_w(gspca_dev, 0x08, 0x08);
479 ret = reg_w(gspca_dev, 0x08, 0x08);
480 } 463 }
481 464
482 /* load registers to sensor (Bit 0, auto clear) */ 465 /* load registers to sensor (Bit 0, auto clear) */
483 if (0 <= ret) 466 reg_w(gspca_dev, 0x11, 0x01);
484 ret = reg_w(gspca_dev, 0x11, 0x01);
485 return ret;
486} 467}
487 468
488static int sethvflip(struct gspca_dev *gspca_dev) 469static void sethvflip(struct gspca_dev *gspca_dev)
489{ 470{
490 struct sd *sd = (struct sd *) gspca_dev; 471 struct sd *sd = (struct sd *) gspca_dev;
491 int ret;
492 __u8 data; 472 __u8 data;
493 473
494 ret = reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 474 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
495 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); 475 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
496 if (0 <= ret) 476 reg_w(gspca_dev, 0x21, data);
497 ret = reg_w(gspca_dev, 0x21, data); 477
498 /* load registers to sensor (Bit 0, auto clear) */ 478 /* load registers to sensor (Bit 0, auto clear) */
499 if (0 <= ret) 479 reg_w(gspca_dev, 0x11, 0x01);
500 ret = reg_w(gspca_dev, 0x11, 0x01);
501 return ret;
502} 480}
503 481
504/* this function is called at probe and resume time for pac7311 */ 482/* this function is called at probe and resume time for pac7311 */
505static int sd_init(struct gspca_dev *gspca_dev) 483static int sd_init(struct gspca_dev *gspca_dev)
506{ 484{
507 return reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2); 485 reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
486 return gspca_dev->usb_err;
508} 487}
509 488
510static int sd_start(struct gspca_dev *gspca_dev) 489static int sd_start(struct gspca_dev *gspca_dev)
511{ 490{
512 struct sd *sd = (struct sd *) gspca_dev; 491 struct sd *sd = (struct sd *) gspca_dev;
513 int ret;
514 492
515 sd->sof_read = 0; 493 sd->sof_read = 0;
516 494
517 ret = reg_w_var(gspca_dev, start_7311, 495 reg_w_var(gspca_dev, start_7311,
518 NULL, 0,
519 page4_7311, sizeof(page4_7311)); 496 page4_7311, sizeof(page4_7311));
520 if (0 <= ret) 497 setcontrast(gspca_dev);
521 ret = setcontrast(gspca_dev); 498 setgain(gspca_dev);
522 if (0 <= ret) 499 setexposure(gspca_dev);
523 ret = setgain(gspca_dev); 500 sethvflip(gspca_dev);
524 if (0 <= ret)
525 ret = setexposure(gspca_dev);
526 if (0 <= ret)
527 ret = sethvflip(gspca_dev);
528 501
529 /* set correct resolution */ 502 /* set correct resolution */
530 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 503 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
531 case 2: /* 160x120 pac7311 */ 504 case 2: /* 160x120 pac7311 */
532 if (0 <= ret) 505 reg_w(gspca_dev, 0xff, 0x01);
533 ret = reg_w(gspca_dev, 0xff, 0x01); 506 reg_w(gspca_dev, 0x17, 0x20);
534 if (0 <= ret) 507 reg_w(gspca_dev, 0x87, 0x10);
535 ret = reg_w(gspca_dev, 0x17, 0x20);
536 if (0 <= ret)
537 ret = reg_w(gspca_dev, 0x87, 0x10);
538 break; 508 break;
539 case 1: /* 320x240 pac7311 */ 509 case 1: /* 320x240 pac7311 */
540 if (0 <= ret) 510 reg_w(gspca_dev, 0xff, 0x01);
541 ret = reg_w(gspca_dev, 0xff, 0x01); 511 reg_w(gspca_dev, 0x17, 0x30);
542 if (0 <= ret) 512 reg_w(gspca_dev, 0x87, 0x11);
543 ret = reg_w(gspca_dev, 0x17, 0x30);
544 if (0 <= ret)
545 ret = reg_w(gspca_dev, 0x87, 0x11);
546 break; 513 break;
547 case 0: /* 640x480 */ 514 case 0: /* 640x480 */
548 if (0 <= ret) 515 reg_w(gspca_dev, 0xff, 0x01);
549 ret = reg_w(gspca_dev, 0xff, 0x01); 516 reg_w(gspca_dev, 0x17, 0x00);
550 if (0 <= ret) 517 reg_w(gspca_dev, 0x87, 0x12);
551 ret = reg_w(gspca_dev, 0x17, 0x00);
552 if (0 <= ret)
553 ret = reg_w(gspca_dev, 0x87, 0x12);
554 break; 518 break;
555 } 519 }
556 520
@@ -559,37 +523,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
559 atomic_set(&sd->avg_lum, -1); 523 atomic_set(&sd->avg_lum, -1);
560 524
561 /* start stream */ 525 /* start stream */
562 if (0 <= ret) 526 reg_w(gspca_dev, 0xff, 0x01);
563 ret = reg_w(gspca_dev, 0xff, 0x01); 527 reg_w(gspca_dev, 0x78, 0x05);
564 if (0 <= ret)
565 ret = reg_w(gspca_dev, 0x78, 0x05);
566 528
567 return ret; 529 return gspca_dev->usb_err;
568} 530}
569 531
570static void sd_stopN(struct gspca_dev *gspca_dev) 532static void sd_stopN(struct gspca_dev *gspca_dev)
571{ 533{
572 int ret; 534 reg_w(gspca_dev, 0xff, 0x04);
573 535 reg_w(gspca_dev, 0x27, 0x80);
574 ret = reg_w(gspca_dev, 0xff, 0x04); 536 reg_w(gspca_dev, 0x28, 0xca);
575 if (0 <= ret) 537 reg_w(gspca_dev, 0x29, 0x53);
576 ret = reg_w(gspca_dev, 0x27, 0x80); 538 reg_w(gspca_dev, 0x2a, 0x0e);
577 if (0 <= ret) 539 reg_w(gspca_dev, 0xff, 0x01);
578 ret = reg_w(gspca_dev, 0x28, 0xca); 540 reg_w(gspca_dev, 0x3e, 0x20);
579 if (0 <= ret) 541 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
580 ret = reg_w(gspca_dev, 0x29, 0x53); 542 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
581 if (0 <= ret) 543 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
582 ret = reg_w(gspca_dev, 0x2a, 0x0e);
583 if (0 <= ret)
584 ret = reg_w(gspca_dev, 0xff, 0x01);
585 if (0 <= ret)
586 ret = reg_w(gspca_dev, 0x3e, 0x20);
587 if (0 <= ret)
588 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
589 if (0 <= ret)
590 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
591 if (0 <= ret)
592 ret = reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
593} 544}
594 545
595/* called on streamoff with alt 0 and on disconnect for 7311 */ 546/* called on streamoff with alt 0 and on disconnect for 7311 */
@@ -734,7 +685,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
734 if (gspca_dev->streaming) { 685 if (gspca_dev->streaming) {
735 setcontrast(gspca_dev); 686 setcontrast(gspca_dev);
736 } 687 }
737 return 0; 688 return gspca_dev->usb_err;
738} 689}
739 690
740static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 691static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -752,7 +703,7 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
752 sd->gain = val; 703 sd->gain = val;
753 if (gspca_dev->streaming) 704 if (gspca_dev->streaming)
754 setgain(gspca_dev); 705 setgain(gspca_dev);
755 return 0; 706 return gspca_dev->usb_err;
756} 707}
757 708
758static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 709static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -770,7 +721,7 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
770 sd->exposure = val; 721 sd->exposure = val;
771 if (gspca_dev->streaming) 722 if (gspca_dev->streaming)
772 setexposure(gspca_dev); 723 setexposure(gspca_dev);
773 return 0; 724 return gspca_dev->usb_err;
774} 725}
775 726
776static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 727static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
@@ -801,7 +752,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
801 } 752 }
802 } 753 }
803 754
804 return 0; 755 return gspca_dev->usb_err;
805} 756}
806 757
807static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 758static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
@@ -819,7 +770,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
819 sd->hflip = val; 770 sd->hflip = val;
820 if (gspca_dev->streaming) 771 if (gspca_dev->streaming)
821 sethvflip(gspca_dev); 772 sethvflip(gspca_dev);
822 return 0; 773 return gspca_dev->usb_err;
823} 774}
824 775
825static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 776static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -837,7 +788,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
837 sd->vflip = val; 788 sd->vflip = val;
838 if (gspca_dev->streaming) 789 if (gspca_dev->streaming)
839 sethvflip(gspca_dev); 790 sethvflip(gspca_dev);
840 return 0; 791 return gspca_dev->usb_err;
841} 792}
842 793
843static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 794static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -848,8 +799,39 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
848 return 0; 799 return 0;
849} 800}
850 801
802#ifdef CONFIG_INPUT
803static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
804 u8 *data, /* interrupt packet data */
805 int len) /* interrupt packet length */
806{
807 int ret = -EINVAL;
808 u8 data0, data1;
809
810 if (len == 2) {
811 data0 = data[0];
812 data1 = data[1];
813 if ((data0 == 0x00 && data1 == 0x11) ||
814 (data0 == 0x22 && data1 == 0x33) ||
815 (data0 == 0x44 && data1 == 0x55) ||
816 (data0 == 0x66 && data1 == 0x77) ||
817 (data0 == 0x88 && data1 == 0x99) ||
818 (data0 == 0xaa && data1 == 0xbb) ||
819 (data0 == 0xcc && data1 == 0xdd) ||
820 (data0 == 0xee && data1 == 0xff)) {
821 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
822 input_sync(gspca_dev->input_dev);
823 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
824 input_sync(gspca_dev->input_dev);
825 ret = 0;
826 }
827 }
828
829 return ret;
830}
831#endif
832
851/* sub-driver description for pac7311 */ 833/* sub-driver description for pac7311 */
852static struct sd_desc sd_desc = { 834static const struct sd_desc sd_desc = {
853 .name = MODULE_NAME, 835 .name = MODULE_NAME,
854 .ctrls = sd_ctrls, 836 .ctrls = sd_ctrls,
855 .nctrls = ARRAY_SIZE(sd_ctrls), 837 .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -860,6 +842,9 @@ static struct sd_desc sd_desc = {
860 .stop0 = sd_stop0, 842 .stop0 = sd_stop0,
861 .pkt_scan = sd_pkt_scan, 843 .pkt_scan = sd_pkt_scan,
862 .dq_callback = do_autogain, 844 .dq_callback = do_autogain,
845#ifdef CONFIG_INPUT
846 .int_pkt_scan = sd_int_pkt_scan,
847#endif
863}; 848};
864 849
865/* -- module initialisation -- */ 850/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
index 20f67d9b8c06..8462a7c1a338 100644
--- a/drivers/media/video/gspca/pac_common.h
+++ b/drivers/media/video/gspca/pac_common.h
@@ -24,11 +24,10 @@
24 */ 24 */
25 25
26/* We calculate the autogain at the end of the transfer of a frame, at this 26/* We calculate the autogain at the end of the transfer of a frame, at this
27 moment a frame with the old settings is being transmitted, and a frame is 27 moment a frame with the old settings is being captured and transmitted. So
28 being captured with the old settings. So if we adjust the autogain we must 28 if we adjust the gain or exposure we must ignore atleast the next frame for
29 ignore atleast the 2 next frames for the new settings to come into effect 29 the new settings to come into effect before doing any other adjustments. */
30 before doing any other adjustments */ 30#define PAC_AUTOGAIN_IGNORE_FRAMES 2
31#define PAC_AUTOGAIN_IGNORE_FRAMES 3
32 31
33static const unsigned char pac_sof_marker[5] = 32static const unsigned char pac_sof_marker[5] =
34 { 0xff, 0xff, 0x00, 0xff, 0x96 }; 33 { 0xff, 0xff, 0x00, 0xff, 0x96 };
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c
new file mode 100644
index 000000000000..dda5fd4aa69e
--- /dev/null
+++ b/drivers/media/video/gspca/sn9c2028.c
@@ -0,0 +1,757 @@
1/*
2 * SN9C2028 library
3 *
4 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
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 * 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#define MODULE_NAME "sn9c2028"
22
23#include "gspca.h"
24
25MODULE_AUTHOR("Theodore Kilgore");
26MODULE_DESCRIPTION("Sonix SN9C2028 USB Camera Driver");
27MODULE_LICENSE("GPL");
28
29/* specific webcam descriptor */
30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 u8 sof_read;
33 u16 model;
34};
35
36struct init_command {
37 unsigned char instruction[6];
38 unsigned char to_read; /* length to read. 0 means no reply requested */
39};
40
41/* V4L2 controls supported by the driver */
42static struct ctrl sd_ctrls[] = {
43};
44
45/* How to change the resolution of any of the VGA cams is unknown */
46static const struct v4l2_pix_format vga_mode[] = {
47 {640, 480, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
48 .bytesperline = 640,
49 .sizeimage = 640 * 480 * 3 / 4,
50 .colorspace = V4L2_COLORSPACE_SRGB,
51 .priv = 0},
52};
53
54/* No way to change the resolution of the CIF cams is known */
55static const struct v4l2_pix_format cif_mode[] = {
56 {352, 288, V4L2_PIX_FMT_SN9C2028, V4L2_FIELD_NONE,
57 .bytesperline = 352,
58 .sizeimage = 352 * 288 * 3 / 4,
59 .colorspace = V4L2_COLORSPACE_SRGB,
60 .priv = 0},
61};
62
63/* the bytes to write are in gspca_dev->usb_buf */
64static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
65{
66 int rc;
67
68 PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0],
69 command[1], command[2], command[3], command[4], command[5]);
70
71 memcpy(gspca_dev->usb_buf, command, 6);
72 rc = usb_control_msg(gspca_dev->dev,
73 usb_sndctrlpipe(gspca_dev->dev, 0),
74 USB_REQ_GET_CONFIGURATION,
75 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
76 2, 0, gspca_dev->usb_buf, 6, 500);
77 if (rc < 0) {
78 PDEBUG(D_ERR, "command write [%02x] error %d",
79 gspca_dev->usb_buf[0], rc);
80 return rc;
81 }
82
83 return 0;
84}
85
86static int sn9c2028_read1(struct gspca_dev *gspca_dev)
87{
88 int rc;
89
90 rc = usb_control_msg(gspca_dev->dev,
91 usb_rcvctrlpipe(gspca_dev->dev, 0),
92 USB_REQ_GET_STATUS,
93 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
94 1, 0, gspca_dev->usb_buf, 1, 500);
95 if (rc != 1) {
96 PDEBUG(D_ERR, "read1 error %d", rc);
97 return (rc < 0) ? rc : -EIO;
98 }
99 PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]);
100 return gspca_dev->usb_buf[0];
101}
102
103static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
104{
105 int rc;
106 rc = usb_control_msg(gspca_dev->dev,
107 usb_rcvctrlpipe(gspca_dev->dev, 0),
108 USB_REQ_GET_STATUS,
109 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
110 4, 0, gspca_dev->usb_buf, 4, 500);
111 if (rc != 4) {
112 PDEBUG(D_ERR, "read4 error %d", rc);
113 return (rc < 0) ? rc : -EIO;
114 }
115 memcpy(reading, gspca_dev->usb_buf, 4);
116 PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0],
117 reading[1], reading[2], reading[3]);
118 return rc;
119}
120
121static int sn9c2028_long_command(struct gspca_dev *gspca_dev, u8 *command)
122{
123 int i, status;
124 __u8 reading[4];
125
126 status = sn9c2028_command(gspca_dev, command);
127 if (status < 0)
128 return status;
129
130 status = -1;
131 for (i = 0; i < 256 && status < 2; i++)
132 status = sn9c2028_read1(gspca_dev);
133 if (status != 2) {
134 PDEBUG(D_ERR, "long command status read error %d", status);
135 return (status < 0) ? status : -EIO;
136 }
137
138 memset(reading, 0, 4);
139 status = sn9c2028_read4(gspca_dev, reading);
140 if (status < 0)
141 return status;
142
143 /* in general, the first byte of the response is the first byte of
144 * the command, or'ed with 8 */
145 status = sn9c2028_read1(gspca_dev);
146 if (status < 0)
147 return status;
148
149 return 0;
150}
151
152static int sn9c2028_short_command(struct gspca_dev *gspca_dev, u8 *command)
153{
154 int err_code;
155
156 err_code = sn9c2028_command(gspca_dev, command);
157 if (err_code < 0)
158 return err_code;
159
160 err_code = sn9c2028_read1(gspca_dev);
161 if (err_code < 0)
162 return err_code;
163
164 return 0;
165}
166
167/* this function is called at probe time */
168static int sd_config(struct gspca_dev *gspca_dev,
169 const struct usb_device_id *id)
170{
171 struct sd *sd = (struct sd *) gspca_dev;
172 struct cam *cam = &gspca_dev->cam;
173
174 PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)",
175 id->idVendor, id->idProduct);
176
177 sd->model = id->idProduct;
178
179 switch (sd->model) {
180 case 0x7005:
181 PDEBUG(D_PROBE, "Genius Smart 300 camera");
182 break;
183 case 0x8000:
184 PDEBUG(D_PROBE, "DC31VC");
185 break;
186 case 0x8001:
187 PDEBUG(D_PROBE, "Spy camera");
188 break;
189 case 0x8003:
190 PDEBUG(D_PROBE, "CIF camera");
191 break;
192 case 0x8008:
193 PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera");
194 break;
195 case 0x800a:
196 PDEBUG(D_PROBE, "Vivitar 3350b type camera");
197 cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
198 break;
199 }
200
201 switch (sd->model) {
202 case 0x8000:
203 case 0x8001:
204 case 0x8003:
205 cam->cam_mode = cif_mode;
206 cam->nmodes = ARRAY_SIZE(cif_mode);
207 break;
208 default:
209 cam->cam_mode = vga_mode;
210 cam->nmodes = ARRAY_SIZE(vga_mode);
211 }
212 return 0;
213}
214
215/* this function is called at probe and resume time */
216static int sd_init(struct gspca_dev *gspca_dev)
217{
218 int status = -1;
219
220 sn9c2028_read1(gspca_dev);
221 sn9c2028_read1(gspca_dev);
222 status = sn9c2028_read1(gspca_dev);
223
224 return (status < 0) ? status : 0;
225}
226
227static int run_start_commands(struct gspca_dev *gspca_dev,
228 struct init_command *cam_commands, int n)
229{
230 int i, err_code = -1;
231
232 for (i = 0; i < n; i++) {
233 switch (cam_commands[i].to_read) {
234 case 4:
235 err_code = sn9c2028_long_command(gspca_dev,
236 cam_commands[i].instruction);
237 break;
238 case 1:
239 err_code = sn9c2028_short_command(gspca_dev,
240 cam_commands[i].instruction);
241 break;
242 case 0:
243 err_code = sn9c2028_command(gspca_dev,
244 cam_commands[i].instruction);
245 break;
246 }
247 if (err_code < 0)
248 return err_code;
249 }
250 return 0;
251}
252
253static int start_spy_cam(struct gspca_dev *gspca_dev)
254{
255 struct init_command spy_start_commands[] = {
256 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
257 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
258 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
259 {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
260 {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
261 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
262 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, /* width 352 */
263 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, /* height 288 */
264 /* {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4}, */
265 {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4},
266 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* red gain ?*/
267 /* {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4}, */
268 {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
269 /* {{0x13, 0x29, 0x01, 0x0c, 0x00, 0x00}, 4}, */
270 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
271 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
272 /* {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4}, */
273 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
274 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
275 /* {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4}, */
276 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
277 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
278 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
279 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
280 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
281 {{0x11, 0x02, 0x06, 0x00, 0x00, 0x00}, 4},
282 {{0x11, 0x03, 0x13, 0x00, 0x00, 0x00}, 4}, /*don't mess with*/
283 /*{{0x11, 0x04, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
284 {{0x11, 0x04, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
285 /*{{0x11, 0x05, 0x65, 0x00, 0x00, 0x00}, 4}, observed */
286 {{0x11, 0x05, 0x00, 0x00, 0x00, 0x00}, 4}, /* brighter */
287 {{0x11, 0x06, 0xb1, 0x00, 0x00, 0x00}, 4}, /* observed */
288 {{0x11, 0x07, 0x00, 0x00, 0x00, 0x00}, 4},
289 /*{{0x11, 0x08, 0x06, 0x00, 0x00, 0x00}, 4}, observed */
290 {{0x11, 0x08, 0x0b, 0x00, 0x00, 0x00}, 4},
291 {{0x11, 0x09, 0x01, 0x00, 0x00, 0x00}, 4},
292 {{0x11, 0x0a, 0x01, 0x00, 0x00, 0x00}, 4},
293 {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
294 {{0x11, 0x0c, 0x01, 0x00, 0x00, 0x00}, 4},
295 {{0x11, 0x0d, 0x00, 0x00, 0x00, 0x00}, 4},
296 {{0x11, 0x0e, 0x04, 0x00, 0x00, 0x00}, 4},
297 /* {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4}, */
298 /* brightness or gain. 0 is default. 4 is good
299 * indoors at night with incandescent lighting */
300 {{0x11, 0x0f, 0x04, 0x00, 0x00, 0x00}, 4},
301 {{0x11, 0x10, 0x06, 0x00, 0x00, 0x00}, 4}, /*hstart or hoffs*/
302 {{0x11, 0x11, 0x06, 0x00, 0x00, 0x00}, 4},
303 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
304 {{0x11, 0x14, 0x02, 0x00, 0x00, 0x00}, 4},
305 {{0x11, 0x13, 0x01, 0x00, 0x00, 0x00}, 4},
306 /* {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1}, observed */
307 {{0x1b, 0x02, 0x11, 0x00, 0x00, 0x00}, 1}, /* brighter */
308 /* {{0x1b, 0x13, 0x01, 0x00, 0x00, 0x00}, 1}, observed */
309 {{0x1b, 0x13, 0x11, 0x00, 0x00, 0x00}, 1},
310 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}, /* compresses */
311 /* Camera should start to capture now. */
312 };
313
314 return run_start_commands(gspca_dev, spy_start_commands,
315 ARRAY_SIZE(spy_start_commands));
316}
317
318static int start_cif_cam(struct gspca_dev *gspca_dev)
319{
320 struct init_command cif_start_commands[] = {
321 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
322 /* The entire sequence below seems redundant */
323 /* {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
324 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
325 {{0x13, 0x22, 0x01, 0x06, 0x00, 0x00}, 4},
326 {{0x13, 0x23, 0x01, 0x02, 0x00, 0x00}, 4},
327 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
328 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4}, width?
329 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4}, height?
330 {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
331 {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
332 {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
333 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
334 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
335 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
336 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
337 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
338 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
339 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
340 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
341 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},*/
342 {{0x1b, 0x21, 0x00, 0x00, 0x00, 0x00}, 1},
343 {{0x1b, 0x17, 0x00, 0x00, 0x00, 0x00}, 1},
344 {{0x1b, 0x19, 0x00, 0x00, 0x00, 0x00}, 1},
345 {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
346 {{0x1b, 0x03, 0x5a, 0x00, 0x00, 0x00}, 1},
347 {{0x1b, 0x04, 0x27, 0x00, 0x00, 0x00}, 1},
348 {{0x1b, 0x05, 0x01, 0x00, 0x00, 0x00}, 1},
349 {{0x1b, 0x12, 0x14, 0x00, 0x00, 0x00}, 1},
350 {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
351 {{0x1b, 0x14, 0x00, 0x00, 0x00, 0x00}, 1},
352 {{0x1b, 0x15, 0x00, 0x00, 0x00, 0x00}, 1},
353 {{0x1b, 0x16, 0x00, 0x00, 0x00, 0x00}, 1},
354 {{0x1b, 0x77, 0xa2, 0x00, 0x00, 0x00}, 1},
355 {{0x1b, 0x06, 0x0f, 0x00, 0x00, 0x00}, 1},
356 {{0x1b, 0x07, 0x14, 0x00, 0x00, 0x00}, 1},
357 {{0x1b, 0x08, 0x0f, 0x00, 0x00, 0x00}, 1},
358 {{0x1b, 0x09, 0x10, 0x00, 0x00, 0x00}, 1},
359 {{0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00}, 1},
360 {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
361 {{0x1b, 0x12, 0x07, 0x00, 0x00, 0x00}, 1},
362 {{0x1b, 0x10, 0x1f, 0x00, 0x00, 0x00}, 1},
363 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
364 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 1}, /* width/8 */
365 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 1}, /* height/8 */
366 /* {{0x13, 0x27, 0x01, 0x68, 0x00, 0x00}, 4}, subsample?
367 * {{0x13, 0x28, 0x01, 0x1e, 0x00, 0x00}, 4}, does nothing
368 * {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4}, */
369 /* {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
370 * causes subsampling
371 * but not a change in the resolution setting! */
372 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
373 {{0x13, 0x2d, 0x01, 0x01, 0x00, 0x00}, 4},
374 {{0x13, 0x2e, 0x01, 0x08, 0x00, 0x00}, 4},
375 {{0x13, 0x2f, 0x01, 0x06, 0x00, 0x00}, 4},
376 {{0x13, 0x28, 0x01, 0x00, 0x00, 0x00}, 4},
377 {{0x1b, 0x04, 0x6d, 0x00, 0x00, 0x00}, 1},
378 {{0x1b, 0x05, 0x03, 0x00, 0x00, 0x00}, 1},
379 {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
380 {{0x1b, 0x0e, 0x01, 0x00, 0x00, 0x00}, 1},
381 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
382 {{0x1b, 0x0f, 0x00, 0x00, 0x00, 0x00}, 1},
383 {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
384 {{0x1b, 0x10, 0x0f, 0x00, 0x00, 0x00}, 1},
385 {{0x1b, 0x02, 0x06, 0x00, 0x00, 0x00}, 1},
386 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
387 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1},/* use compression */
388 /* Camera should start to capture now. */
389 };
390
391 return run_start_commands(gspca_dev, cif_start_commands,
392 ARRAY_SIZE(cif_start_commands));
393}
394
395static int start_ms350_cam(struct gspca_dev *gspca_dev)
396{
397 struct init_command ms350_start_commands[] = {
398 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
399 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
400 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
401 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
402 {{0x13, 0x22, 0x01, 0x04, 0x00, 0x00}, 4},
403 {{0x13, 0x23, 0x01, 0x03, 0x00, 0x00}, 4},
404 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
405 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
406 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
407 {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
408 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4},
409 {{0x13, 0x29, 0x01, 0x00, 0x00, 0x00}, 4},
410 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
411 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
412 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
413 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
414 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
415 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
416 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
417 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
418 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
419 {{0x11, 0x00, 0x01, 0x00, 0x00, 0x00}, 4},
420 {{0x11, 0x01, 0x70, 0x00, 0x00, 0x00}, 4},
421 {{0x11, 0x02, 0x05, 0x00, 0x00, 0x00}, 4},
422 {{0x11, 0x03, 0x5d, 0x00, 0x00, 0x00}, 4},
423 {{0x11, 0x04, 0x07, 0x00, 0x00, 0x00}, 4},
424 {{0x11, 0x05, 0x25, 0x00, 0x00, 0x00}, 4},
425 {{0x11, 0x06, 0x00, 0x00, 0x00, 0x00}, 4},
426 {{0x11, 0x07, 0x09, 0x00, 0x00, 0x00}, 4},
427 {{0x11, 0x08, 0x01, 0x00, 0x00, 0x00}, 4},
428 {{0x11, 0x09, 0x00, 0x00, 0x00, 0x00}, 4},
429 {{0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, 4},
430 {{0x11, 0x0b, 0x01, 0x00, 0x00, 0x00}, 4},
431 {{0x11, 0x0c, 0x00, 0x00, 0x00, 0x00}, 4},
432 {{0x11, 0x0d, 0x0c, 0x00, 0x00, 0x00}, 4},
433 {{0x11, 0x0e, 0x01, 0x00, 0x00, 0x00}, 4},
434 {{0x11, 0x0f, 0x00, 0x00, 0x00, 0x00}, 4},
435 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
436 {{0x11, 0x11, 0x00, 0x00, 0x00, 0x00}, 4},
437 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
438 {{0x11, 0x13, 0x63, 0x00, 0x00, 0x00}, 4},
439 {{0x11, 0x15, 0x70, 0x00, 0x00, 0x00}, 4},
440 {{0x11, 0x18, 0x00, 0x00, 0x00, 0x00}, 4},
441 {{0x11, 0x11, 0x01, 0x00, 0x00, 0x00}, 4},
442 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* width */
443 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* height */
444 {{0x13, 0x28, 0x01, 0x09, 0x00, 0x00}, 4}, /* vstart? */
445 {{0x13, 0x27, 0x01, 0x28, 0x00, 0x00}, 4},
446 {{0x13, 0x29, 0x01, 0x40, 0x00, 0x00}, 4}, /* hstart? */
447 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
448 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
449 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
450 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
451 {{0x1b, 0x02, 0x05, 0x00, 0x00, 0x00}, 1},
452 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 1},
453 {{0x20, 0x18, 0x00, 0x00, 0x00, 0x00}, 1},
454 {{0x1b, 0x02, 0x0a, 0x00, 0x00, 0x00}, 1},
455 {{0x1b, 0x11, 0x01, 0x00, 0x00, 0x00}, 0},
456 /* Camera should start to capture now. */
457 };
458
459 return run_start_commands(gspca_dev, ms350_start_commands,
460 ARRAY_SIZE(ms350_start_commands));
461}
462
463static int start_genius_cam(struct gspca_dev *gspca_dev)
464{
465 struct init_command genius_start_commands[] = {
466 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
467 {{0x16, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
468 {{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, 4},
469 {{0x13, 0x25, 0x01, 0x16, 0x00, 0x00}, 4},
470 {{0x13, 0x26, 0x01, 0x12, 0x00, 0x00}, 4},
471 /* "preliminary" width and height settings */
472 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
473 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
474 {{0x13, 0x29, 0x01, 0x22, 0x00, 0x00}, 4},
475 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
476 {{0x13, 0x2d, 0x01, 0x02, 0x00, 0x00}, 4},
477 {{0x13, 0x2e, 0x01, 0x09, 0x00, 0x00}, 4},
478 {{0x13, 0x2f, 0x01, 0x07, 0x00, 0x00}, 4},
479 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
480 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
481 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
482 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
483 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
484 {{0x11, 0x11, 0x64, 0x00, 0x00, 0x00}, 4},
485 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
486 {{0x11, 0x13, 0x91, 0x00, 0x00, 0x00}, 4},
487 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
488 {{0x11, 0x15, 0x20, 0x00, 0x00, 0x00}, 4},
489 {{0x11, 0x16, 0x01, 0x00, 0x00, 0x00}, 4},
490 {{0x11, 0x17, 0x60, 0x00, 0x00, 0x00}, 4},
491 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
492 {{0x11, 0x21, 0x2d, 0x00, 0x00, 0x00}, 4},
493 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
494 {{0x11, 0x23, 0x03, 0x00, 0x00, 0x00}, 4},
495 {{0x11, 0x25, 0x00, 0x00, 0x00, 0x00}, 4},
496 {{0x11, 0x26, 0x02, 0x00, 0x00, 0x00}, 4},
497 {{0x11, 0x27, 0x88, 0x00, 0x00, 0x00}, 4},
498 {{0x11, 0x30, 0x38, 0x00, 0x00, 0x00}, 4},
499 {{0x11, 0x31, 0x2a, 0x00, 0x00, 0x00}, 4},
500 {{0x11, 0x32, 0x2a, 0x00, 0x00, 0x00}, 4},
501 {{0x11, 0x33, 0x2a, 0x00, 0x00, 0x00}, 4},
502 {{0x11, 0x34, 0x02, 0x00, 0x00, 0x00}, 4},
503 {{0x11, 0x5b, 0x0a, 0x00, 0x00, 0x00}, 4},
504 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4}, /* real width */
505 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4}, /* real height */
506 {{0x13, 0x28, 0x01, 0x0e, 0x00, 0x00}, 4},
507 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
508 {{0x13, 0x29, 0x01, 0x62, 0x00, 0x00}, 4},
509 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
510 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
511 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
512 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
513 {{0x11, 0x20, 0x00, 0x00, 0x00, 0x00}, 4},
514 {{0x11, 0x21, 0x2a, 0x00, 0x00, 0x00}, 4},
515 {{0x11, 0x22, 0x00, 0x00, 0x00, 0x00}, 4},
516 {{0x11, 0x23, 0x28, 0x00, 0x00, 0x00}, 4},
517 {{0x11, 0x10, 0x00, 0x00, 0x00, 0x00}, 4},
518 {{0x11, 0x11, 0x04, 0x00, 0x00, 0x00}, 4},
519 {{0x11, 0x12, 0x00, 0x00, 0x00, 0x00}, 4},
520 {{0x11, 0x13, 0x03, 0x00, 0x00, 0x00}, 4},
521 {{0x11, 0x14, 0x01, 0x00, 0x00, 0x00}, 4},
522 {{0x11, 0x15, 0xe0, 0x00, 0x00, 0x00}, 4},
523 {{0x11, 0x16, 0x02, 0x00, 0x00, 0x00}, 4},
524 {{0x11, 0x17, 0x80, 0x00, 0x00, 0x00}, 4},
525 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
526 {{0x1c, 0x20, 0x00, 0x2a, 0x00, 0x00}, 1},
527 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 0}
528 /* Camera should start to capture now. */
529 };
530
531 return run_start_commands(gspca_dev, genius_start_commands,
532 ARRAY_SIZE(genius_start_commands));
533}
534
535static int start_vivitar_cam(struct gspca_dev *gspca_dev)
536{
537 struct init_command vivitar_start_commands[] = {
538 {{0x0c, 0x01, 0x00, 0x00, 0x00, 0x00}, 4},
539 {{0x13, 0x20, 0x01, 0x00, 0x00, 0x00}, 4},
540 {{0x13, 0x21, 0x01, 0x00, 0x00, 0x00}, 4},
541 {{0x13, 0x22, 0x01, 0x01, 0x00, 0x00}, 4},
542 {{0x13, 0x23, 0x01, 0x01, 0x00, 0x00}, 4},
543 {{0x13, 0x24, 0x01, 0x00, 0x00, 0x00}, 4},
544 {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
545 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
546 {{0x13, 0x27, 0x01, 0x20, 0x00, 0x00}, 4},
547 {{0x13, 0x28, 0x01, 0x0a, 0x00, 0x00}, 4},
548 /*
549 * Above is changed from OEM 0x0b. Fixes Bayer tiling.
550 * Presumably gives a vertical shift of one row.
551 */
552 {{0x13, 0x29, 0x01, 0x20, 0x00, 0x00}, 4},
553 /* Above seems to do horizontal shift. */
554 {{0x13, 0x2a, 0x01, 0x00, 0x00, 0x00}, 4},
555 {{0x13, 0x2b, 0x01, 0x00, 0x00, 0x00}, 4},
556 {{0x13, 0x2c, 0x01, 0x02, 0x00, 0x00}, 4},
557 {{0x13, 0x2d, 0x01, 0x03, 0x00, 0x00}, 4},
558 {{0x13, 0x2e, 0x01, 0x0f, 0x00, 0x00}, 4},
559 {{0x13, 0x2f, 0x01, 0x0c, 0x00, 0x00}, 4},
560 /* Above three commands seem to relate to brightness. */
561 {{0x12, 0x34, 0x01, 0x00, 0x00, 0x00}, 4},
562 {{0x13, 0x34, 0x01, 0xa1, 0x00, 0x00}, 4},
563 {{0x13, 0x35, 0x01, 0x00, 0x00, 0x00}, 4},
564 {{0x1b, 0x12, 0x80, 0x00, 0x00, 0x00}, 1},
565 {{0x1b, 0x01, 0x77, 0x00, 0x00, 0x00}, 1},
566 {{0x1b, 0x02, 0x3a, 0x00, 0x00, 0x00}, 1},
567 {{0x1b, 0x12, 0x78, 0x00, 0x00, 0x00}, 1},
568 {{0x1b, 0x13, 0x00, 0x00, 0x00, 0x00}, 1},
569 {{0x1b, 0x14, 0x80, 0x00, 0x00, 0x00}, 1},
570 {{0x1b, 0x15, 0x34, 0x00, 0x00, 0x00}, 1},
571 {{0x1b, 0x1b, 0x04, 0x00, 0x00, 0x00}, 1},
572 {{0x1b, 0x20, 0x44, 0x00, 0x00, 0x00}, 1},
573 {{0x1b, 0x23, 0xee, 0x00, 0x00, 0x00}, 1},
574 {{0x1b, 0x26, 0xa0, 0x00, 0x00, 0x00}, 1},
575 {{0x1b, 0x27, 0x9a, 0x00, 0x00, 0x00}, 1},
576 {{0x1b, 0x28, 0xa0, 0x00, 0x00, 0x00}, 1},
577 {{0x1b, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
578 {{0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00}, 1},
579 {{0x1b, 0x2b, 0x00, 0x00, 0x00, 0x00}, 1},
580 {{0x1b, 0x2f, 0x3d, 0x00, 0x00, 0x00}, 1},
581 {{0x1b, 0x30, 0x24, 0x00, 0x00, 0x00}, 1},
582 {{0x1b, 0x32, 0x86, 0x00, 0x00, 0x00}, 1},
583 {{0x1b, 0x60, 0xa9, 0x00, 0x00, 0x00}, 1},
584 {{0x1b, 0x61, 0x42, 0x00, 0x00, 0x00}, 1},
585 {{0x1b, 0x65, 0x00, 0x00, 0x00, 0x00}, 1},
586 {{0x1b, 0x69, 0x38, 0x00, 0x00, 0x00}, 1},
587 {{0x1b, 0x6f, 0x88, 0x00, 0x00, 0x00}, 1},
588 {{0x1b, 0x70, 0x0b, 0x00, 0x00, 0x00}, 1},
589 {{0x1b, 0x71, 0x00, 0x00, 0x00, 0x00}, 1},
590 {{0x1b, 0x74, 0x21, 0x00, 0x00, 0x00}, 1},
591 {{0x1b, 0x75, 0x86, 0x00, 0x00, 0x00}, 1},
592 {{0x1b, 0x76, 0x00, 0x00, 0x00, 0x00}, 1},
593 {{0x1b, 0x7d, 0xf3, 0x00, 0x00, 0x00}, 1},
594 {{0x1b, 0x17, 0x1c, 0x00, 0x00, 0x00}, 1},
595 {{0x1b, 0x18, 0xc0, 0x00, 0x00, 0x00}, 1},
596 {{0x1b, 0x19, 0x05, 0x00, 0x00, 0x00}, 1},
597 {{0x1b, 0x1a, 0xf6, 0x00, 0x00, 0x00}, 1},
598 /* {{0x13, 0x25, 0x01, 0x28, 0x00, 0x00}, 4},
599 {{0x13, 0x26, 0x01, 0x1e, 0x00, 0x00}, 4},
600 {{0x13, 0x28, 0x01, 0x0b, 0x00, 0x00}, 4}, */
601 {{0x20, 0x36, 0x06, 0x00, 0x00, 0x00}, 1},
602 {{0x1b, 0x10, 0x26, 0x00, 0x00, 0x00}, 1},
603 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
604 {{0x1b, 0x76, 0x03, 0x00, 0x00, 0x00}, 1},
605 {{0x20, 0x36, 0x05, 0x00, 0x00, 0x00}, 1},
606 {{0x1b, 0x00, 0x3f, 0x00, 0x00, 0x00}, 1},
607 /* Above is brightness; OEM driver setting is 0x10 */
608 {{0x12, 0x27, 0x01, 0x00, 0x00, 0x00}, 4},
609 {{0x20, 0x29, 0x30, 0x00, 0x00, 0x00}, 1},
610 {{0x20, 0x34, 0xa1, 0x00, 0x00, 0x00}, 1}
611 };
612
613 return run_start_commands(gspca_dev, vivitar_start_commands,
614 ARRAY_SIZE(vivitar_start_commands));
615}
616
617static int sd_start(struct gspca_dev *gspca_dev)
618{
619 struct sd *sd = (struct sd *) gspca_dev;
620 int err_code;
621
622 sd->sof_read = 0;
623
624 switch (sd->model) {
625 case 0x7005:
626 err_code = start_genius_cam(gspca_dev);
627 break;
628 case 0x8001:
629 err_code = start_spy_cam(gspca_dev);
630 break;
631 case 0x8003:
632 err_code = start_cif_cam(gspca_dev);
633 break;
634 case 0x8008:
635 err_code = start_ms350_cam(gspca_dev);
636 break;
637 case 0x800a:
638 err_code = start_vivitar_cam(gspca_dev);
639 break;
640 default:
641 PDEBUG(D_ERR, "Starting unknown camera, please report this");
642 return -ENXIO;
643 }
644
645 return err_code;
646}
647
648static void sd_stopN(struct gspca_dev *gspca_dev)
649{
650 int result;
651 __u8 data[6];
652
653 result = sn9c2028_read1(gspca_dev);
654 if (result < 0)
655 PDEBUG(D_ERR, "Camera Stop read failed");
656
657 memset(data, 0, 6);
658 data[0] = 0x14;
659 result = sn9c2028_command(gspca_dev, data);
660 if (result < 0)
661 PDEBUG(D_ERR, "Camera Stop command failed");
662}
663
664/* Include sn9c2028 sof detection functions */
665#include "sn9c2028.h"
666
667static void sd_pkt_scan(struct gspca_dev *gspca_dev,
668 __u8 *data, /* isoc packet */
669 int len) /* iso packet length */
670{
671 unsigned char *sof;
672
673 sof = sn9c2028_find_sof(gspca_dev, data, len);
674 if (sof) {
675 int n;
676
677 /* finish decoding current frame */
678 n = sof - data;
679 if (n > sizeof sn9c2028_sof_marker)
680 n -= sizeof sn9c2028_sof_marker;
681 else
682 n = 0;
683 gspca_frame_add(gspca_dev, LAST_PACKET, data, n);
684 /* Start next frame. */
685 gspca_frame_add(gspca_dev, FIRST_PACKET,
686 sn9c2028_sof_marker, sizeof sn9c2028_sof_marker);
687 len -= sof - data;
688 data = sof;
689 }
690 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
691}
692
693/* sub-driver description */
694static const struct sd_desc sd_desc = {
695 .name = MODULE_NAME,
696 .ctrls = sd_ctrls,
697 .nctrls = ARRAY_SIZE(sd_ctrls),
698 .config = sd_config,
699 .init = sd_init,
700 .start = sd_start,
701 .stopN = sd_stopN,
702 .pkt_scan = sd_pkt_scan,
703};
704
705/* -- module initialisation -- */
706static const __devinitdata struct usb_device_id device_table[] = {
707 {USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
708 /* The Genius Smart is untested. I can't find an owner ! */
709 /* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */
710 {USB_DEVICE(0x0c45, 0x8001)}, /* Wild Planet digital spy cam */
711 {USB_DEVICE(0x0c45, 0x8003)}, /* Several small CIF cameras */
712 /* {USB_DEVICE(0x0c45, 0x8006)}, Unknown VGA camera */
713 {USB_DEVICE(0x0c45, 0x8008)}, /* Mini-Shotz ms-350 */
714 {USB_DEVICE(0x0c45, 0x800a)}, /* Vivicam 3350B */
715 {}
716};
717MODULE_DEVICE_TABLE(usb, device_table);
718
719/* -- device connect -- */
720static int sd_probe(struct usb_interface *intf,
721 const struct usb_device_id *id)
722{
723 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
724 THIS_MODULE);
725}
726
727static struct usb_driver sd_driver = {
728 .name = MODULE_NAME,
729 .id_table = device_table,
730 .probe = sd_probe,
731 .disconnect = gspca_disconnect,
732#ifdef CONFIG_PM
733 .suspend = gspca_suspend,
734 .resume = gspca_resume,
735#endif
736};
737
738/* -- module insert / remove -- */
739static int __init sd_mod_init(void)
740{
741 int ret;
742
743 ret = usb_register(&sd_driver);
744 if (ret < 0)
745 return ret;
746 PDEBUG(D_PROBE, "registered");
747 return 0;
748}
749
750static void __exit sd_mod_exit(void)
751{
752 usb_deregister(&sd_driver);
753 PDEBUG(D_PROBE, "deregistered");
754}
755
756module_init(sd_mod_init);
757module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sn9c2028.h b/drivers/media/video/gspca/sn9c2028.h
new file mode 100644
index 000000000000..8fd1d3e05665
--- /dev/null
+++ b/drivers/media/video/gspca/sn9c2028.h
@@ -0,0 +1,51 @@
1/*
2 * SN9C2028 common functions
3 *
4 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn,edu>
5 *
6 * Based closely upon the file gspca/pac_common.h
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 */
23
24static const unsigned char sn9c2028_sof_marker[5] =
25 { 0xff, 0xff, 0x00, 0xc4, 0xc4 };
26
27static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
28 unsigned char *m, int len)
29{
30 struct sd *sd = (struct sd *) gspca_dev;
31 int i;
32
33 /* Search for the SOF marker (fixed part) in the header */
34 for (i = 0; i < len; i++) {
35 if (m[i] == sn9c2028_sof_marker[sd->sof_read]) {
36 sd->sof_read++;
37 if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
38 PDEBUG(D_FRAM,
39 "SOF found, bytes to analyze: %u."
40 " Frame starts at byte #%u",
41 len, i + 1);
42 sd->sof_read = 0;
43 return m + i + 1;
44 }
45 } else {
46 sd->sof_read = 0;
47 }
48 }
49
50 return NULL;
51}
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 0ca1c06652b1..4a1bc08f82b9 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -129,7 +129,7 @@ static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
129static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); 129static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
130static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); 130static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
131 131
132static struct ctrl sd_ctrls[] = { 132static const struct ctrl sd_ctrls[] = {
133 { 133 {
134#define BRIGHTNESS_IDX 0 134#define BRIGHTNESS_IDX 0
135 { 135 {
@@ -1506,36 +1506,36 @@ static int set_cmatrix(struct gspca_dev *gspca_dev)
1506 struct sd *sd = (struct sd *) gspca_dev; 1506 struct sd *sd = (struct sd *) gspca_dev;
1507 s32 hue_coord, hue_index = 180 + sd->hue; 1507 s32 hue_coord, hue_index = 180 + sd->hue;
1508 u8 cmatrix[21]; 1508 u8 cmatrix[21];
1509 memset(cmatrix, 0, 21);
1510 1509
1510 memset(cmatrix, 0, sizeof cmatrix);
1511 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; 1511 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1512 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1512 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1513 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1513 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1514 cmatrix[18] = sd->brightness - 0x80; 1514 cmatrix[18] = sd->brightness - 0x80;
1515 1515
1516 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; 1516 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1517 cmatrix[6] = (unsigned char)(hue_coord & 0xff); 1517 cmatrix[6] = hue_coord;
1518 cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f); 1518 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1519 1519
1520 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; 1520 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1521 cmatrix[8] = (unsigned char)(hue_coord & 0xff); 1521 cmatrix[8] = hue_coord;
1522 cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f); 1522 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1523 1523
1524 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; 1524 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1525 cmatrix[10] = (unsigned char)(hue_coord & 0xff); 1525 cmatrix[10] = hue_coord;
1526 cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f); 1526 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1527 1527
1528 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; 1528 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1529 cmatrix[12] = (unsigned char)(hue_coord & 0xff); 1529 cmatrix[12] = hue_coord;
1530 cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f); 1530 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1531 1531
1532 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; 1532 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1533 cmatrix[14] = (unsigned char)(hue_coord & 0xff); 1533 cmatrix[14] = hue_coord;
1534 cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f); 1534 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1535 1535
1536 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; 1536 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1537 cmatrix[16] = (unsigned char)(hue_coord & 0xff); 1537 cmatrix[16] = hue_coord;
1538 cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f); 1538 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1539 1539
1540 return reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1540 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1541} 1541}
@@ -2015,6 +2015,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2015 default: 2015 default:
2016 cam->cam_mode = vga_mode; 2016 cam->cam_mode = vga_mode;
2017 cam->nmodes = ARRAY_SIZE(vga_mode); 2017 cam->nmodes = ARRAY_SIZE(vga_mode);
2018 break;
2018 } 2019 }
2019 2020
2020 sd->old_step = 0; 2021 sd->old_step = 0;
@@ -2319,7 +2320,7 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2319 } 2320 }
2320 } 2321 }
2321 if (avg_lum > MAX_AVG_LUM) { 2322 if (avg_lum > MAX_AVG_LUM) {
2322 if (sd->gain >= 1) { 2323 if (sd->gain > 0) {
2323 sd->gain--; 2324 sd->gain--;
2324 set_gain(gspca_dev); 2325 set_gain(gspca_dev);
2325 } 2326 }
@@ -2347,7 +2348,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2347{ 2348{
2348 struct sd *sd = (struct sd *) gspca_dev; 2349 struct sd *sd = (struct sd *) gspca_dev;
2349 int avg_lum; 2350 int avg_lum;
2350 static unsigned char frame_header[] = 2351 static u8 frame_header[] =
2351 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 2352 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2352 if (len == 64 && memcmp(data, frame_header, 6) == 0) { 2353 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2353 avg_lum = ((data[35] >> 2) & 3) | 2354 avg_lum = ((data[35] >> 2) & 3) |
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index ddff2b5ee5c2..785eeb4c2014 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -42,6 +42,7 @@ Reg Use
42 42
43#define MODULE_NAME "sonixb" 43#define MODULE_NAME "sonixb"
44 44
45#include <linux/input.h>
45#include "gspca.h" 46#include "gspca.h"
46 47
47MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 48MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -53,9 +54,11 @@ struct sd {
53 struct gspca_dev gspca_dev; /* !! must be the first item */ 54 struct gspca_dev gspca_dev; /* !! must be the first item */
54 atomic_t avg_lum; 55 atomic_t avg_lum;
55 int prev_avg_lum; 56 int prev_avg_lum;
57 int exp_too_low_cnt;
58 int exp_too_high_cnt;
56 59
60 unsigned short exposure;
57 unsigned char gain; 61 unsigned char gain;
58 unsigned char exposure;
59 unsigned char brightness; 62 unsigned char brightness;
60 unsigned char autogain; 63 unsigned char autogain;
61 unsigned char autogain_ignore_frames; 64 unsigned char autogain_ignore_frames;
@@ -73,8 +76,9 @@ struct sd {
73#define SENSOR_OV7630 2 76#define SENSOR_OV7630 2
74#define SENSOR_PAS106 3 77#define SENSOR_PAS106 3
75#define SENSOR_PAS202 4 78#define SENSOR_PAS202 4
76#define SENSOR_TAS5110 5 79#define SENSOR_TAS5110C 5
77#define SENSOR_TAS5130CXX 6 80#define SENSOR_TAS5110D 6
81#define SENSOR_TAS5130CXX 7
78 __u8 reg11; 82 __u8 reg11;
79}; 83};
80 84
@@ -95,13 +99,15 @@ struct sensor_data {
95/* sensor_data flags */ 99/* sensor_data flags */
96#define F_GAIN 0x01 /* has gain */ 100#define F_GAIN 0x01 /* has gain */
97#define F_SIF 0x02 /* sif or vga */ 101#define F_SIF 0x02 /* sif or vga */
102#define F_COARSE_EXPO 0x04 /* exposure control is coarse */
98 103
99/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ 104/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100#define MODE_RAW 0x10 /* raw bayer mode */ 105#define MODE_RAW 0x10 /* raw bayer mode */
101#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 106#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
102 107
103/* ctrl_dis helper macros */ 108/* ctrl_dis helper macros */
104#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) 109#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
110 (1 << AUTOGAIN_IDX))
105#define NO_FREQ (1 << FREQ_IDX) 111#define NO_FREQ (1 << FREQ_IDX)
106#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) 112#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
107 113
@@ -127,11 +133,10 @@ struct sensor_data {
127} 133}
128 134
129/* We calculate the autogain at the end of the transfer of a frame, at this 135/* We calculate the autogain at the end of the transfer of a frame, at this
130 moment a frame with the old settings is being transmitted, and a frame is 136 moment a frame with the old settings is being captured and transmitted. So
131 being captured with the old settings. So if we adjust the autogain we must 137 if we adjust the gain or exposure we must ignore atleast the next frame for
132 ignore atleast the 2 next frames for the new settings to come into effect 138 the new settings to come into effect before doing any other adjustments. */
133 before doing any other adjustments */ 139#define AUTOGAIN_IGNORE_FRAMES 1
134#define AUTOGAIN_IGNORE_FRAMES 3
135 140
136/* V4L2 controls supported by the driver */ 141/* V4L2 controls supported by the driver */
137static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 142static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -145,7 +150,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
145static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 150static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
146static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 151static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
147 152
148static struct ctrl sd_ctrls[] = { 153static const struct ctrl sd_ctrls[] = {
149#define BRIGHTNESS_IDX 0 154#define BRIGHTNESS_IDX 0
150 { 155 {
151 { 156 {
@@ -171,7 +176,7 @@ static struct ctrl sd_ctrls[] = {
171 .maximum = 255, 176 .maximum = 255,
172 .step = 1, 177 .step = 1,
173#define GAIN_DEF 127 178#define GAIN_DEF 127
174#define GAIN_KNEE 200 179#define GAIN_KNEE 230
175 .default_value = GAIN_DEF, 180 .default_value = GAIN_DEF,
176 }, 181 },
177 .set = sd_setgain, 182 .set = sd_setgain,
@@ -183,10 +188,10 @@ static struct ctrl sd_ctrls[] = {
183 .id = V4L2_CID_EXPOSURE, 188 .id = V4L2_CID_EXPOSURE,
184 .type = V4L2_CTRL_TYPE_INTEGER, 189 .type = V4L2_CTRL_TYPE_INTEGER,
185 .name = "Exposure", 190 .name = "Exposure",
186#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ 191#define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
187#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ 192#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
188 .minimum = 0, 193 .minimum = 0,
189 .maximum = 255, 194 .maximum = 1023,
190 .step = 1, 195 .step = 1,
191 .default_value = EXPOSURE_DEF, 196 .default_value = EXPOSURE_DEF,
192 .flags = 0, 197 .flags = 0,
@@ -194,7 +199,23 @@ static struct ctrl sd_ctrls[] = {
194 .set = sd_setexposure, 199 .set = sd_setexposure,
195 .get = sd_getexposure, 200 .get = sd_getexposure,
196 }, 201 },
197#define AUTOGAIN_IDX 3 202#define COARSE_EXPOSURE_IDX 3
203 {
204 {
205 .id = V4L2_CID_EXPOSURE,
206 .type = V4L2_CTRL_TYPE_INTEGER,
207 .name = "Exposure",
208#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
209 .minimum = 2,
210 .maximum = 15,
211 .step = 1,
212 .default_value = COARSE_EXPOSURE_DEF,
213 .flags = 0,
214 },
215 .set = sd_setexposure,
216 .get = sd_getexposure,
217 },
218#define AUTOGAIN_IDX 4
198 { 219 {
199 { 220 {
200 .id = V4L2_CID_AUTOGAIN, 221 .id = V4L2_CID_AUTOGAIN,
@@ -210,7 +231,7 @@ static struct ctrl sd_ctrls[] = {
210 .set = sd_setautogain, 231 .set = sd_setautogain,
211 .get = sd_getautogain, 232 .get = sd_getautogain,
212 }, 233 },
213#define FREQ_IDX 4 234#define FREQ_IDX 5
214 { 235 {
215 { 236 {
216 .id = V4L2_CID_POWER_LINE_FREQUENCY, 237 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -219,7 +240,7 @@ static struct ctrl sd_ctrls[] = {
219 .minimum = 0, 240 .minimum = 0,
220 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 241 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
221 .step = 1, 242 .step = 1,
222#define FREQ_DEF 1 243#define FREQ_DEF 0
223 .default_value = FREQ_DEF, 244 .default_value = FREQ_DEF,
224 }, 245 },
225 .set = sd_setfreq, 246 .set = sd_setfreq,
@@ -345,7 +366,7 @@ static const __u8 initOv7630[] = {
345}; 366};
346static const __u8 initOv7630_3[] = { 367static const __u8 initOv7630_3[] = {
347 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 368 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
348 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ 369 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
349 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 370 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
350 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 371 0x28, 0x1e, /* H & V sizes r15 .. r16 */
351 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 372 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
@@ -387,6 +408,30 @@ static const __u8 initPas106[] = {
387 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 408 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
388}; 409};
389/* compression 0x86 mckinit1 0x2b */ 410/* compression 0x86 mckinit1 0x2b */
411
412/* "Known" PAS106B registers:
413 0x02 clock divider
414 0x03 Variable framerate bits 4-11
415 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
416 The variable framerate control must never be set lower then 300,
417 which sets the framerate at 90 / reg02, otherwise vsync is lost.
418 0x05 Shutter Time Line Offset, this can be used as an exposure control:
419 0 = use full frame time, 255 = no exposure at all
420 Note this may never be larger then "var-framerate control" / 2 - 2.
421 When var-framerate control is < 514, no exposure is reached at the max
422 allowed value for the framerate control value, rather then at 255.
423 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
424 only a very little bit, leave at 0xcd
425 0x07 offset sign bit (bit0 1 > negative offset)
426 0x08 offset
427 0x09 Blue Gain
428 0x0a Green1 Gain
429 0x0b Green2 Gain
430 0x0c Red Gain
431 0x0e Global gain
432 0x13 Write 1 to commit settings to sensor
433*/
434
390static const __u8 pas106_sensor_init[][8] = { 435static const __u8 pas106_sensor_init[][8] = {
391 /* Pixel Clock Divider 6 */ 436 /* Pixel Clock Divider 6 */
392 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 }, 437 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
@@ -433,37 +478,55 @@ static const __u8 initPas202[] = {
433 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 478 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
434 0x00, 0x00, 479 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, 480 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
436 0x28, 0x1e, 0x28, 0x89, 0x20, 481 0x28, 0x1e, 0x20, 0x89, 0x20,
437 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c 482 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
438}; 483};
484
485/* "Known" PAS202BCB registers:
486 0x02 clock divider
487 0x04 Variable framerate bits 6-11 (*)
488 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
489 0x07 Blue Gain
490 0x08 Green Gain
491 0x09 Red Gain
492 0x0b offset sign bit (bit0 1 > negative offset)
493 0x0c offset
494 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
495 leave at 1 otherwise we get a jump in our exposure control
496 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
497 0x10 Master gain 0 - 31
498 0x11 write 1 to apply changes
499 (*) The variable framerate control must never be set lower then 500
500 which sets the framerate at 30 / reg02, otherwise vsync is lost.
501*/
439static const __u8 pas202_sensor_init[][8] = { 502static const __u8 pas202_sensor_init[][8] = {
440 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}, 503 /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
504 to set it lower, but for some reason the bridge starts missing
505 vsync's then */
506 {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
441 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, 507 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
442 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, 508 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
443 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10}, 509 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
444 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, 510 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
445 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, 511 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
446 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, 512 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
447 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, 513 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
448 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, 514 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
449 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, 515 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
450 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
451 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
452
453 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
454 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
455 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
456 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
457 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
458 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
459 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
460 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
461}; 516};
462 517
463static const __u8 initTas5110[] = { 518static const __u8 initTas5110c[] = {
464 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 519 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
465 0x00, 0x00, 520 0x00, 0x00,
466 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a, 521 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
522 0x16, 0x12, 0x60, 0x86, 0x2b,
523 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
524};
525/* Same as above, except a different hstart */
526static const __u8 initTas5110d[] = {
527 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
528 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
467 0x16, 0x12, 0x60, 0x86, 0x2b, 530 0x16, 0x12, 0x60, 0x86, 0x2b,
468 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 531 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
469}; 532};
@@ -476,7 +539,7 @@ static const __u8 tas5110_sensor_init[][8] = {
476static const __u8 initTas5130[] = { 539static const __u8 initTas5130[] = {
477 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 540 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
478 0x00, 0x00, 541 0x00, 0x00,
479 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a, 542 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
480 0x28, 0x1e, 0x60, COMP, MCK_INIT, 543 0x28, 0x1e, 0x60, COMP, MCK_INIT,
481 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 544 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
482}; 545};
@@ -493,12 +556,14 @@ SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
493SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), 556SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
494SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, 557SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
495 F_GAIN, 0, 0x21), 558 F_GAIN, 0, 0x21),
496SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 559SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
497 0), 560 0),
498SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0, 561SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
499 NO_EXPO|NO_FREQ, 0), 562 NO_FREQ, 0),
500SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF, 563SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
501 NO_BRIGHTNESS|NO_FREQ, 0), 564 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
565SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
566 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
502SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 567SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
503 0), 568 0),
504}; 569};
@@ -587,42 +652,28 @@ static void setbrightness(struct gspca_dev *gspca_dev)
587 goto err; 652 goto err;
588 break; 653 break;
589 } 654 }
590 case SENSOR_PAS106: { 655 case SENSOR_PAS106:
591 __u8 i2c1[] =
592 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
593
594 i2c1[3] = sd->brightness >> 3;
595 i2c1[2] = 0x0e;
596 if (i2c_w(gspca_dev, i2c1) < 0)
597 goto err;
598 i2c1[3] = 0x01;
599 i2c1[2] = 0x13;
600 if (i2c_w(gspca_dev, i2c1) < 0)
601 goto err;
602 break;
603 }
604 case SENSOR_PAS202: { 656 case SENSOR_PAS202: {
605 /* __u8 i2cpexpo1[] = 657 __u8 i2cpbright[] =
606 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */ 658 {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
607 __u8 i2cpexpo[] = 659 __u8 i2cpdoit[] =
608 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16}; 660 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
609 __u8 i2cp202[] = 661
610 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}; 662 /* PAS106 uses reg 7 and 8 instead of b and c */
611 static __u8 i2cpdoit[] = 663 if (sd->sensor == SENSOR_PAS106) {
612 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}; 664 i2cpbright[2] = 7;
613 665 i2cpdoit[2] = 0x13;
614 /* change reg 0x10 */ 666 }
615 i2cpexpo[4] = 0xff - sd->brightness; 667
616/* if(i2c_w(gspca_dev,i2cpexpo1) < 0) 668 if (sd->brightness < 127) {
617 goto err; */ 669 /* change reg 0x0b, signreg */
618/* if(i2c_w(gspca_dev,i2cpdoit) < 0) 670 i2cpbright[3] = 0x01;
619 goto err; */ 671 /* set reg 0x0c, offset */
620 if (i2c_w(gspca_dev, i2cpexpo) < 0) 672 i2cpbright[4] = 127 - sd->brightness;
621 goto err; 673 } else
622 if (i2c_w(gspca_dev, i2cpdoit) < 0) 674 i2cpbright[4] = sd->brightness - 127;
623 goto err; 675
624 i2cp202[3] = sd->brightness >> 3; 676 if (i2c_w(gspca_dev, i2cpbright) < 0)
625 if (i2c_w(gspca_dev, i2cp202) < 0)
626 goto err; 677 goto err;
627 if (i2c_w(gspca_dev, i2cpdoit) < 0) 678 if (i2c_w(gspca_dev, i2cpdoit) < 0)
628 goto err; 679 goto err;
@@ -652,7 +703,8 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
652 703
653 switch (sd->sensor) { 704 switch (sd->sensor) {
654 705
655 case SENSOR_TAS5110: { 706 case SENSOR_TAS5110C:
707 case SENSOR_TAS5110D: {
656 __u8 i2c[] = 708 __u8 i2c[] =
657 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; 709 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
658 710
@@ -674,6 +726,37 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
674 goto err; 726 goto err;
675 break; 727 break;
676 } 728 }
729 case SENSOR_PAS106:
730 case SENSOR_PAS202: {
731 __u8 i2cpgain[] =
732 {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
733 __u8 i2cpcolorgain[] =
734 {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
735 __u8 i2cpdoit[] =
736 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
737
738 /* PAS106 uses different regs (and has split green gains) */
739 if (sd->sensor == SENSOR_PAS106) {
740 i2cpgain[2] = 0x0e;
741 i2cpcolorgain[0] = 0xd0;
742 i2cpcolorgain[2] = 0x09;
743 i2cpdoit[2] = 0x13;
744 }
745
746 i2cpgain[3] = sd->gain >> 3;
747 i2cpcolorgain[3] = sd->gain >> 4;
748 i2cpcolorgain[4] = sd->gain >> 4;
749 i2cpcolorgain[5] = sd->gain >> 4;
750 i2cpcolorgain[6] = sd->gain >> 4;
751
752 if (i2c_w(gspca_dev, i2cpgain) < 0)
753 goto err;
754 if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
755 goto err;
756 if (i2c_w(gspca_dev, i2cpdoit) < 0)
757 goto err;
758 break;
759 }
677 } 760 }
678 return; 761 return;
679err: 762err:
@@ -684,19 +767,21 @@ static void setgain(struct gspca_dev *gspca_dev)
684{ 767{
685 struct sd *sd = (struct sd *) gspca_dev; 768 struct sd *sd = (struct sd *) gspca_dev;
686 __u8 gain; 769 __u8 gain;
687 __u8 rgb_value; 770 __u8 buf[2] = { 0, 0 };
771
772 if (sensor_data[sd->sensor].flags & F_GAIN) {
773 /* Use the sensor gain to do the actual gain */
774 setsensorgain(gspca_dev);
775 return;
776 }
688 777
689 gain = sd->gain >> 4; 778 gain = sd->gain >> 4;
690 779
691 /* red and blue gain */ 780 /* red and blue gain */
692 rgb_value = gain << 4 | gain; 781 buf[0] = gain << 4 | gain;
693 reg_w(gspca_dev, 0x10, &rgb_value, 1);
694 /* green gain */ 782 /* green gain */
695 rgb_value = gain; 783 buf[1] = gain;
696 reg_w(gspca_dev, 0x11, &rgb_value, 1); 784 reg_w(gspca_dev, 0x10, buf, 2);
697
698 if (sensor_data[sd->sensor].flags & F_GAIN)
699 setsensorgain(gspca_dev);
700} 785}
701 786
702static void setexposure(struct gspca_dev *gspca_dev) 787static void setexposure(struct gspca_dev *gspca_dev)
@@ -704,17 +789,12 @@ static void setexposure(struct gspca_dev *gspca_dev)
704 struct sd *sd = (struct sd *) gspca_dev; 789 struct sd *sd = (struct sd *) gspca_dev;
705 790
706 switch (sd->sensor) { 791 switch (sd->sensor) {
707 case SENSOR_TAS5110: { 792 case SENSOR_TAS5110C:
708 __u8 reg; 793 case SENSOR_TAS5110D: {
709
710 /* register 19's high nibble contains the sn9c10x clock divider 794 /* register 19's high nibble contains the sn9c10x clock divider
711 The high nibble configures the no fps according to the 795 The high nibble configures the no fps according to the
712 formula: 60 / high_nibble. With a maximum of 30 fps */ 796 formula: 60 / high_nibble. With a maximum of 30 fps */
713 reg = 120 * sd->exposure / 1000; 797 __u8 reg = sd->exposure;
714 if (reg < 2)
715 reg = 2;
716 else if (reg > 15)
717 reg = 15;
718 reg = (reg << 4) | 0x0b; 798 reg = (reg << 4) | 0x0b;
719 reg_w(gspca_dev, 0x19, &reg, 1); 799 reg_w(gspca_dev, 0x19, &reg, 1);
720 break; 800 break;
@@ -750,20 +830,21 @@ static void setexposure(struct gspca_dev *gspca_dev)
750 } else 830 } else
751 reg10_max = 0x41; 831 reg10_max = 0x41;
752 832
753 reg11 = (60 * sd->exposure + 999) / 1000; 833 reg11 = (15 * sd->exposure + 999) / 1000;
754 if (reg11 < 1) 834 if (reg11 < 1)
755 reg11 = 1; 835 reg11 = 1;
756 else if (reg11 > 16) 836 else if (reg11 > 16)
757 reg11 = 16; 837 reg11 = 16;
758 838
759 /* In 640x480, if the reg11 has less than 3, the image is 839 /* In 640x480, if the reg11 has less than 4, the image is
760 unstable (not enough bandwidth). */ 840 unstable (the bridge goes into a higher compression mode
761 if (gspca_dev->width == 640 && reg11 < 3) 841 which we have not reverse engineered yet). */
762 reg11 = 3; 842 if (gspca_dev->width == 640 && reg11 < 4)
843 reg11 = 4;
763 844
764 /* frame exposure time in ms = 1000 * reg11 / 30 -> 845 /* frame exposure time in ms = 1000 * reg11 / 30 ->
765 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ 846 reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
766 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); 847 reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
767 848
768 /* Don't allow this to get below 10 when using autogain, the 849 /* Don't allow this to get below 10 when using autogain, the
769 steps become very large (relatively) when below 10 causing 850 steps become very large (relatively) when below 10 causing
@@ -786,10 +867,85 @@ static void setexposure(struct gspca_dev *gspca_dev)
786 if (i2c_w(gspca_dev, i2c) == 0) 867 if (i2c_w(gspca_dev, i2c) == 0)
787 sd->reg11 = reg11; 868 sd->reg11 = reg11;
788 else 869 else
789 PDEBUG(D_ERR, "i2c error exposure"); 870 goto err;
871 break;
872 }
873 case SENSOR_PAS202: {
874 __u8 i2cpframerate[] =
875 {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
876 __u8 i2cpexpo[] =
877 {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
878 const __u8 i2cpdoit[] =
879 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
880 int framerate_ctrl;
881
882 /* The exposure knee for the autogain algorithm is 200
883 (100 ms / 10 fps on other sensors), for values below this
884 use the control for setting the partial frame expose time,
885 above that use variable framerate. This way we run at max
886 framerate (640x480@7.5 fps, 320x240@10fps) until the knee
887 is reached. Using the variable framerate control above 200
888 is better then playing around with both clockdiv + partial
889 frame exposure times (like we are doing with the ov chips),
890 as that sometimes leads to jumps in the exposure control,
891 which are bad for auto exposure. */
892 if (sd->exposure < 200) {
893 i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
894 framerate_ctrl = 500;
895 } else {
896 /* The PAS202's exposure control goes from 0 - 4095,
897 but anything below 500 causes vsync issues, so scale
898 our 200-1023 to 500-4095 */
899 framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
900 500;
901 }
902
903 i2cpframerate[3] = framerate_ctrl >> 6;
904 i2cpframerate[4] = framerate_ctrl & 0x3f;
905 if (i2c_w(gspca_dev, i2cpframerate) < 0)
906 goto err;
907 if (i2c_w(gspca_dev, i2cpexpo) < 0)
908 goto err;
909 if (i2c_w(gspca_dev, i2cpdoit) < 0)
910 goto err;
911 break;
912 }
913 case SENSOR_PAS106: {
914 __u8 i2cpframerate[] =
915 {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
916 __u8 i2cpexpo[] =
917 {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
918 const __u8 i2cpdoit[] =
919 {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
920 int framerate_ctrl;
921
922 /* For values below 150 use partial frame exposure, above
923 that use framerate ctrl */
924 if (sd->exposure < 150) {
925 i2cpexpo[3] = 150 - sd->exposure;
926 framerate_ctrl = 300;
927 } else {
928 /* The PAS106's exposure control goes from 0 - 4095,
929 but anything below 300 causes vsync issues, so scale
930 our 150-1023 to 300-4095 */
931 framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
932 300;
933 }
934
935 i2cpframerate[3] = framerate_ctrl >> 4;
936 i2cpframerate[4] = framerate_ctrl & 0x0f;
937 if (i2c_w(gspca_dev, i2cpframerate) < 0)
938 goto err;
939 if (i2c_w(gspca_dev, i2cpexpo) < 0)
940 goto err;
941 if (i2c_w(gspca_dev, i2cpdoit) < 0)
942 goto err;
790 break; 943 break;
791 } 944 }
792 } 945 }
946 return;
947err:
948 PDEBUG(D_ERR, "i2c error exposure");
793} 949}
794 950
795static void setfreq(struct gspca_dev *gspca_dev) 951static void setfreq(struct gspca_dev *gspca_dev)
@@ -823,30 +979,43 @@ static void setfreq(struct gspca_dev *gspca_dev)
823 } 979 }
824} 980}
825 981
982#include "coarse_expo_autogain.h"
983
826static void do_autogain(struct gspca_dev *gspca_dev) 984static void do_autogain(struct gspca_dev *gspca_dev)
827{ 985{
828 int deadzone, desired_avg_lum; 986 int deadzone, desired_avg_lum, result;
829 struct sd *sd = (struct sd *) gspca_dev; 987 struct sd *sd = (struct sd *) gspca_dev;
830 int avg_lum = atomic_read(&sd->avg_lum); 988 int avg_lum = atomic_read(&sd->avg_lum);
831 989
832 if (avg_lum == -1) 990 if (avg_lum == -1 || !sd->autogain)
833 return; 991 return;
834 992
993 if (sd->autogain_ignore_frames > 0) {
994 sd->autogain_ignore_frames--;
995 return;
996 }
997
835 /* SIF / VGA sensors have a different autoexposure area and thus 998 /* SIF / VGA sensors have a different autoexposure area and thus
836 different avg_lum values for the same picture brightness */ 999 different avg_lum values for the same picture brightness */
837 if (sensor_data[sd->sensor].flags & F_SIF) { 1000 if (sensor_data[sd->sensor].flags & F_SIF) {
838 deadzone = 1000; 1001 deadzone = 500;
839 desired_avg_lum = 7000; 1002 /* SIF sensors tend to overexpose, so keep this small */
1003 desired_avg_lum = 5000;
840 } else { 1004 } else {
841 deadzone = 3000; 1005 deadzone = 1500;
842 desired_avg_lum = 23000; 1006 desired_avg_lum = 18000;
843 } 1007 }
844 1008
845 if (sd->autogain_ignore_frames > 0) 1009 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
846 sd->autogain_ignore_frames--; 1010 result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
847 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 1011 sd->brightness * desired_avg_lum / 127,
848 sd->brightness * desired_avg_lum / 127, 1012 deadzone);
849 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) { 1013 else
1014 result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
1015 sd->brightness * desired_avg_lum / 127,
1016 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1017
1018 if (result) {
850 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", 1019 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
851 (int)sd->gain, (int)sd->exposure); 1020 (int)sd->gain, (int)sd->exposure);
852 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1021 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
@@ -881,7 +1050,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
881 1050
882 sd->brightness = BRIGHTNESS_DEF; 1051 sd->brightness = BRIGHTNESS_DEF;
883 sd->gain = GAIN_DEF; 1052 sd->gain = GAIN_DEF;
884 sd->exposure = EXPOSURE_DEF; 1053 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1054 sd->exposure = COARSE_EXPOSURE_DEF;
1055 gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
1056 } else {
1057 sd->exposure = EXPOSURE_DEF;
1058 gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1059 }
885 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) 1060 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
886 sd->autogain = 0; /* Disable do_autogain callback */ 1061 sd->autogain = 0; /* Disable do_autogain callback */
887 else 1062 else
@@ -917,9 +1092,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
917 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); 1092 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
918 /* Special cases where reg 17 and or 19 value depends on mode */ 1093 /* Special cases where reg 17 and or 19 value depends on mode */
919 switch (sd->sensor) { 1094 switch (sd->sensor) {
920 case SENSOR_PAS202:
921 reg12_19[5] = mode ? 0x24 : 0x20;
922 break;
923 case SENSOR_TAS5130CXX: 1095 case SENSOR_TAS5130CXX:
924 /* probably not mode specific at all most likely the upper 1096 /* probably not mode specific at all most likely the upper
925 nibble of 0x19 is exposure (clock divider) just as with 1097 nibble of 0x19 is exposure (clock divider) just as with
@@ -955,6 +1127,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
955 sensor_data[sd->sensor].sensor_bridge_init_size[ 1127 sensor_data[sd->sensor].sensor_bridge_init_size[
956 sd->bridge]); 1128 sd->bridge]);
957 1129
1130 /* Mode specific sensor setup */
1131 switch (sd->sensor) {
1132 case SENSOR_PAS202: {
1133 const __u8 i2cpclockdiv[] =
1134 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1135 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1136 if (mode)
1137 i2c_w(gspca_dev, i2cpclockdiv);
1138 }
1139 }
958 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 1140 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
959 reg_w(gspca_dev, 0x15, &reg12_19[3], 2); 1141 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
960 /* compression register */ 1142 /* compression register */
@@ -985,6 +1167,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
985 1167
986 sd->frames_to_drop = 0; 1168 sd->frames_to_drop = 0;
987 sd->autogain_ignore_frames = 0; 1169 sd->autogain_ignore_frames = 0;
1170 sd->exp_too_high_cnt = 0;
1171 sd->exp_too_low_cnt = 0;
988 atomic_set(&sd->avg_lum, -1); 1172 atomic_set(&sd->avg_lum, -1);
989 return 0; 1173 return 0;
990} 1174}
@@ -1143,11 +1327,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1143 struct sd *sd = (struct sd *) gspca_dev; 1327 struct sd *sd = (struct sd *) gspca_dev;
1144 1328
1145 sd->autogain = val; 1329 sd->autogain = val;
1330 sd->exp_too_high_cnt = 0;
1331 sd->exp_too_low_cnt = 0;
1332
1146 /* when switching to autogain set defaults to make sure 1333 /* when switching to autogain set defaults to make sure
1147 we are on a valid point of the autogain gain / 1334 we are on a valid point of the autogain gain /
1148 exposure knee graph, and give this change time to 1335 exposure knee graph, and give this change time to
1149 take effect before doing autogain. */ 1336 take effect before doing autogain. */
1150 if (sd->autogain) { 1337 if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1151 sd->exposure = EXPOSURE_DEF; 1338 sd->exposure = EXPOSURE_DEF;
1152 sd->gain = GAIN_DEF; 1339 sd->gain = GAIN_DEF;
1153 if (gspca_dev->streaming) { 1340 if (gspca_dev->streaming) {
@@ -1207,6 +1394,25 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
1207 return -EINVAL; 1394 return -EINVAL;
1208} 1395}
1209 1396
1397#ifdef CONFIG_INPUT
1398static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1399 u8 *data, /* interrupt packet data */
1400 int len) /* interrupt packet length */
1401{
1402 int ret = -EINVAL;
1403
1404 if (len == 1 && data[0] == 1) {
1405 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1406 input_sync(gspca_dev->input_dev);
1407 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1408 input_sync(gspca_dev->input_dev);
1409 ret = 0;
1410 }
1411
1412 return ret;
1413}
1414#endif
1415
1210/* sub-driver description */ 1416/* sub-driver description */
1211static const struct sd_desc sd_desc = { 1417static const struct sd_desc sd_desc = {
1212 .name = MODULE_NAME, 1418 .name = MODULE_NAME,
@@ -1219,6 +1425,9 @@ static const struct sd_desc sd_desc = {
1219 .pkt_scan = sd_pkt_scan, 1425 .pkt_scan = sd_pkt_scan,
1220 .querymenu = sd_querymenu, 1426 .querymenu = sd_querymenu,
1221 .dq_callback = do_autogain, 1427 .dq_callback = do_autogain,
1428#ifdef CONFIG_INPUT
1429 .int_pkt_scan = sd_int_pkt_scan,
1430#endif
1222}; 1431};
1223 1432
1224/* -- module initialisation -- */ 1433/* -- module initialisation -- */
@@ -1227,21 +1436,21 @@ static const struct sd_desc sd_desc = {
1227 1436
1228 1437
1229static const struct usb_device_id device_table[] __devinitconst = { 1438static const struct usb_device_id device_table[] __devinitconst = {
1230 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ 1439 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1231 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ 1440 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1232#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1441#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1233 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */ 1442 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1443#endif
1234 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, 1444 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1235 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, 1445 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1236#endif
1237 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, 1446 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1238#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1447#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1239 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, 1448 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1240 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, 1449 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1241 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, 1450 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1451#endif
1242 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)}, 1452 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1243 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, 1453 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1244#endif
1245 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, 1454 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1246 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, 1455 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1247#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 1456#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 0bd36a00dd2a..83d5773d4629 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -21,6 +21,7 @@
21 21
22#define MODULE_NAME "sonixj" 22#define MODULE_NAME "sonixj"
23 23
24#include <linux/input.h>
24#include "gspca.h" 25#include "gspca.h"
25#include "jpeg.h" 26#include "jpeg.h"
26 27
@@ -45,6 +46,7 @@ struct sd {
45 u8 red; 46 u8 red;
46 u8 gamma; 47 u8 gamma;
47 u8 vflip; /* ov7630/ov7648 only */ 48 u8 vflip; /* ov7630/ov7648 only */
49 u8 sharpness;
48 u8 infrared; /* mt9v111 only */ 50 u8 infrared; /* mt9v111 only */
49 u8 freq; /* ov76xx only */ 51 u8 freq; /* ov76xx only */
50 u8 quality; /* image quality */ 52 u8 quality; /* image quality */
@@ -64,16 +66,17 @@ struct sd {
64#define BRIDGE_SN9C110 2 66#define BRIDGE_SN9C110 2
65#define BRIDGE_SN9C120 3 67#define BRIDGE_SN9C120 3
66 u8 sensor; /* Type of image sensor chip */ 68 u8 sensor; /* Type of image sensor chip */
67#define SENSOR_HV7131R 0 69#define SENSOR_ADCM1700 0
68#define SENSOR_MI0360 1 70#define SENSOR_HV7131R 1
69#define SENSOR_MO4000 2 71#define SENSOR_MI0360 2
70#define SENSOR_MT9V111 3 72#define SENSOR_MO4000 3
71#define SENSOR_OM6802 4 73#define SENSOR_MT9V111 4
72#define SENSOR_OV7630 5 74#define SENSOR_OM6802 5
73#define SENSOR_OV7648 6 75#define SENSOR_OV7630 6
74#define SENSOR_OV7660 7 76#define SENSOR_OV7648 7
75#define SENSOR_PO1030 8 77#define SENSOR_OV7660 8
76#define SENSOR_SP80708 9 78#define SENSOR_PO1030 9
79#define SENSOR_SP80708 10
77 u8 i2c_addr; 80 u8 i2c_addr;
78 81
79 u8 *jpeg_hdr; 82 u8 *jpeg_hdr;
@@ -96,12 +99,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 99static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 100static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 101static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); 104static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); 105static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
101static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
103 108
104static struct ctrl sd_ctrls[] = { 109static const struct ctrl sd_ctrls[] = {
105#define BRIGHTNESS_IDX 0 110#define BRIGHTNESS_IDX 0
106 { 111 {
107 { 112 {
@@ -225,8 +230,23 @@ static struct ctrl sd_ctrls[] = {
225 .set = sd_setvflip, 230 .set = sd_setvflip,
226 .get = sd_getvflip, 231 .get = sd_getvflip,
227 }, 232 },
233#define SHARPNESS_IDX 8
234 {
235 {
236 .id = V4L2_CID_SHARPNESS,
237 .type = V4L2_CTRL_TYPE_INTEGER,
238 .name = "Sharpness",
239 .minimum = 0,
240 .maximum = 255,
241 .step = 1,
242#define SHARPNESS_DEF 90
243 .default_value = SHARPNESS_DEF,
244 },
245 .set = sd_setsharpness,
246 .get = sd_getsharpness,
247 },
228/* mt9v111 only */ 248/* mt9v111 only */
229#define INFRARED_IDX 8 249#define INFRARED_IDX 9
230 { 250 {
231 { 251 {
232 .id = V4L2_CID_INFRARED, 252 .id = V4L2_CID_INFRARED,
@@ -242,7 +262,7 @@ static struct ctrl sd_ctrls[] = {
242 .get = sd_getinfrared, 262 .get = sd_getinfrared,
243 }, 263 },
244/* ov7630/ov7648/ov7660 only */ 264/* ov7630/ov7648/ov7660 only */
245#define FREQ_IDX 9 265#define FREQ_IDX 10
246 { 266 {
247 { 267 {
248 .id = V4L2_CID_POWER_LINE_FREQUENCY, 268 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -261,28 +281,37 @@ static struct ctrl sd_ctrls[] = {
261 281
262/* table of the disabled controls */ 282/* table of the disabled controls */
263static __u32 ctrl_dis[] = { 283static __u32 ctrl_dis[] = {
284 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) |
285 (1 << AUTOGAIN_IDX), /* SENSOR_ADCM1700 0 */
286 (1 << INFRARED_IDX) | (1 << FREQ_IDX),
287 /* SENSOR_HV7131R 1 */
264 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 288 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
265 /* SENSOR_HV7131R 0 */ 289 /* SENSOR_MI0360 2 */
266 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 290 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
267 /* SENSOR_MI0360 1 */ 291 /* SENSOR_MO4000 3 */
268 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
269 /* SENSOR_MO4000 2 */
270 (1 << VFLIP_IDX) | (1 << FREQ_IDX), 292 (1 << VFLIP_IDX) | (1 << FREQ_IDX),
271 /* SENSOR_MT9V111 3 */ 293 /* SENSOR_MT9V111 4 */
272 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 294 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
273 /* SENSOR_OM6802 4 */ 295 /* SENSOR_OM6802 5 */
274 (1 << INFRARED_IDX), 296 (1 << INFRARED_IDX),
275 /* SENSOR_OV7630 5 */ 297 /* SENSOR_OV7630 6 */
276 (1 << INFRARED_IDX), 298 (1 << INFRARED_IDX),
277 /* SENSOR_OV7648 6 */ 299 /* SENSOR_OV7648 7 */
278 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 300 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
279 /* SENSOR_OV7660 7 */ 301 /* SENSOR_OV7660 8 */
280 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 302 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
281 (1 << FREQ_IDX), /* SENSOR_PO1030 8 */ 303 (1 << FREQ_IDX), /* SENSOR_PO1030 9 */
282 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 304 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
283 (1 << FREQ_IDX), /* SENSOR_SP80708 9 */ 305 (1 << FREQ_IDX), /* SENSOR_SP80708 10 */
284}; 306};
285 307
308static const struct v4l2_pix_format cif_mode[] = {
309 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
310 .bytesperline = 352,
311 .sizeimage = 352 * 288 * 4 / 8 + 590,
312 .colorspace = V4L2_COLORSPACE_JPEG,
313 .priv = 0},
314};
286static const struct v4l2_pix_format vga_mode[] = { 315static const struct v4l2_pix_format vga_mode[] = {
287 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 316 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
288 .bytesperline = 160, 317 .bytesperline = 160,
@@ -302,6 +331,17 @@ static const struct v4l2_pix_format vga_mode[] = {
302 .priv = 0}, 331 .priv = 0},
303}; 332};
304 333
334static const u8 sn_adcm1700[0x1c] = {
335/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
336 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
337/* reg8 reg9 rega regb regc regd rege regf */
338 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
340 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
341/* reg18 reg19 reg1a reg1b */
342 0x06, 0x00, 0x00, 0x00
343};
344
305/*Data from sn9c102p+hv7131r */ 345/*Data from sn9c102p+hv7131r */
306static const u8 sn_hv7131[0x1c] = { 346static const u8 sn_hv7131[0x1c] = {
307/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 347/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
@@ -415,6 +455,7 @@ static const u8 sn_sp80708[0x1c] = {
415 455
416/* sequence specific to the sensors - !! index = SENSOR_xxx */ 456/* sequence specific to the sensors - !! index = SENSOR_xxx */
417static const u8 *sn_tb[] = { 457static const u8 *sn_tb[] = {
458 sn_adcm1700,
418 sn_hv7131, 459 sn_hv7131,
419 sn_mi0360, 460 sn_mi0360,
420 sn_mo4000, 461 sn_mo4000,
@@ -432,6 +473,11 @@ static const u8 gamma_def[17] = {
432 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 473 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
433 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 474 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
434}; 475};
476/* gamma for sensor ADCM1700 */
477static const u8 gamma_spec_0[17] = {
478 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
479 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
480};
435/* gamma for sensors HV7131R and MT9V111 */ 481/* gamma for sensors HV7131R and MT9V111 */
436static const u8 gamma_spec_1[17] = { 482static const u8 gamma_spec_1[17] = {
437 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, 483 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
@@ -450,6 +496,42 @@ static const u8 reg84[] = {
450 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ 496 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
451 0x00, 0x00, 0x00 /* YUV offsets */ 497 0x00, 0x00, 0x00 /* YUV offsets */
452}; 498};
499static const u8 adcm1700_sensor_init[][8] = {
500 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
502 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
503 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
504 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
505 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
506 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
507 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
508 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
509 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
510 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
511 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
512 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
513 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
514 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
515 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
516 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {}
518};
519static const u8 adcm1700_sensor_param1[][8] = {
520 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
521 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
522
523 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
524 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
525 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
526 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
527 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
528
529 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
530 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
531 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
532 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
533 {}
534};
453static const u8 hv7131r_sensor_init[][8] = { 535static const u8 hv7131r_sensor_init[][8] = {
454 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 536 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
455 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, 537 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
@@ -986,17 +1068,18 @@ static const u8 sp80708_sensor_param1[][8] = {
986 {} 1068 {}
987}; 1069};
988 1070
989static const u8 (*sensor_init[10])[8] = { 1071static const u8 (*sensor_init[11])[8] = {
990 hv7131r_sensor_init, /* HV7131R 0 */ 1072 adcm1700_sensor_init, /* ADCM1700 0 */
991 mi0360_sensor_init, /* MI0360 1 */ 1073 hv7131r_sensor_init, /* HV7131R 1 */
992 mo4000_sensor_init, /* MO4000 2 */ 1074 mi0360_sensor_init, /* MI0360 2 */
993 mt9v111_sensor_init, /* MT9V111 3 */ 1075 mo4000_sensor_init, /* MO4000 3 */
994 om6802_sensor_init, /* OM6802 4 */ 1076 mt9v111_sensor_init, /* MT9V111 4 */
995 ov7630_sensor_init, /* OV7630 5 */ 1077 om6802_sensor_init, /* OM6802 5 */
996 ov7648_sensor_init, /* OV7648 6 */ 1078 ov7630_sensor_init, /* OV7630 6 */
997 ov7660_sensor_init, /* OV7660 7 */ 1079 ov7648_sensor_init, /* OV7648 7 */
998 po1030_sensor_init, /* PO1030 8 */ 1080 ov7660_sensor_init, /* OV7660 8 */
999 sp80708_sensor_init, /* SP80708 9 */ 1081 po1030_sensor_init, /* PO1030 9 */
1082 sp80708_sensor_init, /* SP80708 10 */
1000}; 1083};
1001 1084
1002/* read <len> bytes to gspca_dev->usb_buf */ 1085/* read <len> bytes to gspca_dev->usb_buf */
@@ -1064,6 +1147,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1064 1147
1065 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); 1148 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
1066 switch (sd->sensor) { 1149 switch (sd->sensor) {
1150 case SENSOR_ADCM1700:
1067 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */ 1151 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */
1068 gspca_dev->usb_buf[0] = 0x80 | (2 << 4); 1152 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1069 break; 1153 break;
@@ -1110,6 +1194,7 @@ static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1110 u8 mode[8]; 1194 u8 mode[8];
1111 1195
1112 switch (sd->sensor) { 1196 switch (sd->sensor) {
1197 case SENSOR_ADCM1700:
1113 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */ 1198 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */
1114 mode[0] = 0x80 | 0x10; 1199 mode[0] = 0x80 | 0x10;
1115 break; 1200 break;
@@ -1260,7 +1345,8 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1260 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; 1345 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1261 static const u8 regd4[] = {0x60, 0x00, 0x00}; 1346 static const u8 regd4[] = {0x60, 0x00, 0x00};
1262 1347
1263 reg_w1(gspca_dev, 0xf1, 0x00); 1348 /* sensor clock already enabled in sd_init */
1349 /* reg_w1(gspca_dev, 0xf1, 0x00); */
1264 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 1350 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1265 1351
1266 /* configure gpio */ 1352 /* configure gpio */
@@ -1284,6 +1370,12 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1284 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 1370 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1285 1371
1286 switch (sd->sensor) { 1372 switch (sd->sensor) {
1373 case SENSOR_ADCM1700:
1374 reg_w1(gspca_dev, 0x01, 0x43);
1375 reg_w1(gspca_dev, 0x17, 0x62);
1376 reg_w1(gspca_dev, 0x01, 0x42);
1377 reg_w1(gspca_dev, 0x01, 0x42);
1378 break;
1287 case SENSOR_MT9V111: 1379 case SENSOR_MT9V111:
1288 reg_w1(gspca_dev, 0x01, 0x61); 1380 reg_w1(gspca_dev, 0x01, 0x61);
1289 reg_w1(gspca_dev, 0x17, 0x61); 1381 reg_w1(gspca_dev, 0x17, 0x61);
@@ -1357,14 +1449,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
1357 struct sd *sd = (struct sd *) gspca_dev; 1449 struct sd *sd = (struct sd *) gspca_dev;
1358 struct cam *cam; 1450 struct cam *cam;
1359 1451
1360 cam = &gspca_dev->cam;
1361 cam->cam_mode = vga_mode;
1362 cam->nmodes = ARRAY_SIZE(vga_mode);
1363 cam->npkt = 24; /* 24 packets per ISOC message */
1364
1365 sd->bridge = id->driver_info >> 16; 1452 sd->bridge = id->driver_info >> 16;
1366 sd->sensor = id->driver_info; 1453 sd->sensor = id->driver_info;
1367 1454
1455 cam = &gspca_dev->cam;
1456 if (sd->sensor == SENSOR_ADCM1700) {
1457 cam->cam_mode = cif_mode;
1458 cam->nmodes = ARRAY_SIZE(cif_mode);
1459 } else {
1460 cam->cam_mode = vga_mode;
1461 cam->nmodes = ARRAY_SIZE(vga_mode);
1462 }
1463 cam->npkt = 24; /* 24 packets per ISOC message */
1464
1368 sd->brightness = BRIGHTNESS_DEF; 1465 sd->brightness = BRIGHTNESS_DEF;
1369 sd->contrast = CONTRAST_DEF; 1466 sd->contrast = CONTRAST_DEF;
1370 sd->colors = COLOR_DEF; 1467 sd->colors = COLOR_DEF;
@@ -1374,6 +1471,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
1374 sd->autogain = AUTOGAIN_DEF; 1471 sd->autogain = AUTOGAIN_DEF;
1375 sd->ag_cnt = -1; 1472 sd->ag_cnt = -1;
1376 sd->vflip = VFLIP_DEF; 1473 sd->vflip = VFLIP_DEF;
1474 switch (sd->sensor) {
1475 case SENSOR_OM6802:
1476 sd->sharpness = 0x10;
1477 break;
1478 default:
1479 sd->sharpness = SHARPNESS_DEF;
1480 break;
1481 }
1377 sd->infrared = INFRARED_DEF; 1482 sd->infrared = INFRARED_DEF;
1378 sd->freq = FREQ_DEF; 1483 sd->freq = FREQ_DEF;
1379 sd->quality = QUALITY_DEF; 1484 sd->quality = QUALITY_DEF;
@@ -1433,7 +1538,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
1433 break; 1538 break;
1434 } 1539 }
1435 1540
1436 reg_w1(gspca_dev, 0xf1, 0x01); 1541 /* Note we do not disable the sensor clock here (power saving mode),
1542 as that also disables the button on the cam. */
1543 reg_w1(gspca_dev, 0xf1, 0x00);
1437 1544
1438 /* set the i2c address */ 1545 /* set the i2c address */
1439 sn9c1xx = sn_tb[sd->sensor]; 1546 sn9c1xx = sn_tb[sd->sensor];
@@ -1543,6 +1650,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1543 1650
1544 k2 = ((int) sd->brightness - 0x8000) >> 10; 1651 k2 = ((int) sd->brightness - 0x8000) >> 10;
1545 switch (sd->sensor) { 1652 switch (sd->sensor) {
1653 case SENSOR_ADCM1700:
1654 if (k2 > 0x1f)
1655 k2 = 0; /* only positive Y offset */
1656 break;
1546 case SENSOR_HV7131R: 1657 case SENSOR_HV7131R:
1547 expo = sd->brightness << 4; 1658 expo = sd->brightness << 4;
1548 if (expo > 0x002dc6c0) 1659 if (expo > 0x002dc6c0)
@@ -1625,6 +1736,9 @@ static void setgamma(struct gspca_dev *gspca_dev)
1625 }; 1736 };
1626 1737
1627 switch (sd->sensor) { 1738 switch (sd->sensor) {
1739 case SENSOR_ADCM1700:
1740 gamma_base = gamma_spec_0;
1741 break;
1628 case SENSOR_HV7131R: 1742 case SENSOR_HV7131R:
1629 case SENSOR_MT9V111: 1743 case SENSOR_MT9V111:
1630 gamma_base = gamma_spec_1; 1744 gamma_base = gamma_spec_1;
@@ -1670,23 +1784,39 @@ static void setautogain(struct gspca_dev *gspca_dev)
1670 sd->ag_cnt = -1; 1784 sd->ag_cnt = -1;
1671} 1785}
1672 1786
1673/* ov7630/ov7648 only */ 1787/* hv7131r/ov7630/ov7648 only */
1674static void setvflip(struct sd *sd) 1788static void setvflip(struct sd *sd)
1675{ 1789{
1676 u8 comn; 1790 u8 comn;
1677 1791
1678 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX)) 1792 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
1679 return; 1793 return;
1680 if (sd->sensor == SENSOR_OV7630) { 1794 switch (sd->sensor) {
1795 case SENSOR_HV7131R:
1796 comn = 0x18; /* clkdiv = 1, ablcen = 1 */
1797 if (sd->vflip)
1798 comn |= 0x01;
1799 i2c_w1(&sd->gspca_dev, 0x01, comn); /* sctra */
1800 break;
1801 case SENSOR_OV7630:
1681 comn = 0x02; 1802 comn = 0x02;
1682 if (!sd->vflip) 1803 if (!sd->vflip)
1683 comn |= 0x80; 1804 comn |= 0x80;
1684 } else { 1805 i2c_w1(&sd->gspca_dev, 0x75, comn);
1806 break;
1807 default:
1808/* case SENSOR_OV7648: */
1685 comn = 0x06; 1809 comn = 0x06;
1686 if (sd->vflip) 1810 if (sd->vflip)
1687 comn |= 0x80; 1811 comn |= 0x80;
1812 i2c_w1(&sd->gspca_dev, 0x75, comn);
1813 break;
1688 } 1814 }
1689 i2c_w1(&sd->gspca_dev, 0x75, comn); 1815}
1816
1817static void setsharpness(struct sd *sd)
1818{
1819 reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
1690} 1820}
1691 1821
1692static void setinfrared(struct sd *sd) 1822static void setinfrared(struct sd *sd)
@@ -1804,6 +1934,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1804 int mode; 1934 int mode;
1805 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1935 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1806 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1936 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1937 static const u8 CA_adcm1700[] =
1938 { 0x14, 0xec, 0x0a, 0xf6 };
1807 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 1939 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1808 static const u8 CE_ov76xx[] = 1940 static const u8 CE_ov76xx[] =
1809 { 0x32, 0xdd, 0x32, 0xdd }; 1941 { 0x32, 0xdd, 0x32, 0xdd };
@@ -1824,6 +1956,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1824 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); 1956 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
1825 1957
1826 switch (sd->sensor) { 1958 switch (sd->sensor) {
1959 case SENSOR_ADCM1700:
1960 reg2 = 0x60;
1961 break;
1827 case SENSOR_OM6802: 1962 case SENSOR_OM6802:
1828 reg2 = 0x71; 1963 reg2 = 0x71;
1829 break; 1964 break;
@@ -1842,17 +1977,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
1842 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 1977 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1843 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]); 1978 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1844 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1979 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1845 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */ 1980 if (sd->sensor == SENSOR_ADCM1700) {
1846 reg_w1(gspca_dev, 0xd3, 0x50); 1981 reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
1982 reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
1983 } else {
1984 reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
1985 reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
1986 }
1847 reg_w1(gspca_dev, 0xc6, 0x00); 1987 reg_w1(gspca_dev, 0xc6, 0x00);
1848 reg_w1(gspca_dev, 0xc7, 0x00); 1988 reg_w1(gspca_dev, 0xc7, 0x00);
1849 reg_w1(gspca_dev, 0xc8, 0x50); 1989 if (sd->sensor == SENSOR_ADCM1700) {
1850 reg_w1(gspca_dev, 0xc9, 0x3c); 1990 reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
1991 reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
1992 } else {
1993 reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
1994 reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
1995 }
1851 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1852 switch (sd->sensor) { 1997 switch (sd->sensor) {
1853 case SENSOR_MT9V111: 1998 case SENSOR_MT9V111:
1854 reg17 = 0xe0; 1999 reg17 = 0xe0;
1855 break; 2000 break;
2001 case SENSOR_ADCM1700:
1856 case SENSOR_OV7630: 2002 case SENSOR_OV7630:
1857 reg17 = 0xe2; 2003 reg17 = 0xe2;
1858 break; 2004 break;
@@ -1870,44 +2016,39 @@ static int sd_start(struct gspca_dev *gspca_dev)
1870 break; 2016 break;
1871 } 2017 }
1872 reg_w1(gspca_dev, 0x17, reg17); 2018 reg_w1(gspca_dev, 0x17, reg17);
1873/* set reg1 was here */ 2019
1874 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */ 2020 reg_w1(gspca_dev, 0x05, 0x00); /* red */
1875 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ 2021 reg_w1(gspca_dev, 0x07, 0x00); /* green */
1876 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ 2022 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
1877 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 2023 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1878 2024
1879 setgamma(gspca_dev); 2025 setgamma(gspca_dev);
1880 2026
2027/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
1881 for (i = 0; i < 8; i++) 2028 for (i = 0; i < 8; i++)
1882 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 2029 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1883 switch (sd->sensor) { 2030 switch (sd->sensor) {
2031 case SENSOR_ADCM1700:
2032 case SENSOR_OV7660:
2033 case SENSOR_SP80708:
2034 reg_w1(gspca_dev, 0x9a, 0x05);
2035 break;
1884 case SENSOR_MT9V111: 2036 case SENSOR_MT9V111:
1885 reg_w1(gspca_dev, 0x9a, 0x07); 2037 reg_w1(gspca_dev, 0x9a, 0x07);
1886 reg_w1(gspca_dev, 0x99, 0x59);
1887 break;
1888 case SENSOR_OM6802:
1889 reg_w1(gspca_dev, 0x9a, 0x08);
1890 reg_w1(gspca_dev, 0x99, 0x10);
1891 break; 2038 break;
1892 case SENSOR_OV7648: 2039 case SENSOR_OV7648:
1893 reg_w1(gspca_dev, 0x9a, 0x0a); 2040 reg_w1(gspca_dev, 0x9a, 0x0a);
1894 reg_w1(gspca_dev, 0x99, 0x60);
1895 break;
1896 case SENSOR_OV7660:
1897 case SENSOR_SP80708:
1898 reg_w1(gspca_dev, 0x9a, 0x05);
1899 reg_w1(gspca_dev, 0x99, 0x59);
1900 break; 2041 break;
1901 default: 2042 default:
1902 reg_w1(gspca_dev, 0x9a, 0x08); 2043 reg_w1(gspca_dev, 0x9a, 0x08);
1903 reg_w1(gspca_dev, 0x99, 0x59);
1904 break; 2044 break;
1905 } 2045 }
2046 setsharpness(sd);
1906 2047
1907 reg_w(gspca_dev, 0x84, reg84, sizeof reg84); 2048 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1908 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */ 2049 reg_w1(gspca_dev, 0x05, 0x20); /* red */
1909 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ 2050 reg_w1(gspca_dev, 0x07, 0x20); /* green */
1910 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ 2051 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
1911 2052
1912 init = NULL; 2053 init = NULL;
1913 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 2054 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
@@ -1917,6 +2058,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
1917 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ 2058 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1918 reg17 = 0x61; /* 0x:20: enable sensor clock */ 2059 reg17 = 0x61; /* 0x:20: enable sensor clock */
1919 switch (sd->sensor) { 2060 switch (sd->sensor) {
2061 case SENSOR_ADCM1700:
2062 init = adcm1700_sensor_param1;
2063 reg1 = 0x46;
2064 reg17 = 0xe2;
2065 break;
1920 case SENSOR_MO4000: 2066 case SENSOR_MO4000:
1921 if (mode) { 2067 if (mode) {
1922/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ 2068/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
@@ -1940,7 +2086,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1940 reg17 = 0x64; /* 640 MCKSIZE */ 2086 reg17 = 0x64; /* 640 MCKSIZE */
1941 break; 2087 break;
1942 case SENSOR_OV7630: 2088 case SENSOR_OV7630:
1943 setvflip(sd);
1944 reg17 = 0xe2; 2089 reg17 = 0xe2;
1945 reg1 = 0x44; 2090 reg1 = 0x44;
1946 break; 2091 break;
@@ -1986,8 +2131,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
1986 } 2131 }
1987 2132
1988 reg_w(gspca_dev, 0xc0, C0, 6); 2133 reg_w(gspca_dev, 0xc0, C0, 6);
1989 reg_w(gspca_dev, 0xca, CA, 4); 2134 if (sd->sensor == SENSOR_ADCM1700)
2135 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2136 else
2137 reg_w(gspca_dev, 0xca, CA, 4);
1990 switch (sd->sensor) { 2138 switch (sd->sensor) {
2139 case SENSOR_ADCM1700:
1991 case SENSOR_OV7630: 2140 case SENSOR_OV7630:
1992 case SENSOR_OV7648: 2141 case SENSOR_OV7648:
1993 case SENSOR_OV7660: 2142 case SENSOR_OV7660:
@@ -2008,11 +2157,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2008 reg_w1(gspca_dev, 0x17, reg17); 2157 reg_w1(gspca_dev, 0x17, reg17);
2009 reg_w1(gspca_dev, 0x01, reg1); 2158 reg_w1(gspca_dev, 0x01, reg1);
2010 2159
2011 switch (sd->sensor) { 2160 setvflip(sd);
2012 case SENSOR_OV7630:
2013 setvflip(sd);
2014 break;
2015 }
2016 setbrightness(gspca_dev); 2161 setbrightness(gspca_dev);
2017 setcontrast(gspca_dev); 2162 setcontrast(gspca_dev);
2018 setautogain(gspca_dev); 2163 setautogain(gspca_dev);
@@ -2056,7 +2201,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2056 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 2201 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2057 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2202 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2058 reg_w1(gspca_dev, 0x01, data); 2203 reg_w1(gspca_dev, 0x01, data);
2059 reg_w1(gspca_dev, 0xf1, 0x00); 2204 /* Don't disable sensor clock as that disables the button on the cam */
2205 /* reg_w1(gspca_dev, 0xf1, 0x01); */
2060} 2206}
2061 2207
2062static void sd_stop0(struct gspca_dev *gspca_dev) 2208static void sd_stop0(struct gspca_dev *gspca_dev)
@@ -2288,6 +2434,24 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2288 return 0; 2434 return 0;
2289} 2435}
2290 2436
2437static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2438{
2439 struct sd *sd = (struct sd *) gspca_dev;
2440
2441 sd->sharpness = val;
2442 if (gspca_dev->streaming)
2443 setsharpness(sd);
2444 return 0;
2445}
2446
2447static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2448{
2449 struct sd *sd = (struct sd *) gspca_dev;
2450
2451 *val = sd->sharpness;
2452 return 0;
2453}
2454
2291static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) 2455static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2292{ 2456{
2293 struct sd *sd = (struct sd *) gspca_dev; 2457 struct sd *sd = (struct sd *) gspca_dev;
@@ -2391,6 +2555,25 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
2391 return -EINVAL; 2555 return -EINVAL;
2392} 2556}
2393 2557
2558#ifdef CONFIG_INPUT
2559static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2560 u8 *data, /* interrupt packet data */
2561 int len) /* interrupt packet length */
2562{
2563 int ret = -EINVAL;
2564
2565 if (len == 1 && data[0] == 1) {
2566 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2567 input_sync(gspca_dev->input_dev);
2568 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2569 input_sync(gspca_dev->input_dev);
2570 ret = 0;
2571 }
2572
2573 return ret;
2574}
2575#endif
2576
2394/* sub-driver description */ 2577/* sub-driver description */
2395static const struct sd_desc sd_desc = { 2578static const struct sd_desc sd_desc = {
2396 .name = MODULE_NAME, 2579 .name = MODULE_NAME,
@@ -2406,6 +2589,9 @@ static const struct sd_desc sd_desc = {
2406 .get_jcomp = sd_get_jcomp, 2589 .get_jcomp = sd_get_jcomp,
2407 .set_jcomp = sd_set_jcomp, 2590 .set_jcomp = sd_set_jcomp,
2408 .querymenu = sd_querymenu, 2591 .querymenu = sd_querymenu,
2592#ifdef CONFIG_INPUT
2593 .int_pkt_scan = sd_int_pkt_scan,
2594#endif
2409}; 2595};
2410 2596
2411/* -- module initialisation -- */ 2597/* -- module initialisation -- */
@@ -2472,6 +2658,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2472/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/ 2658/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/
2473 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ 2659 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2474 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ 2660 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
2661 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
2475 {} 2662 {}
2476}; 2663};
2477MODULE_DEVICE_TABLE(usb, device_table); 2664MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index fe46868a87f2..b866c73c97db 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -68,7 +68,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 68static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 69static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
70 70
71static struct ctrl sd_ctrls[] = { 71static const struct ctrl sd_ctrls[] = {
72 { 72 {
73 { 73 {
74 .id = V4L2_CID_BRIGHTNESS, 74 .id = V4L2_CID_BRIGHTNESS,
@@ -1047,7 +1047,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1047} 1047}
1048 1048
1049/* sub-driver description */ 1049/* sub-driver description */
1050static struct sd_desc sd_desc = { 1050static const struct sd_desc sd_desc = {
1051 .name = MODULE_NAME, 1051 .name = MODULE_NAME,
1052 .ctrls = sd_ctrls, 1052 .ctrls = sd_ctrls,
1053 .nctrls = ARRAY_SIZE(sd_ctrls), 1053 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 6761a3048a98..c99333933e32 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -59,7 +59,7 @@ static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
59static int sd_setred_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); 60static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
61 61
62static struct ctrl sd_ctrls[] = { 62static const struct ctrl sd_ctrls[] = {
63#define MY_BRIGHTNESS 0 63#define MY_BRIGHTNESS 0
64 { 64 {
65 { 65 {
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 0f9232ff1281..c576eed73abe 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -42,7 +42,7 @@ struct sd {
42static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 42static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
43static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 43static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
44 44
45static struct ctrl sd_ctrls[] = { 45static const struct ctrl sd_ctrls[] = {
46 { 46 {
47 { 47 {
48 .id = V4L2_CID_BRIGHTNESS, 48 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 39257e4e074f..89fec4c500af 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -51,7 +51,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); 51static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); 52static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
53 53
54static struct ctrl sd_ctrls[] = { 54static const struct ctrl sd_ctrls[] = {
55#define SD_BRIGHTNESS 0 55#define SD_BRIGHTNESS 0
56 { 56 {
57 { 57 {
@@ -673,7 +673,7 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
673} 673}
674 674
675/* sub-driver description */ 675/* sub-driver description */
676static struct sd_desc sd_desc = { 676static const struct sd_desc sd_desc = {
677 .name = MODULE_NAME, 677 .name = MODULE_NAME,
678 .ctrls = sd_ctrls, 678 .ctrls = sd_ctrls,
679 .nctrls = ARRAY_SIZE(sd_ctrls), 679 .nctrls = ARRAY_SIZE(sd_ctrls),
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 4d8e6cf75d55..15b2eef8a3f6 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -45,7 +45,7 @@ struct sd {
45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
47 47
48static struct ctrl sd_ctrls[] = { 48static const struct ctrl sd_ctrls[] = {
49 { 49 {
50 { 50 {
51 .id = V4L2_CID_BRIGHTNESS, 51 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 58c2f0039af1..dc7f2b0fbc79 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -922,7 +922,7 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
922} 922}
923 923
924/* control tables */ 924/* control tables */
925static struct ctrl sd_ctrls_12a[] = { 925static const struct ctrl sd_ctrls_12a[] = {
926 { 926 {
927 { 927 {
928 .id = V4L2_CID_HUE, 928 .id = V4L2_CID_HUE,
@@ -964,7 +964,7 @@ static struct ctrl sd_ctrls_12a[] = {
964 }, 964 },
965}; 965};
966 966
967static struct ctrl sd_ctrls_72a[] = { 967static const struct ctrl sd_ctrls_72a[] = {
968 { 968 {
969 { 969 {
970 .id = V4L2_CID_HUE, 970 .id = V4L2_CID_HUE,
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index d70b156872d6..e64662052992 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -47,6 +47,7 @@ MODULE_LICENSE("GPL");
47 47
48/* Commands. These go in the "value" slot. */ 48/* Commands. These go in the "value" slot. */
49#define SQ905C_CLEAR 0xa0 /* clear everything */ 49#define SQ905C_CLEAR 0xa0 /* clear everything */
50#define SQ905C_GET_ID 0x14f4 /* Read version number */
50#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */ 51#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */
51#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */ 52#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */
52#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */ 53#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */
@@ -101,6 +102,26 @@ static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
101 return 0; 102 return 0;
102} 103}
103 104
105static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index,
106 int size)
107{
108 int ret;
109
110 ret = usb_control_msg(gspca_dev->dev,
111 usb_rcvctrlpipe(gspca_dev->dev, 0),
112 USB_REQ_SYNCH_FRAME, /* request */
113 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
114 command, index, gspca_dev->usb_buf, size,
115 SQ905C_CMD_TIMEOUT);
116 if (ret < 0) {
117 PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
118 __func__, ret);
119 return ret;
120 }
121
122 return 0;
123}
124
104/* This function is called as a workqueue function and runs whenever the camera 125/* This function is called as a workqueue function and runs whenever the camera
105 * is streaming data. Because it is a workqueue function it is allowed to sleep 126 * is streaming data. Because it is a workqueue function it is allowed to sleep
106 * so we can use synchronous USB calls. To avoid possible collisions with other 127 * so we can use synchronous USB calls. To avoid possible collisions with other
@@ -183,13 +204,34 @@ static int sd_config(struct gspca_dev *gspca_dev,
183{ 204{
184 struct cam *cam = &gspca_dev->cam; 205 struct cam *cam = &gspca_dev->cam;
185 struct sd *dev = (struct sd *) gspca_dev; 206 struct sd *dev = (struct sd *) gspca_dev;
207 int ret;
186 208
187 PDEBUG(D_PROBE, 209 PDEBUG(D_PROBE,
188 "SQ9050 camera detected" 210 "SQ9050 camera detected"
189 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 211 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
212
213 ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0);
214 if (ret < 0) {
215 PDEBUG(D_ERR, "Get version command failed");
216 return ret;
217 }
218
219 ret = sq905c_read(gspca_dev, 0xf5, 0, 20);
220 if (ret < 0) {
221 PDEBUG(D_ERR, "Reading version command failed");
222 return ret;
223 }
224 /* Note we leave out the usb id and the manufacturing date */
225 PDEBUG(D_PROBE,
226 "SQ9050 ID string: %02x - %02x %02x %02x %02x %02x %02x",
227 gspca_dev->usb_buf[3],
228 gspca_dev->usb_buf[14], gspca_dev->usb_buf[15],
229 gspca_dev->usb_buf[16], gspca_dev->usb_buf[17],
230 gspca_dev->usb_buf[18], gspca_dev->usb_buf[19]);
231
190 cam->cam_mode = sq905c_mode; 232 cam->cam_mode = sq905c_mode;
191 cam->nmodes = 2; 233 cam->nmodes = 2;
192 if (id->idProduct == 0x9050) 234 if (gspca_dev->usb_buf[15] == 0)
193 cam->nmodes = 1; 235 cam->nmodes = 1;
194 /* We don't use the buffer gspca allocates so make it small. */ 236 /* We don't use the buffer gspca allocates so make it small. */
195 cam->bulk_size = 32; 237 cam->bulk_size = 32;
@@ -258,6 +300,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
258static const __devinitdata struct usb_device_id device_table[] = { 300static const __devinitdata struct usb_device_id device_table[] = {
259 {USB_DEVICE(0x2770, 0x905c)}, 301 {USB_DEVICE(0x2770, 0x905c)},
260 {USB_DEVICE(0x2770, 0x9050)}, 302 {USB_DEVICE(0x2770, 0x9050)},
303 {USB_DEVICE(0x2770, 0x9052)},
261 {USB_DEVICE(0x2770, 0x913d)}, 304 {USB_DEVICE(0x2770, 0x913d)},
262 {} 305 {}
263}; 306};
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 2e2935532d99..0fb534210a2c 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -53,7 +53,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 53static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 54static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
55 55
56static struct ctrl sd_ctrls[] = { 56static const struct ctrl sd_ctrls[] = {
57 { 57 {
58 { 58 {
59 .id = V4L2_CID_BRIGHTNESS, 59 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
index 2a69d7ccb50d..e50dd7693f74 100644
--- a/drivers/media/video/gspca/stv0680.c
+++ b/drivers/media/video/gspca/stv0680.c
@@ -45,7 +45,7 @@ struct sd {
45}; 45};
46 46
47/* V4L2 controls supported by the driver */ 47/* V4L2 controls supported by the driver */
48static struct ctrl sd_ctrls[] = { 48static const struct ctrl sd_ctrls[] = {
49}; 49};
50 50
51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, 51static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
@@ -53,24 +53,28 @@ static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
53{ 53{
54 int ret = -1; 54 int ret = -1;
55 u8 req_type = 0; 55 u8 req_type = 0;
56 unsigned int pipe = 0;
56 57
57 switch (set) { 58 switch (set) {
58 case 0: /* 0xc1 */ 59 case 0: /* 0xc1 */
59 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; 60 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
61 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
60 break; 62 break;
61 case 1: /* 0x41 */ 63 case 1: /* 0x41 */
62 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; 64 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
65 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
63 break; 66 break;
64 case 2: /* 0x80 */ 67 case 2: /* 0x80 */
65 req_type = USB_DIR_IN | USB_RECIP_DEVICE; 68 req_type = USB_DIR_IN | USB_RECIP_DEVICE;
69 pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
66 break; 70 break;
67 case 3: /* 0x40 */ 71 case 3: /* 0x40 */
68 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; 72 req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
73 pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
69 break; 74 break;
70 } 75 }
71 76
72 ret = usb_control_msg(gspca_dev->dev, 77 ret = usb_control_msg(gspca_dev->dev, pipe,
73 usb_rcvctrlpipe(gspca_dev->dev, 0),
74 req, req_type, 78 req, req_type,
75 val, 0, gspca_dev->usb_buf, size, 500); 79 val, 0, gspca_dev->usb_buf, size, 500);
76 80
@@ -138,6 +142,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
138 struct sd *sd = (struct sd *) gspca_dev; 142 struct sd *sd = (struct sd *) gspca_dev;
139 struct cam *cam = &gspca_dev->cam; 143 struct cam *cam = &gspca_dev->cam;
140 144
145 /* Give the camera some time to settle, otherwise initalization will
146 fail on hotplug, and yes it really needs a full second. */
147 msleep(1000);
148
141 /* ping camera to be sure STV0680 is present */ 149 /* ping camera to be sure STV0680 is present */
142 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 || 150 if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
143 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) { 151 gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
@@ -169,6 +177,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
169 PDEBUG(D_PROBE, "Camera supports CIF mode"); 177 PDEBUG(D_PROBE, "Camera supports CIF mode");
170 if (gspca_dev->usb_buf[7] & 0x02) 178 if (gspca_dev->usb_buf[7] & 0x02)
171 PDEBUG(D_PROBE, "Camera supports VGA mode"); 179 PDEBUG(D_PROBE, "Camera supports VGA mode");
180 if (gspca_dev->usb_buf[7] & 0x04)
181 PDEBUG(D_PROBE, "Camera supports QCIF mode");
172 if (gspca_dev->usb_buf[7] & 0x08) 182 if (gspca_dev->usb_buf[7] & 0x08)
173 PDEBUG(D_PROBE, "Camera supports QVGA mode"); 183 PDEBUG(D_PROBE, "Camera supports QVGA mode");
174 184
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 5d0241bb1611..af73da34c83f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -27,6 +27,7 @@
27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web 27 * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web
28 */ 28 */
29 29
30#include <linux/input.h>
30#include "stv06xx_sensor.h" 31#include "stv06xx_sensor.h"
31 32
32MODULE_AUTHOR("Erik Andrén"); 33MODULE_AUTHOR("Erik Andrén");
@@ -219,6 +220,7 @@ static void stv06xx_dump_bridge(struct sd *sd)
219 info("Read 0x%x from address 0x%x", data, i); 220 info("Read 0x%x from address 0x%x", data, i);
220 } 221 }
221 222
223 info("Testing stv06xx bridge registers for writability");
222 for (i = 0x1400; i < 0x160f; i++) { 224 for (i = 0x1400; i < 0x160f; i++) {
223 stv06xx_read_bridge(sd, i, &data); 225 stv06xx_read_bridge(sd, i, &data);
224 buf = data; 226 buf = data;
@@ -229,7 +231,7 @@ static void stv06xx_dump_bridge(struct sd *sd)
229 info("Register 0x%x is read/write", i); 231 info("Register 0x%x is read/write", i);
230 else if (data != buf) 232 else if (data != buf)
231 info("Register 0x%x is read/write," 233 info("Register 0x%x is read/write,"
232 "but only partially", i); 234 " but only partially", i);
233 else 235 else
234 info("Register 0x%x is read-only", i); 236 info("Register 0x%x is read-only", i);
235 237
@@ -426,6 +428,29 @@ frame_data:
426 } 428 }
427} 429}
428 430
431#ifdef CONFIG_INPUT
432static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
433 u8 *data, /* interrupt packet data */
434 int len) /* interrupt packet length */
435{
436 int ret = -EINVAL;
437
438 if (len == 1 && data[0] == 0x80) {
439 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
440 input_sync(gspca_dev->input_dev);
441 ret = 0;
442 }
443
444 if (len == 1 && data[0] == 0x88) {
445 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
446 input_sync(gspca_dev->input_dev);
447 ret = 0;
448 }
449
450 return ret;
451}
452#endif
453
429static int stv06xx_config(struct gspca_dev *gspca_dev, 454static int stv06xx_config(struct gspca_dev *gspca_dev,
430 const struct usb_device_id *id); 455 const struct usb_device_id *id);
431 456
@@ -436,7 +461,10 @@ static const struct sd_desc sd_desc = {
436 .init = stv06xx_init, 461 .init = stv06xx_init,
437 .start = stv06xx_start, 462 .start = stv06xx_start,
438 .stopN = stv06xx_stopN, 463 .stopN = stv06xx_stopN,
439 .pkt_scan = stv06xx_pkt_scan 464 .pkt_scan = stv06xx_pkt_scan,
465#ifdef CONFIG_INPUT
466 .int_pkt_scan = sd_int_pkt_scan,
467#endif
440}; 468};
441 469
442/* This function is called at probe time */ 470/* This function is called at probe time */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 306b7d75b4aa..0c786e00ebcf 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -67,7 +67,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 67static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 68static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
69 69
70static struct ctrl sd_ctrls[] = { 70static const struct ctrl sd_ctrls[] = {
71 { 71 {
72 { 72 {
73 .id = V4L2_CID_BRIGHTNESS, 73 .id = V4L2_CID_BRIGHTNESS,
@@ -267,142 +267,6 @@ static const struct cmd spca504A_clicksmart420_open_data[] = {
267 {0x06, 0x0000, 0x0000}, 267 {0x06, 0x0000, 0x0000},
268 {0x00, 0x0004, 0x2880}, 268 {0x00, 0x0004, 0x2880},
269 {0x00, 0x0001, 0x2881}, 269 {0x00, 0x0001, 0x2881},
270/* look like setting a qTable */
271 {0x00, 0x0006, 0x2800},
272 {0x00, 0x0004, 0x2801},
273 {0x00, 0x0004, 0x2802},
274 {0x00, 0x0006, 0x2803},
275 {0x00, 0x000a, 0x2804},
276 {0x00, 0x0010, 0x2805},
277 {0x00, 0x0014, 0x2806},
278 {0x00, 0x0018, 0x2807},
279 {0x00, 0x0005, 0x2808},
280 {0x00, 0x0005, 0x2809},
281 {0x00, 0x0006, 0x280a},
282 {0x00, 0x0008, 0x280b},
283 {0x00, 0x000a, 0x280c},
284 {0x00, 0x0017, 0x280d},
285 {0x00, 0x0018, 0x280e},
286 {0x00, 0x0016, 0x280f},
287
288 {0x00, 0x0006, 0x2810},
289 {0x00, 0x0005, 0x2811},
290 {0x00, 0x0006, 0x2812},
291 {0x00, 0x000a, 0x2813},
292 {0x00, 0x0010, 0x2814},
293 {0x00, 0x0017, 0x2815},
294 {0x00, 0x001c, 0x2816},
295 {0x00, 0x0016, 0x2817},
296 {0x00, 0x0006, 0x2818},
297 {0x00, 0x0007, 0x2819},
298 {0x00, 0x0009, 0x281a},
299 {0x00, 0x000c, 0x281b},
300 {0x00, 0x0014, 0x281c},
301 {0x00, 0x0023, 0x281d},
302 {0x00, 0x0020, 0x281e},
303 {0x00, 0x0019, 0x281f},
304
305 {0x00, 0x0007, 0x2820},
306 {0x00, 0x0009, 0x2821},
307 {0x00, 0x000f, 0x2822},
308 {0x00, 0x0016, 0x2823},
309 {0x00, 0x001b, 0x2824},
310 {0x00, 0x002c, 0x2825},
311 {0x00, 0x0029, 0x2826},
312 {0x00, 0x001f, 0x2827},
313 {0x00, 0x000a, 0x2828},
314 {0x00, 0x000e, 0x2829},
315 {0x00, 0x0016, 0x282a},
316 {0x00, 0x001a, 0x282b},
317 {0x00, 0x0020, 0x282c},
318 {0x00, 0x002a, 0x282d},
319 {0x00, 0x002d, 0x282e},
320 {0x00, 0x0025, 0x282f},
321
322 {0x00, 0x0014, 0x2830},
323 {0x00, 0x001a, 0x2831},
324 {0x00, 0x001f, 0x2832},
325 {0x00, 0x0023, 0x2833},
326 {0x00, 0x0029, 0x2834},
327 {0x00, 0x0030, 0x2835},
328 {0x00, 0x0030, 0x2836},
329 {0x00, 0x0028, 0x2837},
330 {0x00, 0x001d, 0x2838},
331 {0x00, 0x0025, 0x2839},
332 {0x00, 0x0026, 0x283a},
333 {0x00, 0x0027, 0x283b},
334 {0x00, 0x002d, 0x283c},
335 {0x00, 0x0028, 0x283d},
336 {0x00, 0x0029, 0x283e},
337 {0x00, 0x0028, 0x283f},
338
339 {0x00, 0x0007, 0x2840},
340 {0x00, 0x0007, 0x2841},
341 {0x00, 0x000a, 0x2842},
342 {0x00, 0x0013, 0x2843},
343 {0x00, 0x0028, 0x2844},
344 {0x00, 0x0028, 0x2845},
345 {0x00, 0x0028, 0x2846},
346 {0x00, 0x0028, 0x2847},
347 {0x00, 0x0007, 0x2848},
348 {0x00, 0x0008, 0x2849},
349 {0x00, 0x000a, 0x284a},
350 {0x00, 0x001a, 0x284b},
351 {0x00, 0x0028, 0x284c},
352 {0x00, 0x0028, 0x284d},
353 {0x00, 0x0028, 0x284e},
354 {0x00, 0x0028, 0x284f},
355
356 {0x00, 0x000a, 0x2850},
357 {0x00, 0x000a, 0x2851},
358 {0x00, 0x0016, 0x2852},
359 {0x00, 0x0028, 0x2853},
360 {0x00, 0x0028, 0x2854},
361 {0x00, 0x0028, 0x2855},
362 {0x00, 0x0028, 0x2856},
363 {0x00, 0x0028, 0x2857},
364 {0x00, 0x0013, 0x2858},
365 {0x00, 0x001a, 0x2859},
366 {0x00, 0x0028, 0x285a},
367 {0x00, 0x0028, 0x285b},
368 {0x00, 0x0028, 0x285c},
369 {0x00, 0x0028, 0x285d},
370 {0x00, 0x0028, 0x285e},
371 {0x00, 0x0028, 0x285f},
372
373 {0x00, 0x0028, 0x2860},
374 {0x00, 0x0028, 0x2861},
375 {0x00, 0x0028, 0x2862},
376 {0x00, 0x0028, 0x2863},
377 {0x00, 0x0028, 0x2864},
378 {0x00, 0x0028, 0x2865},
379 {0x00, 0x0028, 0x2866},
380 {0x00, 0x0028, 0x2867},
381 {0x00, 0x0028, 0x2868},
382 {0x00, 0x0028, 0x2869},
383 {0x00, 0x0028, 0x286a},
384 {0x00, 0x0028, 0x286b},
385 {0x00, 0x0028, 0x286c},
386 {0x00, 0x0028, 0x286d},
387 {0x00, 0x0028, 0x286e},
388 {0x00, 0x0028, 0x286f},
389
390 {0x00, 0x0028, 0x2870},
391 {0x00, 0x0028, 0x2871},
392 {0x00, 0x0028, 0x2872},
393 {0x00, 0x0028, 0x2873},
394 {0x00, 0x0028, 0x2874},
395 {0x00, 0x0028, 0x2875},
396 {0x00, 0x0028, 0x2876},
397 {0x00, 0x0028, 0x2877},
398 {0x00, 0x0028, 0x2878},
399 {0x00, 0x0028, 0x2879},
400 {0x00, 0x0028, 0x287a},
401 {0x00, 0x0028, 0x287b},
402 {0x00, 0x0028, 0x287c},
403 {0x00, 0x0028, 0x287d},
404 {0x00, 0x0028, 0x287e},
405 {0x00, 0x0028, 0x287f},
406 270
407 {0xa0, 0x0000, 0x0503}, 271 {0xa0, 0x0000, 0x0503},
408}; 272};
@@ -622,6 +486,20 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
622 PDEBUG(D_FRAM, "after wait 0x%04x", notdone); 486 PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
623} 487}
624 488
489static void spca504_read_info(struct gspca_dev *gspca_dev)
490{
491 int i;
492 u8 info[6];
493
494 for (i = 0; i < 6; i++)
495 info[i] = reg_r_1(gspca_dev, i);
496 PDEBUG(D_STREAM,
497 "Read info: %d %d %d %d %d %d."
498 " Should be 1,0,2,2,0,0",
499 info[0], info[1], info[2],
500 info[3], info[4], info[5]);
501}
502
625static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, 503static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
626 u8 req, 504 u8 req,
627 u16 idx, u16 val, u16 endcode, u8 count) 505 u16 idx, u16 val, u16 endcode, u8 count)
@@ -881,8 +759,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
881static int sd_init(struct gspca_dev *gspca_dev) 759static int sd_init(struct gspca_dev *gspca_dev)
882{ 760{
883 struct sd *sd = (struct sd *) gspca_dev; 761 struct sd *sd = (struct sd *) gspca_dev;
884 int i;
885 u8 info[6];
886 762
887 switch (sd->bridge) { 763 switch (sd->bridge) {
888 case BRIDGE_SPCA504B: 764 case BRIDGE_SPCA504B:
@@ -924,15 +800,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
924/* case BRIDGE_SPCA504: */ 800/* case BRIDGE_SPCA504: */
925 PDEBUG(D_STREAM, "Opening SPCA504"); 801 PDEBUG(D_STREAM, "Opening SPCA504");
926 if (sd->subtype == AiptekMiniPenCam13) { 802 if (sd->subtype == AiptekMiniPenCam13) {
927 /*****************************/ 803 spca504_read_info(gspca_dev);
928 for (i = 0; i < 6; i++) 804
929 info[i] = reg_r_1(gspca_dev, i);
930 PDEBUG(D_STREAM,
931 "Read info: %d %d %d %d %d %d."
932 " Should be 1,0,2,2,0,0",
933 info[0], info[1], info[2],
934 info[3], info[4], info[5]);
935 /* spca504a aiptek */
936 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 805 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
937 spca504A_acknowledged_command(gspca_dev, 0x24, 806 spca504A_acknowledged_command(gspca_dev, 0x24,
938 8, 3, 0x9e, 1); 807 8, 3, 0x9e, 1);
@@ -971,8 +840,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
971{ 840{
972 struct sd *sd = (struct sd *) gspca_dev; 841 struct sd *sd = (struct sd *) gspca_dev;
973 int enable; 842 int enable;
974 int i;
975 u8 info[6];
976 843
977 /* create the JPEG header */ 844 /* create the JPEG header */
978 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 845 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
@@ -1008,14 +875,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1008 break; 875 break;
1009 case BRIDGE_SPCA504: 876 case BRIDGE_SPCA504:
1010 if (sd->subtype == AiptekMiniPenCam13) { 877 if (sd->subtype == AiptekMiniPenCam13) {
1011 for (i = 0; i < 6; i++) 878 spca504_read_info(gspca_dev);
1012 info[i] = reg_r_1(gspca_dev, i); 879
1013 PDEBUG(D_STREAM,
1014 "Read info: %d %d %d %d %d %d."
1015 " Should be 1,0,2,2,0,0",
1016 info[0], info[1], info[2],
1017 info[3], info[4], info[5]);
1018 /* spca504a aiptek */
1019 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 880 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1020 spca504A_acknowledged_command(gspca_dev, 0x24, 881 spca504A_acknowledged_command(gspca_dev, 0x24,
1021 8, 3, 0x9e, 1); 882 8, 3, 0x9e, 1);
@@ -1026,13 +887,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1026 0, 0, 0x9d, 1); 887 0, 0, 0x9d, 1);
1027 } else { 888 } else {
1028 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 889 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1029 for (i = 0; i < 6; i++) 890 spca504_read_info(gspca_dev);
1030 info[i] = reg_r_1(gspca_dev, i);
1031 PDEBUG(D_STREAM,
1032 "Read info: %d %d %d %d %d %d."
1033 " Should be 1,0,2,2,0,0",
1034 info[0], info[1], info[2],
1035 info[3], info[4], info[5]);
1036 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 891 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1037 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); 892 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1038 } 893 }
@@ -1336,6 +1191,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1336 {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)}, 1191 {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1337 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)}, 1192 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1338 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)}, 1193 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1194 {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1339 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)}, 1195 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1340 {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)}, 1196 {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1341 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)}, 1197 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 55ef6a744427..668a7536af90 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -52,6 +52,7 @@ struct sd {
52#define SENSOR_OM6802 0 52#define SENSOR_OM6802 0
53#define SENSOR_OTHER 1 53#define SENSOR_OTHER 1
54#define SENSOR_TAS5130A 2 54#define SENSOR_TAS5130A 2
55#define SENSOR_LT168G 3 /* must verify if this is the actual model */
55}; 56};
56 57
57/* V4L2 controls supported by the driver */ 58/* V4L2 controls supported by the driver */
@@ -78,7 +79,7 @@ static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_querymenu(struct gspca_dev *gspca_dev, 79static int sd_querymenu(struct gspca_dev *gspca_dev,
79 struct v4l2_querymenu *menu); 80 struct v4l2_querymenu *menu);
80 81
81static struct ctrl sd_ctrls[] = { 82static const struct ctrl sd_ctrls[] = {
82 { 83 {
83 { 84 {
84 .id = V4L2_CID_BRIGHTNESS, 85 .id = V4L2_CID_BRIGHTNESS,
@@ -306,6 +307,17 @@ static const u8 n4_tas5130a[] = {
306 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8, 307 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
307 0xc6, 0xda 308 0xc6, 0xda
308}; 309};
310static const u8 n4_lt168g[] = {
311 0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
312 0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
313 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
314 0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
315 0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
316 0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
317 0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
318 0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
319 0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
320};
309 321
310static const struct additional_sensor_data sensor_data[] = { 322static const struct additional_sensor_data sensor_data[] = {
311 { /* 0: OM6802 */ 323 { /* 0: OM6802 */
@@ -380,6 +392,23 @@ static const struct additional_sensor_data sensor_data[] = {
380 .stream = 392 .stream =
381 {0x0b, 0x04, 0x0a, 0x40}, 393 {0x0b, 0x04, 0x0a, 0x40},
382 }, 394 },
395 { /* 3: LT168G */
396 .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
397 .n4 = n4_lt168g,
398 .n4sz = sizeof n4_lt168g,
399 .reg80 = 0x7c,
400 .reg8e = 0xb3,
401 .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
402 .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
403 0xb0, 0xf4},
404 .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
405 0xff},
406 .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
407 0xff},
408 .data4 = {0x66, 0x41, 0xa8, 0xf0},
409 .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
410 .stream = {0x0b, 0x04, 0x0a, 0x28},
411 },
383}; 412};
384 413
385#define MAX_EFFECTS 7 414#define MAX_EFFECTS 7
@@ -716,6 +745,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
716 PDEBUG(D_PROBE, "sensor tas5130a"); 745 PDEBUG(D_PROBE, "sensor tas5130a");
717 sd->sensor = SENSOR_TAS5130A; 746 sd->sensor = SENSOR_TAS5130A;
718 break; 747 break;
748 case 0x0802:
749 PDEBUG(D_PROBE, "sensor lt168g");
750 sd->sensor = SENSOR_LT168G;
751 break;
719 case 0x0803: 752 case 0x0803:
720 PDEBUG(D_PROBE, "sensor 'other'"); 753 PDEBUG(D_PROBE, "sensor 'other'");
721 sd->sensor = SENSOR_OTHER; 754 sd->sensor = SENSOR_OTHER;
@@ -758,6 +791,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
758 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3); 791 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
759 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz); 792 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
760 793
794 if (sd->sensor == SENSOR_LT168G) {
795 test_byte = reg_r(gspca_dev, 0x80);
796 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
797 test_byte);
798 reg_w(gspca_dev, 0x6c80);
799 }
800
761 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); 801 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
762 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); 802 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
763 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); 803 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
@@ -782,6 +822,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
782 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); 822 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
783 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); 823 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
784 824
825 if (sd->sensor == SENSOR_LT168G) {
826 test_byte = reg_r(gspca_dev, 0x80);
827 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
828 test_byte);
829 reg_w(gspca_dev, 0x6c80);
830 }
831
785 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); 832 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
786 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); 833 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
787 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); 834 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
@@ -888,6 +935,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
888 case SENSOR_OM6802: 935 case SENSOR_OM6802:
889 om6802_sensor_init(gspca_dev); 936 om6802_sensor_init(gspca_dev);
890 break; 937 break;
938 case SENSOR_LT168G:
939 break;
891 case SENSOR_OTHER: 940 case SENSOR_OTHER:
892 break; 941 break;
893 default: 942 default:
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index b74a3b6489c7..c7b6eb1e04d5 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -39,7 +39,7 @@ struct sd {
39static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 39static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
40static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 40static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
41 41
42static struct ctrl sd_ctrls[] = { 42static const struct ctrl sd_ctrls[] = {
43 { 43 {
44 { 44 {
45 .id = V4L2_CID_BRIGHTNESS, 45 .id = V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 71921c878424..4989f9afb46e 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,10 +32,13 @@ 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 u8 brightness;
36 u8 contrast;
37 u8 colors;
35 u8 hflip; 38 u8 hflip;
36 u8 vflip; 39 u8 vflip;
37 u8 lightfreq; 40 u8 lightfreq;
38 u8 sharpness; 41 s8 sharpness;
39 42
40 u8 image_offset; 43 u8 image_offset;
41 44
@@ -52,6 +55,7 @@ struct sd {
52#define SENSOR_OV7670 6 55#define SENSOR_OV7670 6
53#define SENSOR_PO1200 7 56#define SENSOR_PO1200 7
54#define SENSOR_PO3130NC 8 57#define SENSOR_PO3130NC 8
58#define SENSOR_POxxxx 9
55 u8 flags; 59 u8 flags;
56#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */ 60#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
57#define FL_HFLIP 0x02 /* mirrored by default */ 61#define FL_HFLIP 0x02 /* mirrored by default */
@@ -59,6 +63,12 @@ struct sd {
59}; 63};
60 64
61/* V4L2 controls supported by the driver */ 65/* V4L2 controls supported by the driver */
66static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
62static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 72static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
63static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
64static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -68,9 +78,54 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
70 80
71static struct ctrl sd_ctrls[] = { 81static const struct ctrl sd_ctrls[] = {
82#define BRIGHTNESS_IDX 0
83 {
84 {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "Brightness",
88 .minimum = 0,
89 .maximum = 255,
90 .step = 1,
91#define BRIGHTNESS_DEF 128
92 .default_value = BRIGHTNESS_DEF,
93 },
94 .set = sd_setbrightness,
95 .get = sd_getbrightness,
96 },
97#define CONTRAST_IDX 1
98 {
99 {
100 .id = V4L2_CID_CONTRAST,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Contrast",
103 .minimum = 0,
104 .maximum = 255,
105 .step = 1,
106#define CONTRAST_DEF 127
107 .default_value = CONTRAST_DEF,
108 },
109 .set = sd_setcontrast,
110 .get = sd_getcontrast,
111 },
112#define COLORS_IDX 2
113 {
114 {
115 .id = V4L2_CID_SATURATION,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Saturation",
118 .minimum = 1,
119 .maximum = 127,
120 .step = 1,
121#define COLOR_DEF 63
122 .default_value = COLOR_DEF,
123 },
124 .set = sd_setcolors,
125 .get = sd_getcolors,
126 },
72/* next 2 controls work with some sensors only */ 127/* next 2 controls work with some sensors only */
73#define HFLIP_IDX 0 128#define HFLIP_IDX 3
74 { 129 {
75 { 130 {
76 .id = V4L2_CID_HFLIP, 131 .id = V4L2_CID_HFLIP,
@@ -85,7 +140,7 @@ static struct ctrl sd_ctrls[] = {
85 .set = sd_sethflip, 140 .set = sd_sethflip,
86 .get = sd_gethflip, 141 .get = sd_gethflip,
87 }, 142 },
88#define VFLIP_IDX 1 143#define VFLIP_IDX 4
89 { 144 {
90 { 145 {
91 .id = V4L2_CID_VFLIP, 146 .id = V4L2_CID_VFLIP,
@@ -100,7 +155,7 @@ static struct ctrl sd_ctrls[] = {
100 .set = sd_setvflip, 155 .set = sd_setvflip,
101 .get = sd_getvflip, 156 .get = sd_getvflip,
102 }, 157 },
103#define LIGHTFREQ_IDX 2 158#define LIGHTFREQ_IDX 5
104 { 159 {
105 { 160 {
106 .id = V4L2_CID_POWER_LINE_FREQUENCY, 161 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -115,17 +170,16 @@ static struct ctrl sd_ctrls[] = {
115 .set = sd_setfreq, 170 .set = sd_setfreq,
116 .get = sd_getfreq, 171 .get = sd_getfreq,
117 }, 172 },
118/* po1200 only */ 173#define SHARPNESS_IDX 6
119#define SHARPNESS_IDX 3
120 { 174 {
121 { 175 {
122 .id = V4L2_CID_SHARPNESS, 176 .id = V4L2_CID_SHARPNESS,
123 .type = V4L2_CTRL_TYPE_INTEGER, 177 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Sharpness", 178 .name = "Sharpness",
125 .minimum = 0, 179 .minimum = -1,
126 .maximum = 2, 180 .maximum = 2,
127 .step = 1, 181 .step = 1,
128#define SHARPNESS_DEF 1 182#define SHARPNESS_DEF -1
129 .default_value = SHARPNESS_DEF, 183 .default_value = SHARPNESS_DEF,
130 }, 184 },
131 .set = sd_setsharpness, 185 .set = sd_setsharpness,
@@ -133,6 +187,42 @@ static struct ctrl sd_ctrls[] = {
133 }, 187 },
134}; 188};
135 189
190/* table of the disabled controls */
191static u32 ctrl_dis[] = {
192/* SENSOR_HV7131R 0 */
193 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
194 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
195 | (1 << SHARPNESS_IDX),
196/* SENSOR_MI0360 1 */
197 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
198 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
199 | (1 << SHARPNESS_IDX),
200/* SENSOR_MI1310_SOC 2 */
201 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
202 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
203/* SENSOR_MI1320 3 */
204 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
205 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
206/* SENSOR_MI1320_SOC 4 */
207 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
208 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
209/* SENSOR_OV7660 5 */
210 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
211 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
212/* SENSOR_OV7670 6 */
213 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
214 | (1 << SHARPNESS_IDX),
215/* SENSOR_PO1200 7 */
216 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
217 | (1 << LIGHTFREQ_IDX),
218/* SENSOR_PO3130NC 8 */
219 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
220 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
221 | (1 << SHARPNESS_IDX),
222/* SENSOR_POxxxx 9 */
223 (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX),
224};
225
136static const struct v4l2_pix_format vc0321_mode[] = { 226static const struct v4l2_pix_format vc0321_mode[] = {
137 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 227 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
138 .bytesperline = 320, 228 .bytesperline = 320,
@@ -215,7 +305,7 @@ static const u8 mi0360_initVGA_JPG[][4] = {
215 {0xb3, 0x15, 0x00, 0xcc}, 305 {0xb3, 0x15, 0x00, 0xcc},
216 {0xb3, 0x16, 0x02, 0xcc}, 306 {0xb3, 0x16, 0x02, 0xcc},
217 {0xb3, 0x17, 0x7f, 0xcc}, 307 {0xb3, 0x17, 0x7f, 0xcc},
218 {0xb3, 0x35, 0xdd, 0xcc}, 308 {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */
219 {0xb3, 0x34, 0x02, 0xcc}, 309 {0xb3, 0x34, 0x02, 0xcc},
220 {0xb3, 0x00, 0x25, 0xcc}, 310 {0xb3, 0x00, 0x25, 0xcc},
221 {0xbc, 0x00, 0x71, 0xcc}, 311 {0xbc, 0x00, 0x71, 0xcc},
@@ -435,7 +525,7 @@ static const u8 mi1310_socinitVGA_JPG[][4] = {
435 {0xb3, 0x08, 0x01, 0xcc}, 525 {0xb3, 0x08, 0x01, 0xcc},
436 {0xb3, 0x09, 0x0c, 0xcc}, 526 {0xb3, 0x09, 0x0c, 0xcc},
437 {0xb3, 0x34, 0x02, 0xcc}, 527 {0xb3, 0x34, 0x02, 0xcc},
438 {0xb3, 0x35, 0xdd, 0xcc}, 528 {0xb3, 0x35, 0xdd, 0xcc}, /* i2c add: 5d */
439 {0xb3, 0x02, 0x00, 0xcc}, 529 {0xb3, 0x02, 0x00, 0xcc},
440 {0xb3, 0x03, 0x0a, 0xcc}, 530 {0xb3, 0x03, 0x0a, 0xcc},
441 {0xb3, 0x04, 0x05, 0xcc}, 531 {0xb3, 0x04, 0x05, 0xcc},
@@ -860,7 +950,8 @@ static const u8 mi1320_initVGA_data[][4] = {
860 {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, 950 {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
861 {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, 951 {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
862 {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, 952 {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc},
863 {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, 953 {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */
954 {0xb3, 0x02, 0x00, 0xcc},
864 {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, 955 {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
865 {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, 956 {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
866 {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, 957 {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc},
@@ -901,7 +992,8 @@ static const u8 mi1320_initVGA_data[][4] = {
901 {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, 992 {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb},
902 {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, 993 {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb},
903 {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, 994 {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb},
904 {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, 995 {0x08, 0x00, 0x27, 0xbb},
996 {0x20, 0x01, 0x00, 0xbb}, /* h/v flips - was 03 */
905 {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, 997 {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb},
906 {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, 998 {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb},
907 {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, 999 {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb},
@@ -1012,7 +1104,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
1012 {0xb3, 0x08, 0x01, 0xcc}, 1104 {0xb3, 0x08, 0x01, 0xcc},
1013 {0xb3, 0x09, 0x0c, 0xcc}, 1105 {0xb3, 0x09, 0x0c, 0xcc},
1014 {0xb3, 0x34, 0x02, 0xcc}, 1106 {0xb3, 0x34, 0x02, 0xcc},
1015 {0xb3, 0x35, 0xc8, 0xcc}, 1107 {0xb3, 0x35, 0xc8, 0xcc}, /* i2c add: 48 */
1016 {0xb3, 0x02, 0x00, 0xcc}, 1108 {0xb3, 0x02, 0x00, 0xcc},
1017 {0xb3, 0x03, 0x0a, 0xcc}, 1109 {0xb3, 0x03, 0x0a, 0xcc},
1018 {0xb3, 0x04, 0x05, 0xcc}, 1110 {0xb3, 0x04, 0x05, 0xcc},
@@ -1359,7 +1451,8 @@ static const u8 po3130_initVGA_data[][4] = {
1359 {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc}, 1451 {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc},
1360 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, 1452 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
1361 {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, 1453 {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
1362 {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, 1454 {0xb3, 0x34, 0x01, 0xcc},
1455 {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
1363 {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc}, 1456 {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc},
1364 {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, 1457 {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc},
1365 {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, 1458 {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
@@ -1561,7 +1654,7 @@ static const u8 hv7131r_initVGA_data[][4] = {
1561 {0xb3, 0x16, 0x02, 0xcc}, 1654 {0xb3, 0x16, 0x02, 0xcc},
1562 {0xb3, 0x17, 0x7f, 0xcc}, 1655 {0xb3, 0x17, 0x7f, 0xcc},
1563 {0xb3, 0x34, 0x01, 0xcc}, 1656 {0xb3, 0x34, 0x01, 0xcc},
1564 {0xb3, 0x35, 0x91, 0xcc}, 1657 {0xb3, 0x35, 0x91, 0xcc}, /* i2c add: 11 */
1565 {0xb3, 0x00, 0x27, 0xcc}, 1658 {0xb3, 0x00, 0x27, 0xcc},
1566 {0xbc, 0x00, 0x73, 0xcc}, 1659 {0xbc, 0x00, 0x73, 0xcc},
1567 {0xb8, 0x00, 0x23, 0xcc}, 1660 {0xb8, 0x00, 0x23, 0xcc},
@@ -1747,7 +1840,8 @@ static const u8 ov7660_initVGA_data[][4] = {
1747 {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, 1840 {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc},
1748 {0xb3, 0x1f, 0x02, 0xcc}, 1841 {0xb3, 0x1f, 0x02, 0xcc},
1749 {0xb3, 0x34, 0x01, 0xcc}, 1842 {0xb3, 0x34, 0x01, 0xcc},
1750 {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, 1843 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
1844 {0xb3, 0x00, 0x26, 0xcc},
1751 {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ 1845 {0xb8, 0x00, 0x33, 0xcc}, /* 13 */
1752 {0xb8, 0x01, 0x7d, 0xcc}, 1846 {0xb8, 0x01, 0x7d, 0xcc},
1753 {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, 1847 {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
@@ -1883,7 +1977,8 @@ static const u8 ov7670_initVGA_JPG[][4] = {
1883 {0x00, 0x00, 0x10, 0xdd}, 1977 {0x00, 0x00, 0x10, 0xdd},
1884 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 1978 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
1885 {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, 1979 {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc},
1886 {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, 1980 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
1981 {0xb3, 0x34, 0x01, 0xcc},
1887 {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, 1982 {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc},
1888 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, 1983 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
1889 {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, 1984 {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc},
@@ -2181,7 +2276,7 @@ static const u8 po1200_initVGA_data[][4] = {
2181 {0xb0, 0x54, 0x13, 0xcc}, 2276 {0xb0, 0x54, 0x13, 0xcc},
2182 {0xb3, 0x00, 0x67, 0xcc}, 2277 {0xb3, 0x00, 0x67, 0xcc},
2183 {0xb3, 0x34, 0x01, 0xcc}, 2278 {0xb3, 0x34, 0x01, 0xcc},
2184 {0xb3, 0x35, 0xdc, 0xcc}, 2279 {0xb3, 0x35, 0xdc, 0xcc}, /* i2c add: 5c */
2185 {0x00, 0x03, 0x00, 0xaa}, 2280 {0x00, 0x03, 0x00, 0xaa},
2186 {0x00, 0x12, 0x05, 0xaa}, 2281 {0x00, 0x12, 0x05, 0xaa},
2187 {0x00, 0x13, 0x02, 0xaa}, 2282 {0x00, 0x13, 0x02, 0xaa},
@@ -2408,6 +2503,251 @@ static const u8 po1200_initVGA_data[][4] = {
2408 {0x00, 0xb6, 0x39, 0xaa}, 2503 {0x00, 0xb6, 0x39, 0xaa},
2409 {0x00, 0xb7, 0x24, 0xaa}, 2504 {0x00, 0xb7, 0x24, 0xaa},
2410/*write 89 0400 1415*/ 2505/*write 89 0400 1415*/
2506 {}
2507};
2508
2509static const u8 poxxxx_init_common[][4] = {
2510 {0xb3, 0x00, 0x04, 0xcc},
2511 {0x00, 0x00, 0x10, 0xdd},
2512 {0xb3, 0x00, 0x64, 0xcc},
2513 {0x00, 0x00, 0x10, 0xdd},
2514 {0xb3, 0x00, 0x65, 0xcc},
2515 {0x00, 0x00, 0x10, 0xdd},
2516 {0xb3, 0x00, 0x67, 0xcc},
2517 {0xb0, 0x03, 0x09, 0xcc},
2518 {0xb3, 0x05, 0x00, 0xcc},
2519 {0xb3, 0x06, 0x00, 0xcc},
2520 {0xb3, 0x5c, 0x01, 0xcc},
2521 {0xb3, 0x08, 0x01, 0xcc},
2522 {0xb3, 0x09, 0x0c, 0xcc},
2523 {0xb3, 0x34, 0x01, 0xcc},
2524 {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
2525 {0xb3, 0x02, 0xb0, 0xcc},
2526 {0xb3, 0x03, 0x18, 0xcc},
2527 {0xb3, 0x04, 0x15, 0xcc},
2528 {0xb3, 0x20, 0x00, 0xcc},
2529 {0xb3, 0x21, 0x00, 0xcc},
2530 {0xb3, 0x22, 0x04, 0xcc},
2531 {0xb3, 0x23, 0x00, 0xcc},
2532 {0xb3, 0x14, 0x00, 0xcc},
2533 {0xb3, 0x15, 0x00, 0xcc},
2534 {0xb3, 0x16, 0x04, 0xcc},
2535 {0xb3, 0x17, 0xff, 0xcc},
2536 {0xb3, 0x2c, 0x03, 0xcc},
2537 {0xb3, 0x2d, 0x56, 0xcc},
2538 {0xb3, 0x2e, 0x02, 0xcc},
2539 {0xb3, 0x2f, 0x0a, 0xcc},
2540 {0xb3, 0x40, 0x00, 0xcc},
2541 {0xb3, 0x41, 0x34, 0xcc},
2542 {0xb3, 0x42, 0x01, 0xcc},
2543 {0xb3, 0x43, 0xe0, 0xcc},
2544 {0xbc, 0x00, 0x71, 0xcc},
2545 {0xbc, 0x01, 0x01, 0xcc},
2546 {0xb3, 0x01, 0x41, 0xcc},
2547 {0xb3, 0x4d, 0x00, 0xcc},
2548 {0x00, 0x0b, 0x2a, 0xaa},
2549 {0x00, 0x0e, 0x03, 0xaa},
2550 {0x00, 0x0f, 0xea, 0xaa},
2551 {0x00, 0x12, 0x08, 0xaa},
2552 {0x00, 0x1e, 0x06, 0xaa},
2553 {0x00, 0x21, 0x00, 0xaa},
2554 {0x00, 0x31, 0x1f, 0xaa},
2555 {0x00, 0x33, 0x38, 0xaa},
2556 {0x00, 0x36, 0xc0, 0xaa},
2557 {0x00, 0x37, 0xc8, 0xaa},
2558 {0x00, 0x3b, 0x36, 0xaa},
2559 {0x00, 0x4b, 0xfe, 0xaa},
2560 {0x00, 0x4d, 0x2e, 0xaa},
2561 {0x00, 0x51, 0x1c, 0xaa},
2562 {0x00, 0x52, 0x01, 0xaa},
2563 {0x00, 0x55, 0x0a, 0xaa},
2564 {0x00, 0x56, 0x0a, 0xaa},
2565 {0x00, 0x57, 0x07, 0xaa},
2566 {0x00, 0x58, 0x07, 0xaa},
2567 {0x00, 0x59, 0x04, 0xaa},
2568 {0x00, 0x70, 0x68, 0xaa},
2569 {0x00, 0x71, 0x04, 0xaa},
2570 {0x00, 0x72, 0x10, 0xaa},
2571 {0x00, 0x80, 0x71, 0xaa},
2572 {0x00, 0x81, 0x08, 0xaa},
2573 {0x00, 0x82, 0x00, 0xaa},
2574 {0x00, 0x83, 0x55, 0xaa},
2575 {0x00, 0x84, 0x06, 0xaa},
2576 {0x00, 0x85, 0x06, 0xaa},
2577 {0x00, 0x8b, 0x25, 0xaa},
2578 {0x00, 0x8c, 0x00, 0xaa},
2579 {0x00, 0x8d, 0x86, 0xaa},
2580 {0x00, 0x8e, 0x82, 0xaa},
2581 {0x00, 0x8f, 0x2d, 0xaa},
2582 {0x00, 0x90, 0x8b, 0xaa},
2583 {0x00, 0x91, 0x81, 0xaa},
2584 {0x00, 0x92, 0x81, 0xaa},
2585 {0x00, 0x93, 0x23, 0xaa},
2586 {0x00, 0xa3, 0x2a, 0xaa},
2587 {0x00, 0xa4, 0x03, 0xaa},
2588 {0x00, 0xa5, 0xea, 0xaa},
2589 {0x00, 0xb0, 0x68, 0xaa},
2590 {0x00, 0xbc, 0x04, 0xaa},
2591 {0x00, 0xbe, 0x3b, 0xaa},
2592 {0x00, 0x4e, 0x40, 0xaa},
2593 {0x00, 0x06, 0x04, 0xaa},
2594 {0x00, 0x07, 0x03, 0xaa},
2595 {0x00, 0xcd, 0x18, 0xaa},
2596 {0x00, 0x28, 0x03, 0xaa},
2597 {0x00, 0x29, 0xef, 0xaa},
2598/* reinit on alt 2 (qvga) or alt7 (vga) */
2599 {0xb3, 0x05, 0x00, 0xcc},
2600 {0xb3, 0x06, 0x00, 0xcc},
2601 {0xb8, 0x00, 0x01, 0xcc},
2602
2603 {0x00, 0x1d, 0x85, 0xaa},
2604 {0x00, 0x1e, 0xc6, 0xaa},
2605 {0x00, 0x00, 0x40, 0xdd},
2606 {0x00, 0x1d, 0x05, 0xaa},
2607
2608 {0x00, 0xd6, 0x22, 0xaa}, /* gamma 0 */
2609 {0x00, 0x73, 0x00, 0xaa},
2610 {0x00, 0x74, 0x0a, 0xaa},
2611 {0x00, 0x75, 0x16, 0xaa},
2612 {0x00, 0x76, 0x25, 0xaa},
2613 {0x00, 0x77, 0x34, 0xaa},
2614 {0x00, 0x78, 0x49, 0xaa},
2615 {0x00, 0x79, 0x5a, 0xaa},
2616 {0x00, 0x7a, 0x7f, 0xaa},
2617 {0x00, 0x7b, 0x9b, 0xaa},
2618 {0x00, 0x7c, 0xba, 0xaa},
2619 {0x00, 0x7d, 0xd4, 0xaa},
2620 {0x00, 0x7e, 0xea, 0xaa},
2621
2622 {0x00, 0xd6, 0x62, 0xaa}, /* gamma 1 */
2623 {0x00, 0x73, 0x00, 0xaa},
2624 {0x00, 0x74, 0x0a, 0xaa},
2625 {0x00, 0x75, 0x16, 0xaa},
2626 {0x00, 0x76, 0x25, 0xaa},
2627 {0x00, 0x77, 0x34, 0xaa},
2628 {0x00, 0x78, 0x49, 0xaa},
2629 {0x00, 0x79, 0x5a, 0xaa},
2630 {0x00, 0x7a, 0x7f, 0xaa},
2631 {0x00, 0x7b, 0x9b, 0xaa},
2632 {0x00, 0x7c, 0xba, 0xaa},
2633 {0x00, 0x7d, 0xd4, 0xaa},
2634 {0x00, 0x7e, 0xea, 0xaa},
2635
2636 {0x00, 0xd6, 0xa2, 0xaa}, /* gamma 2 */
2637 {0x00, 0x73, 0x00, 0xaa},
2638 {0x00, 0x74, 0x0a, 0xaa},
2639 {0x00, 0x75, 0x16, 0xaa},
2640 {0x00, 0x76, 0x25, 0xaa},
2641 {0x00, 0x77, 0x34, 0xaa},
2642 {0x00, 0x78, 0x49, 0xaa},
2643 {0x00, 0x79, 0x5a, 0xaa},
2644 {0x00, 0x7a, 0x7f, 0xaa},
2645 {0x00, 0x7b, 0x9b, 0xaa},
2646 {0x00, 0x7c, 0xba, 0xaa},
2647 {0x00, 0x7d, 0xd4, 0xaa},
2648 {0x00, 0x7e, 0xea, 0xaa},
2649
2650 {0x00, 0xaa, 0xff, 0xaa}, /* back light comp */
2651 {0x00, 0xc4, 0x03, 0xaa},
2652 {0x00, 0xc5, 0x19, 0xaa},
2653 {0x00, 0xc6, 0x03, 0xaa},
2654 {0x00, 0xc7, 0x91, 0xaa},
2655 {0x00, 0xc8, 0x01, 0xaa},
2656 {0x00, 0xc9, 0xdd, 0xaa},
2657 {0x00, 0xca, 0x02, 0xaa},
2658 {0x00, 0xcb, 0x37, 0xaa},
2659
2660/* read d1 */
2661 {0x00, 0xd1, 0x3c, 0xaa},
2662 {0x00, 0xb8, 0x28, 0xaa},
2663 {0x00, 0xb9, 0x1e, 0xaa},
2664 {0x00, 0xb6, 0x14, 0xaa},
2665 {0x00, 0xb7, 0x0f, 0xaa},
2666 {0x00, 0x5c, 0x10, 0xaa},
2667 {0x00, 0x5d, 0x18, 0xaa},
2668 {0x00, 0x5e, 0x24, 0xaa},
2669 {0x00, 0x5f, 0x24, 0xaa},
2670 {0x00, 0x86, 0x1a, 0xaa},
2671 {0x00, 0x60, 0x00, 0xaa},
2672 {0x00, 0x61, 0x1b, 0xaa},
2673 {0x00, 0x62, 0x30, 0xaa},
2674 {0x00, 0x63, 0x40, 0xaa},
2675 {0x00, 0x87, 0x1a, 0xaa},
2676 {0x00, 0x64, 0x00, 0xaa},
2677 {0x00, 0x65, 0x08, 0xaa},
2678 {0x00, 0x66, 0x10, 0xaa},
2679 {0x00, 0x67, 0x20, 0xaa},
2680 {0x00, 0x88, 0x10, 0xaa},
2681 {0x00, 0x68, 0x00, 0xaa},
2682 {0x00, 0x69, 0x08, 0xaa},
2683 {0x00, 0x6a, 0x0f, 0xaa},
2684 {0x00, 0x6b, 0x0f, 0xaa},
2685 {0x00, 0x89, 0x07, 0xaa},
2686 {0x00, 0xd5, 0x4c, 0xaa},
2687 {0x00, 0x0a, 0x00, 0xaa},
2688 {0x00, 0x0b, 0x2a, 0xaa},
2689 {0x00, 0x0e, 0x03, 0xaa},
2690 {0x00, 0x0f, 0xea, 0xaa},
2691 {0x00, 0xa2, 0x00, 0xaa},
2692 {0x00, 0xa3, 0x2a, 0xaa},
2693 {0x00, 0xa4, 0x03, 0xaa},
2694 {0x00, 0xa5, 0xea, 0xaa},
2695 {}
2696};
2697static const u8 poxxxx_initVGA[][4] = {
2698 {0x00, 0x20, 0x11, 0xaa},
2699 {0x00, 0x33, 0x38, 0xaa},
2700 {0x00, 0xbb, 0x0d, 0xaa},
2701 {0xb3, 0x22, 0x01, 0xcc},
2702 {0xb3, 0x23, 0xe0, 0xcc},
2703 {0xb3, 0x16, 0x02, 0xcc},
2704 {0xb3, 0x17, 0x7f, 0xcc},
2705 {0xb3, 0x02, 0xb0, 0xcc},
2706 {0xb3, 0x06, 0x00, 0xcc},
2707 {0xb3, 0x5c, 0x01, 0xcc},
2708 {0x00, 0x04, 0x06, 0xaa},
2709 {0x00, 0x05, 0x3f, 0xaa},
2710 {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
2711 {}
2712};
2713static const u8 poxxxx_initQVGA[][4] = {
2714 {0x00, 0x20, 0x33, 0xaa},
2715 {0x00, 0x33, 0x38, 0xaa},
2716 {0x00, 0xbb, 0x0d, 0xaa},
2717 {0xb3, 0x22, 0x00, 0xcc},
2718 {0xb3, 0x23, 0xf0, 0xcc},
2719 {0xb3, 0x16, 0x01, 0xcc},
2720 {0xb3, 0x17, 0x3f, 0xcc},
2721 {0xb3, 0x02, 0xb0, 0xcc},
2722 {0xb3, 0x06, 0x01, 0xcc},
2723 {0xb3, 0x5c, 0x00, 0xcc},
2724 {0x00, 0x04, 0x06, 0xaa},
2725 {0x00, 0x05, 0x3f, 0xaa},
2726 {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
2727 {}
2728};
2729static const u8 poxxxx_init_end_1[][4] = {
2730 {0x00, 0x47, 0x25, 0xaa},
2731 {0x00, 0x48, 0x80, 0xaa},
2732 {0x00, 0x49, 0x1f, 0xaa},
2733 {0x00, 0x4a, 0x40, 0xaa},
2734 {0x00, 0x44, 0x40, 0xaa},
2735 {0x00, 0xab, 0x4a, 0xaa},
2736 {0x00, 0xb1, 0x00, 0xaa},
2737 {0x00, 0xb2, 0x04, 0xaa},
2738 {0x00, 0xb3, 0x08, 0xaa},
2739 {0x00, 0xb4, 0x0b, 0xaa},
2740 {0x00, 0xb5, 0x0d, 0xaa},
2741 {0x00, 0x59, 0x7e, 0xaa}, /* sharpness */
2742 {0x00, 0x16, 0x00, 0xaa}, /* white balance */
2743 {0x00, 0x18, 0x00, 0xaa},
2744 {}
2745};
2746static const u8 poxxxx_init_end_2[][4] = {
2747 {0x00, 0x1d, 0x85, 0xaa},
2748 {0x00, 0x1e, 0x06, 0xaa},
2749 {0x00, 0x1d, 0x05, 0xaa},
2750 {}
2411}; 2751};
2412 2752
2413struct sensor_info { 2753struct sensor_info {
@@ -2420,33 +2760,89 @@ struct sensor_info {
2420 u8 op; 2760 u8 op;
2421}; 2761};
2422 2762
2423static const struct sensor_info sensor_info_data[] = { 2763/* probe values */
2424/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ 2764static const struct sensor_info vc0321_probe_data[] = {
2765/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
2766/* 0 OV9640 */
2425 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, 2767 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2768/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
2426 {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01}, 2769 {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
2427/* (tested in vc032x_probe_sensor) */ 2770/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
2428/* {-1, 0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */ 2771 {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
2429 {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, 2772/* 3 MI1310 */
2773 {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
2774/* 4 MI360 - tested in vc032x_probe_sensor */
2775/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
2776/* 5 7131R */
2777 {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
2778/* 6 OV7649 */
2779 {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
2780/* 7 PAS302BCW */
2781 {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
2782/* 8 OV7660 */
2783 {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
2784/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
2785/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
2786/* 10 PO1030KC */
2787 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2788/* 11 MI1310_SOC */
2430 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, 2789 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
2431/* (tested in vc032x_probe_sensor) */ 2790/* 12 OV9650 */
2791 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2792/* 13 S5K532 */
2793 {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
2794/* 14 MI360_SOC - ??? */
2795/* 15 PO1200N */
2796 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
2797/* 16 PO3030K */
2798 {-1, 0x80 | 0x18, 0x00, 0x0000, 0x24, 0x25, 0x01},
2799/* 17 PO2030 */
2800 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2801/* ?? */
2802 {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
2803 {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
2804};
2805static const struct sensor_info vc0323_probe_data[] = {
2806/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
2807/* 0 OV9640 */
2808 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2809/* 1 ICM108T (may respond on IdAdd == 0x83 - tested in vc032x_probe_sensor) */
2810 {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
2811/* 2 PO2130 (may detect PO3130NC - tested in vc032x_probe_sensor)*/
2812 {-1, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01},
2813/* 3 MI1310 */
2814 {-1, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01},
2815/* 4 MI360 - tested in vc032x_probe_sensor */
2432/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */ 2816/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
2817/* 5 7131R */
2433 {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, 2818 {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
2819/* 6 OV7649 */
2434 {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05}, 2820 {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
2821/* 7 PAS302BCW */
2435 {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05}, 2822 {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
2823/* 8 OV7660 */
2436 {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, 2824 {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
2437/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */ 2825/* 9 PO3130NC - (tested in vc032x_probe_sensor) */
2826/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, */
2827/* 10 PO1030KC */
2438 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, 2828 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2439/* {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */ 2829/* 11 MI1310_SOC */
2440/* {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */ 2830 {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
2831/* 12 OV9650 */
2832 {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
2833/* 13 S5K532 */
2441 {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01}, 2834 {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
2835/* 14 MI360_SOC - ??? */
2836/* 15 PO1200N */
2442 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01}, 2837 {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
2838/* 16 ?? */
2443 {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01}, 2839 {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
2840/* 17 PO2030 */
2444 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, 2841 {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
2842/* ?? */
2445 {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01}, 2843 {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
2446 {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01}, 2844 {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
2447/*fixme: previously detected?*/ 2845/*fixme: not in the ms-win probe - may be found before? */
2448 {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
2449/*fixme: not in the ms-win probe - may be found before?*/
2450 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, 2846 {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
2451}; 2847};
2452 2848
@@ -2520,7 +2916,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2520{ 2916{
2521 struct sd *sd = (struct sd *) gspca_dev; 2917 struct sd *sd = (struct sd *) gspca_dev;
2522 struct usb_device *dev = gspca_dev->dev; 2918 struct usb_device *dev = gspca_dev->dev;
2523 int i; 2919 int i, n;
2524 u16 value; 2920 u16 value;
2525 const struct sensor_info *ptsensor_info; 2921 const struct sensor_info *ptsensor_info;
2526 2922
@@ -2531,9 +2927,16 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2531 } 2927 }
2532 2928
2533 reg_r(gspca_dev, 0xa1, 0xbfcf, 1); 2929 reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
2534 PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]); 2930 PDEBUG(D_PROBE, "vc032%d check sensor header %02x",
2535 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { 2931 sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
2536 ptsensor_info = &sensor_info_data[i]; 2932 if (sd->bridge == BRIDGE_VC0321) {
2933 ptsensor_info = vc0321_probe_data;
2934 n = ARRAY_SIZE(vc0321_probe_data);
2935 } else {
2936 ptsensor_info = vc0323_probe_data;
2937 n = ARRAY_SIZE(vc0323_probe_data);
2938 }
2939 for (i = 0; i < n; i++) {
2537 reg_w(dev, 0xa0, 0x02, 0xb334); 2940 reg_w(dev, 0xa0, 0x02, 0xb334);
2538 reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300); 2941 reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300);
2539 reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300); 2942 reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300);
@@ -2551,13 +2954,15 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2551 return ptsensor_info->sensorId; 2954 return ptsensor_info->sensorId;
2552 2955
2553 switch (value) { 2956 switch (value) {
2957 case 0x3130:
2958 return SENSOR_PO3130NC;
2554 case 0x7673: 2959 case 0x7673:
2555 return SENSOR_OV7670; 2960 return SENSOR_OV7670;
2556 case 0x8243: 2961 case 0x8243:
2557 return SENSOR_MI0360; 2962 return SENSOR_MI0360;
2558 } 2963 }
2559/*fixme: should return here*/
2560 } 2964 }
2965 ptsensor_info++;
2561 } 2966 }
2562 return -1; 2967 return -1;
2563} 2968}
@@ -2619,7 +3024,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
2619 i2c_write(gspca_dev, data[i][0], &data[i][1], 2); 3024 i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
2620 break; 3025 break;
2621 case 0xdd: 3026 case 0xdd:
2622 msleep(data[i][2] + 10); 3027 msleep(data[i][1] * 256 + data[i][2] + 10);
2623 break; 3028 break;
2624 } 3029 }
2625 i++; 3030 i++;
@@ -2646,12 +3051,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
2646 64, /* OV7670 6 */ 3051 64, /* OV7670 6 */
2647 128, /* PO1200 7 */ 3052 128, /* PO1200 7 */
2648 128, /* PO3130NC 8 */ 3053 128, /* PO3130NC 8 */
3054 128, /* POxxxx 9 */
2649 }; 3055 };
2650 3056
2651 cam = &gspca_dev->cam; 3057 cam = &gspca_dev->cam;
2652 sd->bridge = id->driver_info >> 8; 3058 sd->bridge = id->driver_info >> 8;
2653 sd->flags = id->driver_info & 0xff; 3059 sd->flags = id->driver_info & 0xff;
2654 sensor = vc032x_probe_sensor(gspca_dev); 3060 if (id->idVendor == 0x046d &&
3061 (id->idProduct == 0x0892 || id->idProduct == 0x0896))
3062 sensor = SENSOR_POxxxx;
3063 else
3064 sensor = vc032x_probe_sensor(gspca_dev);
2655 switch (sensor) { 3065 switch (sensor) {
2656 case -1: 3066 case -1:
2657 PDEBUG(D_PROBE, "Unknown sensor..."); 3067 PDEBUG(D_PROBE, "Unknown sensor...");
@@ -2684,6 +3094,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
2684 case SENSOR_PO3130NC: 3094 case SENSOR_PO3130NC:
2685 PDEBUG(D_PROBE, "Find Sensor PO3130NC"); 3095 PDEBUG(D_PROBE, "Find Sensor PO3130NC");
2686 break; 3096 break;
3097 case SENSOR_POxxxx:
3098 PDEBUG(D_PROBE, "Sensor POxxxx");
3099 break;
2687 } 3100 }
2688 sd->sensor = sensor; 3101 sd->sensor = sensor;
2689 3102
@@ -2712,28 +3125,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
2712 } 3125 }
2713 cam->npkt = npkt[sd->sensor]; 3126 cam->npkt = npkt[sd->sensor];
2714 3127
3128 sd->brightness = BRIGHTNESS_DEF;
3129 sd->contrast = CONTRAST_DEF;
3130 sd->colors = COLOR_DEF;
2715 sd->hflip = HFLIP_DEF; 3131 sd->hflip = HFLIP_DEF;
2716 sd->vflip = VFLIP_DEF; 3132 sd->vflip = VFLIP_DEF;
2717 if (sd->sensor == SENSOR_OV7670)
2718 sd->flags |= FL_HFLIP | FL_VFLIP;
2719 sd->lightfreq = FREQ_DEF; 3133 sd->lightfreq = FREQ_DEF;
2720 if (sd->sensor != SENSOR_OV7670)
2721 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2722 switch (sd->sensor) {
2723 case SENSOR_MI1310_SOC:
2724 case SENSOR_MI1320_SOC:
2725 case SENSOR_OV7660:
2726 case SENSOR_OV7670:
2727 case SENSOR_PO1200:
2728 break;
2729 default:
2730 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
2731 | (1 << VFLIP_IDX);
2732 break;
2733 }
2734
2735 sd->sharpness = SHARPNESS_DEF; 3134 sd->sharpness = SHARPNESS_DEF;
2736 3135
3136 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
3137
3138 if (sd->sensor == SENSOR_OV7670)
3139 sd->flags |= FL_HFLIP | FL_VFLIP;
3140
2737 if (sd->bridge == BRIDGE_VC0321) { 3141 if (sd->bridge == BRIDGE_VC0321) {
2738 reg_r(gspca_dev, 0x8a, 0, 3); 3142 reg_r(gspca_dev, 0x8a, 0, 3);
2739 reg_w(dev, 0x87, 0x00, 0x0f0f); 3143 reg_w(dev, 0x87, 0x00, 0x0f0f);
@@ -2747,10 +3151,55 @@ static int sd_config(struct gspca_dev *gspca_dev,
2747/* this function is called at probe and resume time */ 3151/* this function is called at probe and resume time */
2748static int sd_init(struct gspca_dev *gspca_dev) 3152static int sd_init(struct gspca_dev *gspca_dev)
2749{ 3153{
3154 struct sd *sd = (struct sd *) gspca_dev;
3155
3156 if (sd->sensor == SENSOR_POxxxx) {
3157 reg_r(gspca_dev, 0xa1, 0xb300, 1);
3158 if (gspca_dev->usb_buf[0] != 0) {
3159 reg_w(gspca_dev->dev, 0xa0, 0x26, 0xb300);
3160 reg_w(gspca_dev->dev, 0xa0, 0x04, 0xb300);
3161 reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb300);
3162 }
3163 }
2750 return 0; 3164 return 0;
2751} 3165}
2752 3166
2753/* some sensors only */ 3167static void setbrightness(struct gspca_dev *gspca_dev)
3168{
3169 struct sd *sd = (struct sd *) gspca_dev;
3170 u8 data;
3171
3172 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
3173 return;
3174 data = sd->brightness;
3175 if (data >= 0x80)
3176 data &= 0x7f;
3177 else
3178 data = 0xff ^ data;
3179 i2c_write(gspca_dev, 0x98, &data, 1);
3180}
3181
3182static void setcontrast(struct gspca_dev *gspca_dev)
3183{
3184 struct sd *sd = (struct sd *) gspca_dev;
3185
3186 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
3187 return;
3188 i2c_write(gspca_dev, 0x99, &sd->contrast, 1);
3189}
3190
3191static void setcolors(struct gspca_dev *gspca_dev)
3192{
3193 struct sd *sd = (struct sd *) gspca_dev;
3194 u8 data;
3195
3196 if (gspca_dev->ctrl_dis & (1 << COLORS_IDX))
3197 return;
3198 data = sd->colors - (sd->colors >> 3) - 1;
3199 i2c_write(gspca_dev, 0x94, &data, 1);
3200 i2c_write(gspca_dev, 0x95, &sd->colors, 1);
3201}
3202
2754static void sethvflip(struct gspca_dev *gspca_dev) 3203static void sethvflip(struct gspca_dev *gspca_dev)
2755{ 3204{
2756 struct sd *sd = (struct sd *) gspca_dev; 3205 struct sd *sd = (struct sd *) gspca_dev;
@@ -2764,6 +3213,7 @@ static void sethvflip(struct gspca_dev *gspca_dev)
2764 vflip = !vflip; 3213 vflip = !vflip;
2765 switch (sd->sensor) { 3214 switch (sd->sensor) {
2766 case SENSOR_MI1310_SOC: 3215 case SENSOR_MI1310_SOC:
3216 case SENSOR_MI1320:
2767 case SENSOR_MI1320_SOC: 3217 case SENSOR_MI1320_SOC:
2768 data[0] = data[1] = 0; /* select page 0 */ 3218 data[0] = data[1] = 0; /* select page 0 */
2769 i2c_write(gspca_dev, 0xf0, data, 2); 3219 i2c_write(gspca_dev, 0xf0, data, 2);
@@ -2801,18 +3251,29 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
2801 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); 3251 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
2802} 3252}
2803 3253
2804/* po1200 only */
2805static void setsharpness(struct gspca_dev *gspca_dev) 3254static void setsharpness(struct gspca_dev *gspca_dev)
2806{ 3255{
2807 struct sd *sd = (struct sd *) gspca_dev; 3256 struct sd *sd = (struct sd *) gspca_dev;
2808 u8 data; 3257 u8 data;
2809 3258
2810 if (sd->sensor != SENSOR_PO1200) 3259 switch (sd->sensor) {
2811 return; 3260 case SENSOR_PO1200:
2812 data = 0; 3261 data = 0;
2813 i2c_write(gspca_dev, 0x03, &data, 1); 3262 i2c_write(gspca_dev, 0x03, &data, 1);
2814 data = 0xb5 + sd->sharpness * 3; 3263 if (sd->sharpness < 0)
2815 i2c_write(gspca_dev, 0x61, &data, 1); 3264 data = 0x6a;
3265 else
3266 data = 0xb5 + sd->sharpness * 3;
3267 i2c_write(gspca_dev, 0x61, &data, 1);
3268 break;
3269 case SENSOR_POxxxx:
3270 if (sd->sharpness < 0)
3271 data = 0x7e; /* def = max */
3272 else
3273 data = 0x60 + sd->sharpness * 0x0f;
3274 i2c_write(gspca_dev, 0x59, &data, 1);
3275 break;
3276 }
2816} 3277}
2817 3278
2818static int sd_start(struct gspca_dev *gspca_dev) 3279static int sd_start(struct gspca_dev *gspca_dev)
@@ -2922,12 +3383,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
2922 usb_exchange(gspca_dev, init); 3383 usb_exchange(gspca_dev, init);
2923 init = po3130_rundata; 3384 init = po3130_rundata;
2924 break; 3385 break;
2925 default: 3386 case SENSOR_PO1200:
2926/* case SENSOR_PO1200: */
2927 GammaT = po1200_gamma; 3387 GammaT = po1200_gamma;
2928 MatrixT = po1200_matrix; 3388 MatrixT = po1200_matrix;
2929 init = po1200_initVGA_data; 3389 init = po1200_initVGA_data;
2930 break; 3390 break;
3391 default:
3392/* case SENSOR_POxxxx: */
3393 usb_exchange(gspca_dev, poxxxx_init_common);
3394 if (mode)
3395 init = poxxxx_initQVGA;
3396 else
3397 init = poxxxx_initVGA;
3398 usb_exchange(gspca_dev, init);
3399 reg_r(gspca_dev, 0x8c, 0x0000, 3);
3400 reg_w(gspca_dev->dev, 0xa0,
3401 gspca_dev->usb_buf[2] & 1 ? 0 : 1,
3402 0xb35c);
3403 msleep(300);
3404/*fixme: i2c read 04 and 05*/
3405 init = poxxxx_init_end_1;
3406 break;
2931 } 3407 }
2932 usb_exchange(gspca_dev, init); 3408 usb_exchange(gspca_dev, init);
2933 if (GammaT && MatrixT) { 3409 if (GammaT && MatrixT) {
@@ -2936,7 +3412,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
2936 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); 3412 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
2937 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); 3413 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
2938 3414
2939 /* set the led on 0x0892 0x0896 */
2940 switch (sd->sensor) { 3415 switch (sd->sensor) {
2941 case SENSOR_PO1200: 3416 case SENSOR_PO1200:
2942 case SENSOR_HV7131R: 3417 case SENSOR_HV7131R:
@@ -2945,16 +3420,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
2945 case SENSOR_MI1310_SOC: 3420 case SENSOR_MI1310_SOC:
2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000); 3421 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
2947 break; 3422 break;
2948 default:
2949 if (!(sd->flags & FL_SAMSUNG))
2950 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
2951 break;
2952 } 3423 }
2953 msleep(100); 3424 msleep(100);
2954 setsharpness(gspca_dev); 3425 setsharpness(gspca_dev);
2955 sethvflip(gspca_dev); 3426 sethvflip(gspca_dev);
2956 setlightfreq(gspca_dev); 3427 setlightfreq(gspca_dev);
2957 } 3428 }
3429 if (sd->sensor == SENSOR_POxxxx) {
3430 setcolors(gspca_dev);
3431 setbrightness(gspca_dev);
3432 setcontrast(gspca_dev);
3433
3434 /* led on */
3435 msleep(80);
3436 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
3437 usb_exchange(gspca_dev, poxxxx_init_end_2);
3438 }
2958 return 0; 3439 return 0;
2959} 3440}
2960 3441
@@ -2963,10 +3444,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2963 struct usb_device *dev = gspca_dev->dev; 3444 struct usb_device *dev = gspca_dev->dev;
2964 struct sd *sd = (struct sd *) gspca_dev; 3445 struct sd *sd = (struct sd *) gspca_dev;
2965 3446
2966 if (sd->sensor == SENSOR_MI1310_SOC) 3447 switch (sd->sensor) {
3448 case SENSOR_MI1310_SOC:
2967 reg_w(dev, 0x89, 0x058c, 0x00ff); 3449 reg_w(dev, 0x89, 0x058c, 0x00ff);
2968 else if (!(sd->flags & FL_SAMSUNG)) 3450 break;
2969 reg_w(dev, 0x89, 0xffff, 0xffff); 3451 case SENSOR_POxxxx:
3452 return;
3453 default:
3454 if (!(sd->flags & FL_SAMSUNG))
3455 reg_w(dev, 0x89, 0xffff, 0xffff);
3456 break;
3457 }
2970 reg_w(dev, 0xa0, 0x01, 0xb301); 3458 reg_w(dev, 0xa0, 0x01, 0xb301);
2971 reg_w(dev, 0xa0, 0x09, 0xb003); 3459 reg_w(dev, 0xa0, 0x09, 0xb003);
2972} 3460}
@@ -2984,6 +3472,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2984 reg_w(dev, 0x89, 0x058c, 0x00ff); 3472 reg_w(dev, 0x89, 0x058c, 0x00ff);
2985 else if (!(sd->flags & FL_SAMSUNG)) 3473 else if (!(sd->flags & FL_SAMSUNG))
2986 reg_w(dev, 0x89, 0xffff, 0xffff); 3474 reg_w(dev, 0x89, 0xffff, 0xffff);
3475
3476 if (sd->sensor == SENSOR_POxxxx) {
3477 reg_w(dev, 0xa0, 0x26, 0xb300);
3478 reg_w(dev, 0xa0, 0x04, 0xb300);
3479 reg_w(dev, 0xa0, 0x00, 0xb300);
3480 }
2987} 3481}
2988 3482
2989static void sd_pkt_scan(struct gspca_dev *gspca_dev, 3483static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -3020,6 +3514,60 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3020 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 3514 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3021} 3515}
3022 3516
3517static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
3518{
3519 struct sd *sd = (struct sd *) gspca_dev;
3520
3521 sd->brightness = val;
3522 if (gspca_dev->streaming)
3523 setbrightness(gspca_dev);
3524 return 0;
3525}
3526
3527static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
3528{
3529 struct sd *sd = (struct sd *) gspca_dev;
3530
3531 *val = sd->brightness;
3532 return 0;
3533}
3534
3535static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
3536{
3537 struct sd *sd = (struct sd *) gspca_dev;
3538
3539 sd->contrast = val;
3540 if (gspca_dev->streaming)
3541 setcontrast(gspca_dev);
3542 return 0;
3543}
3544
3545static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
3546{
3547 struct sd *sd = (struct sd *) gspca_dev;
3548
3549 *val = sd->contrast;
3550 return 0;
3551}
3552
3553static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
3554{
3555 struct sd *sd = (struct sd *) gspca_dev;
3556
3557 sd->colors = val;
3558 if (gspca_dev->streaming)
3559 setcolors(gspca_dev);
3560 return 0;
3561}
3562
3563static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
3564{
3565 struct sd *sd = (struct sd *) gspca_dev;
3566
3567 *val = sd->colors;
3568 return 0;
3569}
3570
3023static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 3571static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
3024{ 3572{
3025 struct sd *sd = (struct sd *) gspca_dev; 3573 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 1a800fc1c00e..50986da3d912 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Z-Star/Vimicro zc301/zc302p/vc30x library 2 * Z-Star/Vimicro zc301/zc302p/vc30x library
3 * Copyright (C) 2004 2005 2006 Michel Xhaard
4 * mxhaard@magic.fr
5 * 3 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2010 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
7 * 6 *
8 * 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
9 * 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
@@ -22,10 +21,11 @@
22 21
23#define MODULE_NAME "zc3xx" 22#define MODULE_NAME "zc3xx"
24 23
24#include <linux/input.h>
25#include "gspca.h" 25#include "gspca.h"
26#include "jpeg.h" 26#include "jpeg.h"
27 27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " 28MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
29 "Serge A. Suchkov <Serge.A.S@tochka.ru>"); 29 "Serge A. Suchkov <Serge.A.S@tochka.ru>");
30MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
@@ -39,18 +39,18 @@ static int force_sensor = -1;
39struct sd { 39struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */ 40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 41
42 __u8 brightness; 42 u8 brightness;
43 __u8 contrast; 43 u8 contrast;
44 __u8 gamma; 44 u8 gamma;
45 __u8 autogain; 45 u8 autogain;
46 __u8 lightfreq; 46 u8 lightfreq;
47 __u8 sharpness; 47 u8 sharpness;
48 u8 quality; /* image quality */ 48 u8 quality; /* image quality */
49#define QUALITY_MIN 40 49#define QUALITY_MIN 40
50#define QUALITY_MAX 60 50#define QUALITY_MAX 60
51#define QUALITY_DEF 50 51#define QUALITY_DEF 50
52 52
53 signed char sensor; /* Type of image sensor chip */ 53 u8 sensor; /* Type of image sensor chip */
54/* !! values used in different tables */ 54/* !! values used in different tables */
55#define SENSOR_ADCM2700 0 55#define SENSOR_ADCM2700 0
56#define SENSOR_CS2102 1 56#define SENSOR_CS2102 1
@@ -92,9 +92,8 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 92static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 93static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
94 94
95static struct ctrl sd_ctrls[] = { 95static const struct ctrl sd_ctrls[] = {
96#define BRIGHTNESS_IDX 0 96#define BRIGHTNESS_IDX 0
97#define SD_BRIGHTNESS 0
98 { 97 {
99 { 98 {
100 .id = V4L2_CID_BRIGHTNESS, 99 .id = V4L2_CID_BRIGHTNESS,
@@ -103,26 +102,26 @@ static struct ctrl sd_ctrls[] = {
103 .minimum = 0, 102 .minimum = 0,
104 .maximum = 255, 103 .maximum = 255,
105 .step = 1, 104 .step = 1,
106 .default_value = 128, 105#define BRIGHTNESS_DEF 128
106 .default_value = BRIGHTNESS_DEF,
107 }, 107 },
108 .set = sd_setbrightness, 108 .set = sd_setbrightness,
109 .get = sd_getbrightness, 109 .get = sd_getbrightness,
110 }, 110 },
111#define SD_CONTRAST 1
112 { 111 {
113 { 112 {
114 .id = V4L2_CID_CONTRAST, 113 .id = V4L2_CID_CONTRAST,
115 .type = V4L2_CTRL_TYPE_INTEGER, 114 .type = V4L2_CTRL_TYPE_INTEGER,
116 .name = "Contrast", 115 .name = "Contrast",
117 .minimum = 0, 116 .minimum = 0,
118 .maximum = 256, 117 .maximum = 255,
119 .step = 1, 118 .step = 1,
120 .default_value = 128, 119#define CONTRAST_DEF 128
120 .default_value = CONTRAST_DEF,
121 }, 121 },
122 .set = sd_setcontrast, 122 .set = sd_setcontrast,
123 .get = sd_getcontrast, 123 .get = sd_getcontrast,
124 }, 124 },
125#define SD_GAMMA 2
126 { 125 {
127 { 126 {
128 .id = V4L2_CID_GAMMA, 127 .id = V4L2_CID_GAMMA,
@@ -136,7 +135,6 @@ static struct ctrl sd_ctrls[] = {
136 .set = sd_setgamma, 135 .set = sd_setgamma,
137 .get = sd_getgamma, 136 .get = sd_getgamma,
138 }, 137 },
139#define SD_AUTOGAIN 3
140 { 138 {
141 { 139 {
142 .id = V4L2_CID_AUTOGAIN, 140 .id = V4L2_CID_AUTOGAIN,
@@ -145,13 +143,13 @@ static struct ctrl sd_ctrls[] = {
145 .minimum = 0, 143 .minimum = 0,
146 .maximum = 1, 144 .maximum = 1,
147 .step = 1, 145 .step = 1,
148 .default_value = 1, 146#define AUTOGAIN_DEF 1
147 .default_value = AUTOGAIN_DEF,
149 }, 148 },
150 .set = sd_setautogain, 149 .set = sd_setautogain,
151 .get = sd_getautogain, 150 .get = sd_getautogain,
152 }, 151 },
153#define LIGHTFREQ_IDX 4 152#define LIGHTFREQ_IDX 4
154#define SD_FREQ 4
155 { 153 {
156 { 154 {
157 .id = V4L2_CID_POWER_LINE_FREQUENCY, 155 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -160,12 +158,12 @@ static struct ctrl sd_ctrls[] = {
160 .minimum = 0, 158 .minimum = 0,
161 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ 159 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
162 .step = 1, 160 .step = 1,
163 .default_value = 1, 161#define FREQ_DEF 0
162 .default_value = FREQ_DEF,
164 }, 163 },
165 .set = sd_setfreq, 164 .set = sd_setfreq,
166 .get = sd_getfreq, 165 .get = sd_getfreq,
167 }, 166 },
168#define SD_SHARPNESS 5
169 { 167 {
170 { 168 {
171 .id = V4L2_CID_SHARPNESS, 169 .id = V4L2_CID_SHARPNESS,
@@ -174,7 +172,8 @@ static struct ctrl sd_ctrls[] = {
174 .minimum = 0, 172 .minimum = 0,
175 .maximum = 3, 173 .maximum = 3,
176 .step = 1, 174 .step = 1,
177 .default_value = 2, 175#define SHARPNESS_DEF 2
176 .default_value = SHARPNESS_DEF,
178 }, 177 },
179 .set = sd_setsharpness, 178 .set = sd_setsharpness,
180 .get = sd_getsharpness, 179 .get = sd_getsharpness,
@@ -194,6 +193,19 @@ static const struct v4l2_pix_format vga_mode[] = {
194 .priv = 0}, 193 .priv = 0},
195}; 194};
196 195
196static const struct v4l2_pix_format broken_vga_mode[] = {
197 {320, 232, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
198 .bytesperline = 320,
199 .sizeimage = 320 * 232 * 4 / 8 + 590,
200 .colorspace = V4L2_COLORSPACE_JPEG,
201 .priv = 1},
202 {640, 472, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
203 .bytesperline = 640,
204 .sizeimage = 640 * 472 * 3 / 8 + 590,
205 .colorspace = V4L2_COLORSPACE_JPEG,
206 .priv = 0},
207};
208
197static const struct v4l2_pix_format sif_mode[] = { 209static const struct v4l2_pix_format sif_mode[] = {
198 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 210 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199 .bytesperline = 176, 211 .bytesperline = 176,
@@ -209,9 +221,9 @@ static const struct v4l2_pix_format sif_mode[] = {
209 221
210/* usb exchanges */ 222/* usb exchanges */
211struct usb_action { 223struct usb_action {
212 __u8 req; 224 u8 req;
213 __u8 val; 225 u8 val;
214 __u16 idx; 226 u16 idx;
215}; 227};
216 228
217static const struct usb_action adcm2700_Initial[] = { 229static const struct usb_action adcm2700_Initial[] = {
@@ -421,7 +433,7 @@ static const struct usb_action adcm2700_NoFliker[] = {
421 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ 433 {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
422 {} 434 {}
423}; 435};
424static const struct usb_action cs2102_Initial[] = { /* 320x240 */ 436static const struct usb_action cs2102_InitialScale[] = { /* 320x240 */
425 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 437 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
426 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 438 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
427 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 439 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -473,7 +485,7 @@ static const struct usb_action cs2102_Initial[] = { /* 320x240 */
473 {} 485 {}
474}; 486};
475 487
476static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */ 488static const struct usb_action cs2102_Initial[] = { /* 640x480 */
477 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 489 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
478 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 490 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
479 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 491 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -524,7 +536,7 @@ static const struct usb_action cs2102_InitialScale[] = { /* 640x480 */
524 {0xa0, 0x00, 0x01ad}, 536 {0xa0, 0x00, 0x01ad},
525 {} 537 {}
526}; 538};
527static const struct usb_action cs2102_50HZ[] = { 539static const struct usb_action cs2102_50HZScale[] = {
528 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 540 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
529 {0xaa, 0x23, 0x0001}, 541 {0xaa, 0x23, 0x0001},
530 {0xaa, 0x24, 0x005f}, 542 {0xaa, 0x24, 0x005f},
@@ -546,7 +558,7 @@ static const struct usb_action cs2102_50HZ[] = {
546 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 558 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
547 {} 559 {}
548}; 560};
549static const struct usb_action cs2102_50HZScale[] = { 561static const struct usb_action cs2102_50HZ[] = {
550 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 562 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
551 {0xaa, 0x23, 0x0000}, 563 {0xaa, 0x23, 0x0000},
552 {0xaa, 0x24, 0x00af}, 564 {0xaa, 0x24, 0x00af},
@@ -568,7 +580,7 @@ static const struct usb_action cs2102_50HZScale[] = {
568 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 580 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
569 {} 581 {}
570}; 582};
571static const struct usb_action cs2102_60HZ[] = { 583static const struct usb_action cs2102_60HZScale[] = {
572 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 584 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
573 {0xaa, 0x23, 0x0001}, 585 {0xaa, 0x23, 0x0001},
574 {0xaa, 0x24, 0x0055}, 586 {0xaa, 0x24, 0x0055},
@@ -590,7 +602,7 @@ static const struct usb_action cs2102_60HZ[] = {
590 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 602 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
591 {} 603 {}
592}; 604};
593static const struct usb_action cs2102_60HZScale[] = { 605static const struct usb_action cs2102_60HZ[] = {
594 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 606 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
595 {0xaa, 0x23, 0x0000}, 607 {0xaa, 0x23, 0x0000},
596 {0xaa, 0x24, 0x00aa}, 608 {0xaa, 0x24, 0x00aa},
@@ -612,7 +624,7 @@ static const struct usb_action cs2102_60HZScale[] = {
612 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 624 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
613 {} 625 {}
614}; 626};
615static const struct usb_action cs2102_NoFliker[] = { 627static const struct usb_action cs2102_NoFlikerScale[] = {
616 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 628 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
617 {0xaa, 0x23, 0x0001}, 629 {0xaa, 0x23, 0x0001},
618 {0xaa, 0x24, 0x005f}, 630 {0xaa, 0x24, 0x005f},
@@ -634,7 +646,7 @@ static const struct usb_action cs2102_NoFliker[] = {
634 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, 646 {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
635 {} 647 {}
636}; 648};
637static const struct usb_action cs2102_NoFlikerScale[] = { 649static const struct usb_action cs2102_NoFliker[] = {
638 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, 650 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
639 {0xaa, 0x23, 0x0000}, 651 {0xaa, 0x23, 0x0000},
640 {0xaa, 0x24, 0x00af}, 652 {0xaa, 0x24, 0x00af},
@@ -658,7 +670,7 @@ static const struct usb_action cs2102_NoFlikerScale[] = {
658}; 670};
659 671
660/* CS2102_KOCOM */ 672/* CS2102_KOCOM */
661static const struct usb_action cs2102K_Initial[] = { 673static const struct usb_action cs2102K_InitialScale[] = {
662 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 674 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
663 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 675 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
664 {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, 676 {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -917,7 +929,7 @@ static const struct usb_action cs2102K_Initial[] = {
917 {} 929 {}
918}; 930};
919 931
920static const struct usb_action cs2102K_InitialScale[] = { 932static const struct usb_action cs2102K_Initial[] = {
921 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 933 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
922 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 934 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
923 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 935 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1495,7 +1507,7 @@ static const struct usb_action gc0305_NoFliker[] = {
1495 {} 1507 {}
1496}; 1508};
1497 1509
1498static const struct usb_action hdcs2020xb_Initial[] = { 1510static const struct usb_action hdcs2020b_InitialScale[] = {
1499 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1511 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1500 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 1512 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
1501 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ 1513 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */
@@ -1627,7 +1639,7 @@ static const struct usb_action hdcs2020xb_Initial[] = {
1627 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 1639 {0xa0, 0x40, ZC3XX_R118_BGAIN},
1628 {} 1640 {}
1629}; 1641};
1630static const struct usb_action hdcs2020xb_InitialScale[] = { 1642static const struct usb_action hdcs2020b_Initial[] = {
1631 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1643 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1632 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 1644 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1633 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 1645 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1819,7 +1831,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = {
1819 {} 1831 {}
1820}; 1832};
1821 1833
1822static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */ 1834static const struct usb_action hv7131b_InitialScale[] = { /* 320x240 */
1823 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1835 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1824 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 1836 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
1825 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 1837 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -1866,7 +1878,7 @@ static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
1866 {} 1878 {}
1867}; 1879};
1868 1880
1869static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/ 1881static const struct usb_action hv7131b_Initial[] = { /* 640x480*/
1870 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1882 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1871 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 1883 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1872 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, 1884 {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2063,7 +2075,7 @@ static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
2063 {} 2075 {}
2064}; 2076};
2065 2077
2066static const struct usb_action hv7131cxx_Initial[] = { 2078static const struct usb_action hv7131r_InitialScale[] = {
2067 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2079 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2068 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 2080 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
2069 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, 2081 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2157,7 +2169,7 @@ static const struct usb_action hv7131cxx_Initial[] = {
2157 {} 2169 {}
2158}; 2170};
2159 2171
2160static const struct usb_action hv7131cxx_InitialScale[] = { 2172static const struct usb_action hv7131r_Initial[] = {
2161 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2173 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2162 2174
2163 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */ 2175 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */
@@ -2259,7 +2271,7 @@ static const struct usb_action hv7131cxx_InitialScale[] = {
2259 {} 2271 {}
2260}; 2272};
2261 2273
2262static const struct usb_action icm105axx_Initial[] = { 2274static const struct usb_action icm105a_InitialScale[] = {
2263 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2275 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2264 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 2276 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
2265 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 2277 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -2436,7 +2448,7 @@ static const struct usb_action icm105axx_Initial[] = {
2436 {} 2448 {}
2437}; 2449};
2438 2450
2439static const struct usb_action icm105axx_InitialScale[] = { 2451static const struct usb_action icm105a_Initial[] = {
2440 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 2452 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
2441 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 2453 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
2442 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 2454 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -2615,7 +2627,7 @@ static const struct usb_action icm105axx_InitialScale[] = {
2615 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 2627 {0xa0, 0x40, ZC3XX_R118_BGAIN},
2616 {} 2628 {}
2617}; 2629};
2618static const struct usb_action icm105a_50HZ[] = { 2630static const struct usb_action icm105a_50HZScale[] = {
2619 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2631 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2620 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2632 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2621 {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ 2633 {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */
@@ -2646,7 +2658,7 @@ static const struct usb_action icm105a_50HZ[] = {
2646 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 2658 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
2647 {} 2659 {}
2648}; 2660};
2649static const struct usb_action icm105a_50HZScale[] = { 2661static const struct usb_action icm105a_50HZ[] = {
2650 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2662 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2651 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2663 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2652 {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ 2664 {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */
@@ -2679,7 +2691,7 @@ static const struct usb_action icm105a_50HZScale[] = {
2679 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ 2691 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
2680 {} 2692 {}
2681}; 2693};
2682static const struct usb_action icm105a_60HZ[] = { 2694static const struct usb_action icm105a_60HZScale[] = {
2683 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2695 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2684 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2696 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2685 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ 2697 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2710,7 +2722,7 @@ static const struct usb_action icm105a_60HZ[] = {
2710 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 2722 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
2711 {} 2723 {}
2712}; 2724};
2713static const struct usb_action icm105a_60HZScale[] = { 2725static const struct usb_action icm105a_60HZ[] = {
2714 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2726 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2715 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2727 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2716 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ 2728 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
@@ -2743,7 +2755,7 @@ static const struct usb_action icm105a_60HZScale[] = {
2743 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ 2755 {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
2744 {} 2756 {}
2745}; 2757};
2746static const struct usb_action icm105a_NoFliker[] = { 2758static const struct usb_action icm105a_NoFlikerScale[] = {
2747 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2759 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2748 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2760 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2749 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ 2761 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2774,7 +2786,7 @@ static const struct usb_action icm105a_NoFliker[] = {
2774 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ 2786 {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
2775 {} 2787 {}
2776}; 2788};
2777static const struct usb_action icm105a_NoFlikerScale[] = { 2789static const struct usb_action icm105a_NoFliker[] = {
2778 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 2790 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
2779 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ 2791 {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
2780 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ 2792 {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
@@ -2808,7 +2820,7 @@ static const struct usb_action icm105a_NoFlikerScale[] = {
2808 {} 2820 {}
2809}; 2821};
2810 2822
2811static const struct usb_action MC501CB_InitialScale[] = { 2823static const struct usb_action mc501cb_Initial[] = {
2812 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 2824 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
2813 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ 2825 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
2814 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 2826 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -2928,7 +2940,7 @@ static const struct usb_action MC501CB_InitialScale[] = {
2928 {} 2940 {}
2929}; 2941};
2930 2942
2931static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ 2943static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
2932 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 2944 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
2933 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ 2945 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
2934 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 2946 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -3047,7 +3059,7 @@ static const struct usb_action MC501CB_Initial[] = { /* 320x240 */
3047 {} 3059 {}
3048}; 3060};
3049 3061
3050static const struct usb_action MC501CB_50HZ[] = { 3062static const struct usb_action mc501cb_50HZScale[] = {
3051 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3063 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3052 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3064 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3053 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ 3065 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
@@ -3064,7 +3076,7 @@ static const struct usb_action MC501CB_50HZ[] = {
3064 {} 3076 {}
3065}; 3077};
3066 3078
3067static const struct usb_action MC501CB_50HZScale[] = { 3079static const struct usb_action mc501cb_50HZ[] = {
3068 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3080 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3069 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3081 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3070 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ 3082 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
@@ -3081,7 +3093,7 @@ static const struct usb_action MC501CB_50HZScale[] = {
3081 {} 3093 {}
3082}; 3094};
3083 3095
3084static const struct usb_action MC501CB_60HZ[] = { 3096static const struct usb_action mc501cb_60HZScale[] = {
3085 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3097 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3086 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3098 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3087 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3099 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3098,7 +3110,7 @@ static const struct usb_action MC501CB_60HZ[] = {
3098 {} 3110 {}
3099}; 3111};
3100 3112
3101static const struct usb_action MC501CB_60HZScale[] = { 3113static const struct usb_action mc501cb_60HZ[] = {
3102 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3114 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3103 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3115 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3104 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3116 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3115,7 +3127,7 @@ static const struct usb_action MC501CB_60HZScale[] = {
3115 {} 3127 {}
3116}; 3128};
3117 3129
3118static const struct usb_action MC501CB_NoFliker[] = { 3130static const struct usb_action mc501cb_NoFlikerScale[] = {
3119 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3131 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3120 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3132 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3121 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3133 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3132,7 +3144,7 @@ static const struct usb_action MC501CB_NoFliker[] = {
3132 {} 3144 {}
3133}; 3145};
3134 3146
3135static const struct usb_action MC501CB_NoFlikerScale[] = { 3147static const struct usb_action mc501cb_NoFliker[] = {
3136 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3148 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3137 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3149 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3138 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3150 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3144,8 +3156,8 @@ static const struct usb_action MC501CB_NoFlikerScale[] = {
3144 {} 3156 {}
3145}; 3157};
3146 3158
3147/* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ 3159/* from zs211.inf */
3148static const struct usb_action OV7620_mode0[] = { 3160static const struct usb_action ov7620_Initial[] = { /* 640x480 */
3149 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 3161 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
3150 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */ 3162 {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */
3151 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 3163 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
@@ -3214,9 +3226,7 @@ static const struct usb_action OV7620_mode0[] = {
3214 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ 3226 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
3215 {} 3227 {}
3216}; 3228};
3217 3229static const struct usb_action ov7620_InitialScale[] = { /* 320x240 */
3218/* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */
3219static const struct usb_action OV7620_mode1[] = {
3220 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 3230 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
3221 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */ 3231 {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */
3222 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 3232 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
@@ -3287,9 +3297,7 @@ static const struct usb_action OV7620_mode1[] = {
3287 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ 3297 {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
3288 {} 3298 {}
3289}; 3299};
3290 3300static const struct usb_action ov7620_50HZ[] = {
3291/* from zs211.inf - HKR,%OV7620%\AE,50HZ */
3292static const struct usb_action OV7620_50HZ[] = {
3293 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ 3301 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
3294 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ 3302 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
3295 {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ 3303 {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
@@ -3307,9 +3315,7 @@ static const struct usb_action OV7620_50HZ[] = {
3307 if mode0 (640x480) */ 3315 if mode0 (640x480) */
3308 {} 3316 {}
3309}; 3317};
3310 3318static const struct usb_action ov7620_60HZ[] = {
3311/* from zs211.inf - HKR,%OV7620%\AE,60HZ */
3312static const struct usb_action OV7620_60HZ[] = {
3313 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ 3319 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
3314 /* (bug in zs211.inf) */ 3320 /* (bug in zs211.inf) */
3315 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ 3321 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
@@ -3331,9 +3337,7 @@ static const struct usb_action OV7620_60HZ[] = {
3331 {0xa1, 0x01, 0x0037}, */ 3337 {0xa1, 0x01, 0x0037}, */
3332 {} 3338 {}
3333}; 3339};
3334 3340static const struct usb_action ov7620_NoFliker[] = {
3335/* from zs211.inf - HKR,%OV7620%\AE,NoFliker */
3336static const struct usb_action OV7620_NoFliker[] = {
3337 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ 3341 {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
3338 /* (bug in zs211.inf) */ 3342 /* (bug in zs211.inf) */
3339 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ 3343 {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
@@ -3354,7 +3358,7 @@ static const struct usb_action OV7620_NoFliker[] = {
3354 {} 3358 {}
3355}; 3359};
3356 3360
3357static const struct usb_action ov7630c_Initial[] = { 3361static const struct usb_action ov7630c_InitialScale[] = {
3358 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 3362 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
3359 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, 3363 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
3360 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 3364 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
@@ -3511,7 +3515,7 @@ static const struct usb_action ov7630c_Initial[] = {
3511 {} 3515 {}
3512}; 3516};
3513 3517
3514static const struct usb_action ov7630c_InitialScale[] = { 3518static const struct usb_action ov7630c_Initial[] = {
3515 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 3519 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
3516 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 3520 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
3517 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 3521 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -3682,7 +3686,7 @@ static const struct usb_action pas106b_Initial_com[] = {
3682 {} 3686 {}
3683}; 3687};
3684 3688
3685static const struct usb_action pas106b_Initial[] = { /* 176x144 */ 3689static const struct usb_action pas106b_InitialScale[] = { /* 176x144 */
3686/* JPEG control */ 3690/* JPEG control */
3687 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 3691 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
3688/* Sream and Sensor specific */ 3692/* Sream and Sensor specific */
@@ -3800,7 +3804,7 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */
3800 {} 3804 {}
3801}; 3805};
3802 3806
3803static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ 3807static const struct usb_action pas106b_Initial[] = { /* 352x288 */
3804/* JPEG control */ 3808/* JPEG control */
3805 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 3809 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
3806/* Sream and Sensor specific */ 3810/* Sream and Sensor specific */
@@ -3972,10 +3976,10 @@ static const struct usb_action pas106b_NoFliker[] = {
3972 {} 3976 {}
3973}; 3977};
3974 3978
3975/* from usbvm31b.inf */ 3979/* from lvWIMv.inf 046d:08a2/:08aa 2007/06/03 */
3976static const struct usb_action pas202b_Initial[] = { /* 640x480 */ 3980static const struct usb_action pas202b_Initial[] = { /* 640x480 */
3977 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 3981 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
3978 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 3982 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
3979 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */ 3983 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
3980 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ 3984 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
3981 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ 3985 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
@@ -4000,7 +4004,7 @@ static const struct usb_action pas202b_Initial[] = { /* 640x480 */
4000 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */ 4004 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4001 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */ 4005 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4002 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */ 4006 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4003 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ 4007 {0xaa, 0x0c, 0x0006},
4004 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */ 4008 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4005 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ 4009 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4006 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */ 4010 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
@@ -4019,13 +4023,13 @@ static const struct usb_action pas202b_Initial[] = { /* 640x480 */
4019}; 4023};
4020static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */ 4024static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4021 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 4025 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4022 {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ 4026 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
4023 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */ 4027 {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0e,cc */
4024 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ 4028 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
4025 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ 4029 {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
4026 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ 4030 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
4027 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ 4031 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
4028 {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ 4032 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
4029 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ 4033 {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
4030 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ 4034 {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
4031 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ 4035 {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
@@ -4035,7 +4039,7 @@ static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4035 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */ 4039 {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,08,cc */
4036 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */ 4040 {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,02,cc */
4037 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ 4041 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
4038 {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ 4042 {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
4039 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ 4043 {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
4040 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ 4044 {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
4041 {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */ 4045 {0xaa, 0x02, 0x0002}, /* 00,02,02,aa */
@@ -4044,7 +4048,7 @@ static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4044 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */ 4048 {0xaa, 0x09, 0x0006}, /* 00,09,06,aa */
4045 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */ 4049 {0xaa, 0x0a, 0x0001}, /* 00,0a,01,aa */
4046 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */ 4050 {0xaa, 0x0b, 0x0001}, /* 00,0b,01,aa */
4047 {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ 4051 {0xaa, 0x0c, 0x0006},
4048 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */ 4052 {0xaa, 0x0d, 0x0000}, /* 00,0d,00,aa */
4049 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ 4053 {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
4050 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */ 4054 {0xaa, 0x12, 0x0005}, /* 00,12,05,aa */
@@ -4059,6 +4063,8 @@ static const struct usb_action pas202b_InitialScale[] = { /* 320x240 */
4059 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ 4063 {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
4060 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ 4064 {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
4061 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */ 4065 {0xa0, 0x70, ZC3XX_R18D_YTARGET}, /* 01,8d,70,cc */
4066 {0xa0, 0xff, ZC3XX_R097_WINYSTARTHIGH},
4067 {0xa0, 0xfe, ZC3XX_R098_WINYSTARTLOW},
4062 {} 4068 {}
4063}; 4069};
4064static const struct usb_action pas202b_50HZ[] = { 4070static const struct usb_action pas202b_50HZ[] = {
@@ -4066,22 +4072,22 @@ static const struct usb_action pas202b_50HZ[] = {
4066 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4072 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4067 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4073 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4068 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4074 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4069 {0xaa, 0x21, 0x0068}, /* 00,21,68,aa */ 4075 {0xaa, 0x21, 0x001b},
4070 {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */ 4076 {0xaa, 0x03, 0x0044}, /* 00,03,44,aa */
4071 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */ 4077 {0xaa, 0x04, 0x0008},
4072 {0xaa, 0x05, 0x0028}, /* 00,05,28,aa */ 4078 {0xaa, 0x05, 0x001b},
4073 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4079 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4074 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4080 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4075 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4081 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4076 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4082 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4077 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4083 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4078 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4084 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
4079 {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,d2,cc */ 4085 {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
4080 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4086 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4081 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4087 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4082 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */ 4088 {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4d,cc */
4083 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4089 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4084 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4090 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4085 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */ 4091 {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, /* 00,1d,44,cc */
4086 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ 4092 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4087 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */ 4093 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
@@ -4094,23 +4100,23 @@ static const struct usb_action pas202b_50HZScale[] = {
4094 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4100 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4095 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4101 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4096 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4102 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4097 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4103 {0xaa, 0x20, 0x0004},
4098 {0xaa, 0x21, 0x006c}, /* 00,21,6c,aa */ 4104 {0xaa, 0x21, 0x003d},
4099 {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */ 4105 {0xaa, 0x03, 0x0041}, /* 00,03,41,aa */
4100 {0xaa, 0x04, 0x0009}, /* 00,04,09,aa */ 4106 {0xaa, 0x04, 0x0010},
4101 {0xaa, 0x05, 0x002c}, /* 00,05,2c,aa */ 4107 {0xaa, 0x05, 0x003d},
4102 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4108 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4103 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4109 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4104 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4110 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4105 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4111 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4106 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4112 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4107 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */ 4113 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
4108 {0xa0, 0xbe, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,be,cc */ 4114 {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
4109 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4115 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4110 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4116 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4111 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */ 4117 {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,9b,cc */
4112 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4118 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4113 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4119 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4114 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ 4120 {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
4115 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ 4121 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4116 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */ 4122 {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ad,cc */
@@ -4130,16 +4136,16 @@ static const struct usb_action pas202b_60HZ[] = {
4130 {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ 4136 {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
4131 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4137 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4132 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4138 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4133 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4139 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4134 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4140 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4135 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4141 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4136 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4142 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
4137 {0xa0, 0xc0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,c0,cc */ 4143 {0xa0, 0x00, ZC3XX_R192_EXPOSURELIMITLOW},
4138 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4144 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4139 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4145 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4140 {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */ 4146 {0xa0, 0x40, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,40,cc */
4141 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4147 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4142 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4148 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4143 {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */ 4149 {0xa0, 0x45, ZC3XX_R01D_HSYNC_0}, /* 00,1d,45,cc */
4144 {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */ 4150 {0xa0, 0x8e, ZC3XX_R01E_HSYNC_1}, /* 00,1e,8e,cc */
4145 {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */ 4151 {0xa0, 0xc1, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c1,cc */
@@ -4152,23 +4158,23 @@ static const struct usb_action pas202b_60HZScale[] = {
4152 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4158 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4153 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4159 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4154 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4160 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4155 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4161 {0xaa, 0x20, 0x0004},
4156 {0xaa, 0x21, 0x0004}, /* 00,21,04,aa */ 4162 {0xaa, 0x21, 0x0008},
4157 {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */ 4163 {0xaa, 0x03, 0x0042}, /* 00,03,42,aa */
4158 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ 4164 {0xaa, 0x04, 0x0010},
4159 {0xaa, 0x05, 0x0004}, /* 00,05,04,aa */ 4165 {0xaa, 0x05, 0x0008},
4160 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4166 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4161 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4167 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4162 {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,14,cc */ 4168 {0xa0, 0x1c, ZC3XX_R1A9_DIGITALLIMITDIFF},
4163 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ 4169 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
4164 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4170 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4165 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */ 4171 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
4166 {0xa0, 0x9f, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,9f,cc */ 4172 {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW},
4167 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4173 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4168 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4174 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4169 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */ 4175 {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
4170 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4176 {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
4171 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4177 {0xa0, 0x1b, ZC3XX_R18F_AEUNFREEZE},
4172 {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */ 4178 {0xa0, 0x42, ZC3XX_R01D_HSYNC_0}, /* 00,1d,42,cc */
4173 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */ 4179 {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, /* 00,1e,6f,cc */
4174 {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */ 4180 {0xa0, 0xaf, ZC3XX_R01F_HSYNC_2}, /* 00,1f,af,cc */
@@ -4182,22 +4188,22 @@ static const struct usb_action pas202b_NoFliker[] = {
4182 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4188 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4183 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4189 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4184 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4190 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */
4185 {0xaa, 0x21, 0x0020}, /* 00,21,20,aa */ 4191 {0xaa, 0x21, 0x0006},
4186 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */ 4192 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4187 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ 4193 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */
4188 {0xaa, 0x05, 0x0020}, /* 00,05,20,aa */ 4194 {0xaa, 0x05, 0x0006},
4189 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4195 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4190 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4196 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4191 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4197 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4192 {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ 4198 {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
4193 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4199 {0xa0, 0x06, ZC3XX_R192_EXPOSURELIMITLOW},
4194 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4200 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4195 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4201 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4196 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */ 4202 {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW},
4197 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4203 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4198 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4204 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4199 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4205 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4200 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4206 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4201 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */ 4207 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4202 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */ 4208 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4203 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4209 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
@@ -4210,23 +4216,23 @@ static const struct usb_action pas202b_NoFlikerScale[] = {
4210 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 4216 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
4211 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */ 4217 {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
4212 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */ 4218 {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
4213 {0xaa, 0x20, 0x0002}, /* 00,20,02,aa */ 4219 {0xaa, 0x20, 0x0004},
4214 {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */ 4220 {0xaa, 0x21, 0x000c},
4215 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */ 4221 {0xaa, 0x03, 0x0040}, /* 00,03,40,aa */
4216 {0xaa, 0x04, 0x0008}, /* 00,04,08,aa */ 4222 {0xaa, 0x04, 0x0010},
4217 {0xaa, 0x05, 0x0010}, /* 00,05,10,aa */ 4223 {0xaa, 0x05, 0x000c},
4218 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */ 4224 {0xaa, 0x0e, 0x0001}, /* 00,0e,01,aa */
4219 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */ 4225 {0xaa, 0x0f, 0x0000}, /* 00,0f,00,aa */
4220 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ 4226 {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
4221 {0xa0, 0x0f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0f,cc */ 4227 {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
4222 {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ 4228 {0xa0, 0x0c, ZC3XX_R192_EXPOSURELIMITLOW},
4223 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ 4229 {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
4224 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ 4230 {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
4225 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */ 4231 {0xa0, 0x02, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,02,cc */
4226 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ 4232 {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
4227 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ 4233 {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
4228 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ 4234 {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
4229 {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ 4235 {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
4230 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */ 4236 {0xa0, 0x40, ZC3XX_R01D_HSYNC_0}, /* 00,1d,40,cc */
4231 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */ 4237 {0xa0, 0x60, ZC3XX_R01E_HSYNC_1}, /* 00,1e,60,cc */
4232 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ 4238 {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
@@ -4713,8 +4719,8 @@ static const struct usb_action pb0330_NoFlikerScale[] = {
4713 {} 4719 {}
4714}; 4720};
4715 4721
4716/* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ 4722/* from oem9.inf */
4717static const struct usb_action PO2030_mode0[] = { 4723static const struct usb_action po2030_Initial[] = { /* 640x480 */
4718 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 4724 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4719 {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ 4725 {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
4720 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 4726 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -4790,8 +4796,8 @@ static const struct usb_action PO2030_mode0[] = {
4790 {} 4796 {}
4791}; 4797};
4792 4798
4793/* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ 4799/* from oem9.inf */
4794static const struct usb_action PO2030_mode1[] = { 4800static const struct usb_action po2030_InitialScale[] = { /* 320x240 */
4795 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ 4801 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
4796 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ 4802 {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
4797 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ 4803 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
@@ -4867,7 +4873,7 @@ static const struct usb_action PO2030_mode1[] = {
4867 {} 4873 {}
4868}; 4874};
4869 4875
4870static const struct usb_action PO2030_50HZ[] = { 4876static const struct usb_action po2030_50HZ[] = {
4871 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ 4877 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
4872 {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ 4878 {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */
4873 {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ 4879 {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */
@@ -4889,7 +4895,7 @@ static const struct usb_action PO2030_50HZ[] = {
4889 {} 4895 {}
4890}; 4896};
4891 4897
4892static const struct usb_action PO2030_60HZ[] = { 4898static const struct usb_action po2030_60HZ[] = {
4893 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ 4899 {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
4894 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ 4900 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
4895 {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ 4901 {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */
@@ -4912,7 +4918,7 @@ static const struct usb_action PO2030_60HZ[] = {
4912 {} 4918 {}
4913}; 4919};
4914 4920
4915static const struct usb_action PO2030_NoFliker[] = { 4921static const struct usb_action po2030_NoFliker[] = {
4916 {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ 4922 {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
4917 {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ 4923 {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
4918 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ 4924 {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
@@ -4924,7 +4930,7 @@ static const struct usb_action PO2030_NoFliker[] = {
4924}; 4930};
4925 4931
4926/* TEST */ 4932/* TEST */
4927static const struct usb_action tas5130CK_Initial[] = { 4933static const struct usb_action tas5130cK_InitialScale[] = {
4928 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 4934 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
4929 {0xa0, 0x01, 0x003b}, 4935 {0xa0, 0x01, 0x003b},
4930 {0xa0, 0x0e, 0x003a}, 4936 {0xa0, 0x0e, 0x003a},
@@ -5127,7 +5133,7 @@ static const struct usb_action tas5130CK_Initial[] = {
5127 {} 5133 {}
5128}; 5134};
5129 5135
5130static const struct usb_action tas5130CK_InitialScale[] = { 5136static const struct usb_action tas5130cK_Initial[] = {
5131 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 5137 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
5132 {0xa0, 0x01, 0x003b}, 5138 {0xa0, 0x01, 0x003b},
5133 {0xa0, 0x0e, 0x003a}, 5139 {0xa0, 0x0e, 0x003a},
@@ -5560,7 +5566,7 @@ static const struct usb_action tas5130cxx_NoFlikerScale[] = {
5560 {} 5566 {}
5561}; 5567};
5562 5568
5563static const struct usb_action tas5130c_vf0250_Initial[] = { 5569static const struct usb_action tas5130c_vf0250_InitialScale[] = {
5564 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ 5570 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
5565 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ 5571 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
5566 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ 5572 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
@@ -5627,7 +5633,7 @@ static const struct usb_action tas5130c_vf0250_Initial[] = {
5627 {} 5633 {}
5628}; 5634};
5629 5635
5630static const struct usb_action tas5130c_vf0250_InitialScale[] = { 5636static const struct usb_action tas5130c_vf0250_Initial[] = {
5631 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ 5637 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
5632 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ 5638 {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
5633 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ 5639 {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
@@ -5692,8 +5698,7 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = {
5692 {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ 5698 {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
5693 {} 5699 {}
5694}; 5700};
5695/* "50HZ" light frequency banding filter */ 5701static const struct usb_action tas5130c_vf0250_50HZScale[] = {
5696static const struct usb_action tas5130c_vf0250_50HZ[] = {
5697 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5702 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5698 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ 5703 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
5699 {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ 5704 {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */
@@ -5717,8 +5722,7 @@ static const struct usb_action tas5130c_vf0250_50HZ[] = {
5717 {} 5722 {}
5718}; 5723};
5719 5724
5720/* "50HZScale" light frequency banding filter */ 5725static const struct usb_action tas5130c_vf0250_50HZ[] = {
5721static const struct usb_action tas5130c_vf0250_50HZScale[] = {
5722 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5726 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5723 {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ 5727 {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */
5724 {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ 5728 {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */
@@ -5742,8 +5746,7 @@ static const struct usb_action tas5130c_vf0250_50HZScale[] = {
5742 {} 5746 {}
5743}; 5747};
5744 5748
5745/* "60HZ" light frequency banding filter */ 5749static const struct usb_action tas5130c_vf0250_60HZScale[] = {
5746static const struct usb_action tas5130c_vf0250_60HZ[] = {
5747 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5750 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5748 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ 5751 {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
5749 {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ 5752 {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */
@@ -5767,8 +5770,7 @@ static const struct usb_action tas5130c_vf0250_60HZ[] = {
5767 {} 5770 {}
5768}; 5771};
5769 5772
5770/* "60HZScale" light frequency banding ilter */ 5773static const struct usb_action tas5130c_vf0250_60HZ[] = {
5771static const struct usb_action tas5130c_vf0250_60HZScale[] = {
5772 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5774 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5773 {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ 5775 {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */
5774 {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ 5776 {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */
@@ -5792,8 +5794,7 @@ static const struct usb_action tas5130c_vf0250_60HZScale[] = {
5792 {} 5794 {}
5793}; 5795};
5794 5796
5795/* "NoFliker" light frequency banding flter */ 5797static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
5796static const struct usb_action tas5130c_vf0250_NoFliker[] = {
5797 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ 5798 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
5798 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5799 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5799 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ 5800 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
@@ -5815,8 +5816,7 @@ static const struct usb_action tas5130c_vf0250_NoFliker[] = {
5815 {} 5816 {}
5816}; 5817};
5817 5818
5818/* "NoFlikerScale" light frequency banding filter */ 5819static const struct usb_action tas5130c_vf0250_NoFliker[] = {
5819static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
5820 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ 5820 {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
5821 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ 5821 {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
5822 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ 5822 {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
@@ -5839,7 +5839,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
5839}; 5839};
5840 5840
5841static u8 reg_r_i(struct gspca_dev *gspca_dev, 5841static u8 reg_r_i(struct gspca_dev *gspca_dev,
5842 __u16 index) 5842 u16 index)
5843{ 5843{
5844 usb_control_msg(gspca_dev->dev, 5844 usb_control_msg(gspca_dev->dev,
5845 usb_rcvctrlpipe(gspca_dev->dev, 0), 5845 usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -5852,7 +5852,7 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev,
5852} 5852}
5853 5853
5854static u8 reg_r(struct gspca_dev *gspca_dev, 5854static u8 reg_r(struct gspca_dev *gspca_dev,
5855 __u16 index) 5855 u16 index)
5856{ 5856{
5857 u8 ret; 5857 u8 ret;
5858 5858
@@ -5862,8 +5862,8 @@ static u8 reg_r(struct gspca_dev *gspca_dev,
5862} 5862}
5863 5863
5864static void reg_w_i(struct usb_device *dev, 5864static void reg_w_i(struct usb_device *dev,
5865 __u8 value, 5865 u8 value,
5866 __u16 index) 5866 u16 index)
5867{ 5867{
5868 usb_control_msg(dev, 5868 usb_control_msg(dev,
5869 usb_sndctrlpipe(dev, 0), 5869 usb_sndctrlpipe(dev, 0),
@@ -5874,18 +5874,18 @@ static void reg_w_i(struct usb_device *dev,
5874} 5874}
5875 5875
5876static void reg_w(struct usb_device *dev, 5876static void reg_w(struct usb_device *dev,
5877 __u8 value, 5877 u8 value,
5878 __u16 index) 5878 u16 index)
5879{ 5879{
5880 PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value); 5880 PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
5881 reg_w_i(dev, value, index); 5881 reg_w_i(dev, value, index);
5882} 5882}
5883 5883
5884static __u16 i2c_read(struct gspca_dev *gspca_dev, 5884static u16 i2c_read(struct gspca_dev *gspca_dev,
5885 __u8 reg) 5885 u8 reg)
5886{ 5886{
5887 __u8 retbyte; 5887 u8 retbyte;
5888 __u16 retval; 5888 u16 retval;
5889 5889
5890 reg_w_i(gspca_dev->dev, reg, 0x0092); 5890 reg_w_i(gspca_dev->dev, reg, 0x0092);
5891 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ 5891 reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
@@ -5900,12 +5900,12 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
5900 return retval; 5900 return retval;
5901} 5901}
5902 5902
5903static __u8 i2c_write(struct gspca_dev *gspca_dev, 5903static u8 i2c_write(struct gspca_dev *gspca_dev,
5904 __u8 reg, 5904 u8 reg,
5905 __u8 valL, 5905 u8 valL,
5906 __u8 valH) 5906 u8 valH)
5907{ 5907{
5908 __u8 retbyte; 5908 u8 retbyte;
5909 5909
5910 reg_w_i(gspca_dev->dev, reg, 0x92); 5910 reg_w_i(gspca_dev->dev, reg, 0x92);
5911 reg_w_i(gspca_dev->dev, valL, 0x93); 5911 reg_w_i(gspca_dev->dev, valL, 0x93);
@@ -5957,24 +5957,24 @@ static void setmatrix(struct gspca_dev *gspca_dev)
5957{ 5957{
5958 struct sd *sd = (struct sd *) gspca_dev; 5958 struct sd *sd = (struct sd *) gspca_dev;
5959 int i; 5959 int i;
5960 const __u8 *matrix; 5960 const u8 *matrix;
5961 static const u8 adcm2700_matrix[9] = 5961 static const u8 adcm2700_matrix[9] =
5962/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */ 5962/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
5963/*ms-win*/ 5963/*ms-win*/
5964 {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74}; 5964 {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
5965 static const __u8 gc0305_matrix[9] = 5965 static const u8 gc0305_matrix[9] =
5966 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; 5966 {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
5967 static const __u8 ov7620_matrix[9] = 5967 static const u8 ov7620_matrix[9] =
5968 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; 5968 {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
5969 static const __u8 pas202b_matrix[9] = 5969 static const u8 pas202b_matrix[9] =
5970 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f}; 5970 {0x4c, 0xf5, 0xff, 0xf9, 0x51, 0xf5, 0xfb, 0xed, 0x5f};
5971 static const __u8 po2030_matrix[9] = 5971 static const u8 po2030_matrix[9] =
5972 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; 5972 {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
5973 static const u8 tas5130c_matrix[9] = 5973 static const u8 tas5130c_matrix[9] =
5974 {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68}; 5974 {0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
5975 static const __u8 vf0250_matrix[9] = 5975 static const u8 vf0250_matrix[9] =
5976 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; 5976 {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
5977 static const __u8 *matrix_tb[SENSOR_MAX] = { 5977 static const u8 *matrix_tb[SENSOR_MAX] = {
5978 adcm2700_matrix, /* SENSOR_ADCM2700 0 */ 5978 adcm2700_matrix, /* SENSOR_ADCM2700 0 */
5979 ov7620_matrix, /* SENSOR_CS2102 1 */ 5979 ov7620_matrix, /* SENSOR_CS2102 1 */
5980 NULL, /* SENSOR_CS2102K 2 */ 5980 NULL, /* SENSOR_CS2102K 2 */
@@ -6006,11 +6006,12 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6006static void setbrightness(struct gspca_dev *gspca_dev) 6006static void setbrightness(struct gspca_dev *gspca_dev)
6007{ 6007{
6008 struct sd *sd = (struct sd *) gspca_dev; 6008 struct sd *sd = (struct sd *) gspca_dev;
6009 __u8 brightness; 6009 u8 brightness;
6010 6010
6011 switch (sd->sensor) { 6011 switch (sd->sensor) {
6012 case SENSOR_GC0305: 6012 case SENSOR_GC0305:
6013 case SENSOR_OV7620: 6013 case SENSOR_OV7620:
6014 case SENSOR_PAS202B:
6014 case SENSOR_PO2030: 6015 case SENSOR_PO2030:
6015 return; 6016 return;
6016 } 6017 }
@@ -6034,7 +6035,7 @@ static void setsharpness(struct gspca_dev *gspca_dev)
6034 struct sd *sd = (struct sd *) gspca_dev; 6035 struct sd *sd = (struct sd *) gspca_dev;
6035 struct usb_device *dev = gspca_dev->dev; 6036 struct usb_device *dev = gspca_dev->dev;
6036 int sharpness; 6037 int sharpness;
6037 static const __u8 sharpness_tb[][2] = { 6038 static const u8 sharpness_tb[][2] = {
6038 {0x02, 0x03}, 6039 {0x02, 0x03},
6039 {0x04, 0x07}, 6040 {0x04, 0x07},
6040 {0x08, 0x0f}, 6041 {0x08, 0x0f},
@@ -6053,118 +6054,69 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6053{ 6054{
6054 struct sd *sd = (struct sd *) gspca_dev; 6055 struct sd *sd = (struct sd *) gspca_dev;
6055 struct usb_device *dev = gspca_dev->dev; 6056 struct usb_device *dev = gspca_dev->dev;
6056 const __u8 *Tgamma, *Tgradient; 6057 const u8 *Tgamma;
6057 int g, i, k; 6058 int g, i, k, adj, gp;
6058 static const __u8 kgamma_tb[16] = /* delta for contrast */ 6059 u8 gr[16];
6060 static const u8 delta_tb[16] = /* delta for contrast */
6059 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 6061 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08,
6060 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; 6062 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
6061 static const __u8 kgrad_tb[16] = 6063 static const u8 gamma_tb[6][16] = {
6062 {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
6063 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04};
6064 static const __u8 Tgamma_1[16] =
6065 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, 6064 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
6066 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}; 6065 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff},
6067 static const __u8 Tgradient_1[16] =
6068 {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a,
6069 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06};
6070 static const __u8 Tgamma_2[16] =
6071 {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, 6066 {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c,
6072 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}; 6067 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff},
6073 static const __u8 Tgradient_2[16] =
6074 {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15,
6075 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03};
6076 static const __u8 Tgamma_3[16] =
6077 {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, 6068 {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac,
6078 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}; 6069 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff},
6079 static const __u8 Tgradient_3[16] =
6080 {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12,
6081 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03};
6082 static const __u8 Tgamma_4[16] =
6083 {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 6070 {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
6084 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}; 6071 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff},
6085 static const __u8 Tgradient_4[16] =
6086 {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d,
6087 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02};
6088 static const __u8 Tgamma_5[16] =
6089 {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, 6072 {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2,
6090 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}; 6073 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff},
6091 static const __u8 Tgradient_5[16] =
6092 {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b,
6093 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02};
6094 static const __u8 Tgamma_6[16] = /* ?? was gamma 5 */
6095 {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, 6074 {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3,
6096 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; 6075 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
6097 static const __u8 Tgradient_6[16] =
6098 {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e,
6099 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01};
6100 static const __u8 *gamma_tb[] = {
6101 NULL, Tgamma_1, Tgamma_2,
6102 Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6
6103 }; 6076 };
6104 static const __u8 *gradient_tb[] = {
6105 NULL, Tgradient_1, Tgradient_2,
6106 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
6107 };
6108#ifdef GSPCA_DEBUG
6109 __u8 v[16];
6110#endif
6111 6077
6112 Tgamma = gamma_tb[sd->gamma]; 6078 Tgamma = gamma_tb[sd->gamma - 1];
6113 Tgradient = gradient_tb[sd->gamma];
6114 6079
6115 k = (sd->contrast - 128) /* -128 / 128 */ 6080 k = ((int) sd->contrast - 128); /* -128 / 128 */
6116 * Tgamma[0]; 6081 adj = 0;
6117 PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128", 6082 gp = 0;
6118 sd->gamma, sd->contrast, k);
6119 for (i = 0; i < 16; i++) { 6083 for (i = 0; i < 16; i++) {
6120 g = Tgamma[i] + kgamma_tb[i] * k / 128; 6084 g = Tgamma[i] - delta_tb[i] * k / 128 - adj / 2;
6121 if (g > 0xff) 6085 if (g > 0xff)
6122 g = 0xff; 6086 g = 0xff;
6123 else if (g <= 0) 6087 else if (g <= 0)
6124 g = 1; 6088 g = 1;
6125 reg_w(dev, g, 0x0120 + i); /* gamma */ 6089 reg_w(dev, g, 0x0120 + i); /* gamma */
6126#ifdef GSPCA_DEBUG 6090 if (k > 0)
6127 if (gspca_debug & D_CONF) 6091 adj--;
6128 v[i] = g; 6092 else
6129#endif 6093 adj++;
6130 } 6094
6131 PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x", 6095 if (i != 0) {
6132 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 6096 if (gp == 0)
6133 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6097 gr[i - 1] = 0;
6134 v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
6135 for (i = 0; i < 16; i++) {
6136 g = Tgradient[i] - kgrad_tb[i] * k / 128;
6137 if (g > 0xff)
6138 g = 0xff;
6139 else if (g <= 0) {
6140 if (i != 15)
6141 g = 0;
6142 else 6098 else
6143 g = 1; 6099 gr[i - 1] = g - gp;
6144 } 6100 }
6145 reg_w(dev, g, 0x0130 + i); /* gradient */ 6101 gp = g;
6146#ifdef GSPCA_DEBUG
6147 if (gspca_debug & D_CONF)
6148 v[i] = g;
6149#endif
6150 } 6102 }
6151 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6103 gr[15] = gr[14] / 2;
6152 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 6104 for (i = 0; i < 16; i++)
6153 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6105 reg_w(dev, gr[i], 0x0130 + i); /* gradient */
6154 v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
6155} 6106}
6156 6107
6157static void setquality(struct gspca_dev *gspca_dev) 6108static void setquality(struct gspca_dev *gspca_dev)
6158{ 6109{
6159 struct sd *sd = (struct sd *) gspca_dev; 6110 struct sd *sd = (struct sd *) gspca_dev;
6160 struct usb_device *dev = gspca_dev->dev; 6111 struct usb_device *dev = gspca_dev->dev;
6161 __u8 frxt; 6112 u8 frxt;
6162 6113
6163 switch (sd->sensor) { 6114 switch (sd->sensor) {
6164 case SENSOR_ADCM2700: 6115 case SENSOR_ADCM2700:
6165 case SENSOR_GC0305: 6116 case SENSOR_GC0305:
6166 case SENSOR_HV7131B: 6117 case SENSOR_HV7131B:
6167 case SENSOR_OV7620: 6118 case SENSOR_OV7620:
6119 case SENSOR_PAS202B:
6168 case SENSOR_PO2030: 6120 case SENSOR_PO2030:
6169 return; 6121 return;
6170 } 6122 }
@@ -6218,9 +6170,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6218 hdcs2020b_50HZ, hdcs2020b_50HZ, 6170 hdcs2020b_50HZ, hdcs2020b_50HZ,
6219 hdcs2020b_60HZ, hdcs2020b_60HZ}, 6171 hdcs2020b_60HZ, hdcs2020b_60HZ},
6220/* SENSOR_HV7131B 5 */ 6172/* SENSOR_HV7131B 5 */
6221 {hv7131b_NoFlikerScale, hv7131b_NoFliker, 6173 {hv7131b_NoFliker, hv7131b_NoFlikerScale,
6222 hv7131b_50HZScale, hv7131b_50HZ, 6174 hv7131b_50HZ, hv7131b_50HZScale,
6223 hv7131b_60HZScale, hv7131b_60HZ}, 6175 hv7131b_60HZ, hv7131b_60HZScale},
6224/* SENSOR_HV7131C 6 */ 6176/* SENSOR_HV7131C 6 */
6225 {NULL, NULL, 6177 {NULL, NULL,
6226 NULL, NULL, 6178 NULL, NULL,
@@ -6230,17 +6182,17 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6230 icm105a_50HZ, icm105a_50HZScale, 6182 icm105a_50HZ, icm105a_50HZScale,
6231 icm105a_60HZ, icm105a_60HZScale}, 6183 icm105a_60HZ, icm105a_60HZScale},
6232/* SENSOR_MC501CB 8 */ 6184/* SENSOR_MC501CB 8 */
6233 {MC501CB_NoFliker, MC501CB_NoFlikerScale, 6185 {mc501cb_NoFliker, mc501cb_NoFlikerScale,
6234 MC501CB_50HZ, MC501CB_50HZScale, 6186 mc501cb_50HZ, mc501cb_50HZScale,
6235 MC501CB_60HZ, MC501CB_60HZScale}, 6187 mc501cb_60HZ, mc501cb_60HZScale},
6236/* SENSOR_MI0360SOC 9 */ 6188/* SENSOR_MI0360SOC 9 */
6237 {mi360soc_AENoFlikerScale, mi360soc_AENoFliker, 6189 {mi360soc_AENoFliker, mi360soc_AENoFlikerScale,
6238 mi360soc_AE50HZScale, mi360soc_AE50HZ, 6190 mi360soc_AE50HZ, mi360soc_AE50HZScale,
6239 mi360soc_AE60HZScale, mi360soc_AE60HZ}, 6191 mi360soc_AE60HZ, mi360soc_AE60HZScale},
6240/* SENSOR_OV7620 10 */ 6192/* SENSOR_OV7620 10 */
6241 {OV7620_NoFliker, OV7620_NoFliker, 6193 {ov7620_NoFliker, ov7620_NoFliker,
6242 OV7620_50HZ, OV7620_50HZ, 6194 ov7620_50HZ, ov7620_50HZ,
6243 OV7620_60HZ, OV7620_60HZ}, 6195 ov7620_60HZ, ov7620_60HZ},
6244/* SENSOR_OV7630C 11 */ 6196/* SENSOR_OV7630C 11 */
6245 {NULL, NULL, 6197 {NULL, NULL,
6246 NULL, NULL, 6198 NULL, NULL,
@@ -6258,17 +6210,17 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6258 pb0330_50HZScale, pb0330_50HZ, 6210 pb0330_50HZScale, pb0330_50HZ,
6259 pb0330_60HZScale, pb0330_60HZ}, 6211 pb0330_60HZScale, pb0330_60HZ},
6260/* SENSOR_PO2030 15 */ 6212/* SENSOR_PO2030 15 */
6261 {PO2030_NoFliker, PO2030_NoFliker, 6213 {po2030_NoFliker, po2030_NoFliker,
6262 PO2030_50HZ, PO2030_50HZ, 6214 po2030_50HZ, po2030_50HZ,
6263 PO2030_60HZ, PO2030_60HZ}, 6215 po2030_60HZ, po2030_60HZ},
6264/* SENSOR_TAS5130CK 16 */ 6216/* SENSOR_TAS5130CK 16 */
6265 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, 6217 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
6266 tas5130cxx_50HZScale, tas5130cxx_50HZ, 6218 tas5130cxx_50HZ, tas5130cxx_50HZScale,
6267 tas5130cxx_60HZScale, tas5130cxx_60HZ}, 6219 tas5130cxx_60HZ, tas5130cxx_60HZScale},
6268/* SENSOR_TAS5130CXX 17 */ 6220/* SENSOR_TAS5130CXX 17 */
6269 {tas5130cxx_NoFlikerScale, tas5130cxx_NoFliker, 6221 {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
6270 tas5130cxx_50HZScale, tas5130cxx_50HZ, 6222 tas5130cxx_50HZ, tas5130cxx_50HZScale,
6271 tas5130cxx_60HZScale, tas5130cxx_60HZ}, 6223 tas5130cxx_60HZ, tas5130cxx_60HZScale},
6272/* SENSOR_TAS5130C_VF0250 18 */ 6224/* SENSOR_TAS5130C_VF0250 18 */
6273 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, 6225 {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
6274 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, 6226 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
@@ -6277,9 +6229,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6277 6229
6278 i = sd->lightfreq * 2; 6230 i = sd->lightfreq * 2;
6279 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 6231 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
6280 if (!mode) 6232 if (mode)
6281 i++; /* 640x480 */ 6233 i++; /* 320x240 */
6282 zc3_freq = freq_tb[(int) sd->sensor][i]; 6234 zc3_freq = freq_tb[sd->sensor][i];
6283 if (zc3_freq != NULL) { 6235 if (zc3_freq != NULL) {
6284 usb_exchange(gspca_dev, zc3_freq); 6236 usb_exchange(gspca_dev, zc3_freq);
6285 switch (sd->sensor) { 6237 switch (sd->sensor) {
@@ -6297,6 +6249,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6297 reg_w(gspca_dev->dev, 0x44, 0x0002); 6249 reg_w(gspca_dev->dev, 0x44, 0x0002);
6298 } 6250 }
6299 break; 6251 break;
6252 case SENSOR_PAS202B:
6253 reg_w(gspca_dev->dev, 0x00, 0x01a7);
6254 break;
6300 } 6255 }
6301 } 6256 }
6302 return 0; 6257 return 0;
@@ -6305,7 +6260,7 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6305static void setautogain(struct gspca_dev *gspca_dev) 6260static void setautogain(struct gspca_dev *gspca_dev)
6306{ 6261{
6307 struct sd *sd = (struct sd *) gspca_dev; 6262 struct sd *sd = (struct sd *) gspca_dev;
6308 __u8 autoval; 6263 u8 autoval;
6309 6264
6310 if (sd->autogain) 6265 if (sd->autogain)
6311 autoval = 0x42; 6266 autoval = 0x42;
@@ -6333,6 +6288,12 @@ static void send_unknown(struct usb_device *dev, int sensor)
6333 reg_w(dev, 0x02, 0x003b); 6288 reg_w(dev, 0x02, 0x003b);
6334 reg_w(dev, 0x00, 0x0038); 6289 reg_w(dev, 0x00, 0x0038);
6335 break; 6290 break;
6291 case SENSOR_PAS202B:
6292 reg_w(dev, 0x03, 0x003b);
6293 reg_w(dev, 0x0c, 0x003a);
6294 reg_w(dev, 0x0b, 0x0039);
6295 reg_w(dev, 0x0b, 0x0038);
6296 break;
6336 } 6297 }
6337} 6298}
6338 6299
@@ -6349,7 +6310,7 @@ static void start_2wr_probe(struct usb_device *dev, int sensor)
6349 6310
6350static int sif_probe(struct gspca_dev *gspca_dev) 6311static int sif_probe(struct gspca_dev *gspca_dev)
6351{ 6312{
6352 __u16 checkword; 6313 u16 checkword;
6353 6314
6354 start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */ 6315 start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */
6355 reg_w(gspca_dev->dev, 0x08, 0x008d); 6316 reg_w(gspca_dev->dev, 0x08, 0x008d);
@@ -6392,6 +6353,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
6392 } 6353 }
6393 6354
6394 start_2wr_probe(dev, 0x08); /* HDCS2020 */ 6355 start_2wr_probe(dev, 0x08); /* HDCS2020 */
6356 i2c_write(gspca_dev, 0x1c, 0x00, 0x00);
6395 i2c_write(gspca_dev, 0x15, 0xaa, 0x00); 6357 i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
6396 retword = i2c_read(gspca_dev, 0x15); 6358 retword = i2c_read(gspca_dev, 0x15);
6397 if (retword != 0) 6359 if (retword != 0)
@@ -6420,8 +6382,10 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
6420 i2c_write(gspca_dev, 0x03, 0xaa, 0x00); 6382 i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
6421 msleep(50); 6383 msleep(50);
6422 retword = i2c_read(gspca_dev, 0x03); 6384 retword = i2c_read(gspca_dev, 0x03);
6423 if (retword != 0) 6385 if (retword != 0) {
6386 send_unknown(dev, SENSOR_PAS202B);
6424 return 0x0e; /* PAS202BCB */ 6387 return 0x0e; /* PAS202BCB */
6388 }
6425 6389
6426 start_2wr_probe(dev, 0x02); /* TAS5130C */ 6390 start_2wr_probe(dev, 0x02); /* TAS5130C */
6427 i2c_write(gspca_dev, 0x01, 0xaa, 0x00); 6391 i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
@@ -6457,8 +6421,8 @@ ov_check:
6457} 6421}
6458 6422
6459struct sensor_by_chipset_revision { 6423struct sensor_by_chipset_revision {
6460 __u16 revision; 6424 u16 revision;
6461 __u8 internal_sensor_id; 6425 u8 internal_sensor_id;
6462}; 6426};
6463static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { 6427static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6464 {0xc000, 0x12}, /* TAS5130C */ 6428 {0xc000, 0x12}, /* TAS5130C */
@@ -6467,6 +6431,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6467 {0x8001, 0x13}, 6431 {0x8001, 0x13},
6468 {0x8000, 0x14}, /* CS2102K */ 6432 {0x8000, 0x14}, /* CS2102K */
6469 {0x8400, 0x15}, /* TAS5130K */ 6433 {0x8400, 0x15}, /* TAS5130K */
6434 {0xe400, 0x15},
6470}; 6435};
6471 6436
6472static int vga_3wr_probe(struct gspca_dev *gspca_dev) 6437static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6474,7 +6439,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6474 struct sd *sd = (struct sd *) gspca_dev; 6439 struct sd *sd = (struct sd *) gspca_dev;
6475 struct usb_device *dev = gspca_dev->dev; 6440 struct usb_device *dev = gspca_dev->dev;
6476 int i; 6441 int i;
6477 __u8 retbyte; 6442 u8 retbyte;
6478 u16 retword; 6443 u16 retword;
6479 6444
6480/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ 6445/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
@@ -6622,8 +6587,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
6622 struct sd *sd = (struct sd *) gspca_dev; 6587 struct sd *sd = (struct sd *) gspca_dev;
6623 struct cam *cam; 6588 struct cam *cam;
6624 int sensor; 6589 int sensor;
6625 int vga = 1; /* 1: vga, 0: sif */ 6590 static const u8 gamma[SENSOR_MAX] = {
6626 static const __u8 gamma[SENSOR_MAX] = {
6627 4, /* SENSOR_ADCM2700 0 */ 6591 4, /* SENSOR_ADCM2700 0 */
6628 4, /* SENSOR_CS2102 1 */ 6592 4, /* SENSOR_CS2102 1 */
6629 5, /* SENSOR_CS2102K 2 */ 6593 5, /* SENSOR_CS2102K 2 */
@@ -6644,9 +6608,30 @@ static int sd_config(struct gspca_dev *gspca_dev,
6644 3, /* SENSOR_TAS5130CXX 17 */ 6608 3, /* SENSOR_TAS5130CXX 17 */
6645 3, /* SENSOR_TAS5130C_VF0250 18 */ 6609 3, /* SENSOR_TAS5130C_VF0250 18 */
6646 }; 6610 };
6611 static const u8 mode_tb[SENSOR_MAX] = {
6612 2, /* SENSOR_ADCM2700 0 */
6613 1, /* SENSOR_CS2102 1 */
6614 1, /* SENSOR_CS2102K 2 */
6615 1, /* SENSOR_GC0305 3 */
6616 1, /* SENSOR_HDCS2020b 4 */
6617 1, /* SENSOR_HV7131B 5 */
6618 1, /* SENSOR_HV7131C 6 */
6619 1, /* SENSOR_ICM105A 7 */
6620 2, /* SENSOR_MC501CB 8 */
6621 1, /* SENSOR_MI0360SOC 9 */
6622 2, /* SENSOR_OV7620 10 */
6623 1, /* SENSOR_OV7630C 11 */
6624 0, /* SENSOR_PAS106 12 */
6625 1, /* SENSOR_PAS202B 13 */
6626 1, /* SENSOR_PB0330 14 */
6627 1, /* SENSOR_PO2030 15 */
6628 1, /* SENSOR_TAS5130CK 16 */
6629 1, /* SENSOR_TAS5130CXX 17 */
6630 1, /* SENSOR_TAS5130C_VF0250 18 */
6631 };
6647 6632
6648 /* define some sensors from the vendor/product */ 6633 /* define some sensors from the vendor/product */
6649 sd->sharpness = 2; 6634 sd->sharpness = SHARPNESS_DEF;
6650 sd->sensor = id->driver_info; 6635 sd->sensor = id->driver_info;
6651 sensor = zcxx_probeSensor(gspca_dev); 6636 sensor = zcxx_probeSensor(gspca_dev);
6652 if (sensor >= 0) 6637 if (sensor >= 0)
@@ -6671,8 +6656,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
6671 } 6656 }
6672 break; 6657 break;
6673 case 0: 6658 case 0:
6674 PDEBUG(D_PROBE, "Find Sensor HV7131B"); 6659 /* check the sensor type */
6675 sd->sensor = SENSOR_HV7131B; 6660 sensor = i2c_read(gspca_dev, 0x00);
6661 PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor);
6662 switch (sensor) {
6663 case 0: /* hv7131b */
6664 case 1: /* hv7131e */
6665 PDEBUG(D_PROBE, "Find Sensor HV7131B");
6666 sd->sensor = SENSOR_HV7131B;
6667 break;
6668 default:
6669/* case 2: * hv7131r */
6670 PDEBUG(D_PROBE, "Find Sensor HV7131R(c)");
6671 sd->sensor = SENSOR_HV7131C;
6672 break;
6673 }
6676 break; 6674 break;
6677 case 0x02: 6675 case 0x02:
6678 PDEBUG(D_PROBE, "Sensor TAS5130C"); 6676 PDEBUG(D_PROBE, "Sensor TAS5130C");
@@ -6699,12 +6697,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
6699 case 0x0e: 6697 case 0x0e:
6700 PDEBUG(D_PROBE, "Find Sensor PAS202B"); 6698 PDEBUG(D_PROBE, "Find Sensor PAS202B");
6701 sd->sensor = SENSOR_PAS202B; 6699 sd->sensor = SENSOR_PAS202B;
6702 sd->sharpness = 1; 6700/* sd->sharpness = 1; */
6703 break; 6701 break;
6704 case 0x0f: 6702 case 0x0f:
6705 PDEBUG(D_PROBE, "Find Sensor PAS106"); 6703 PDEBUG(D_PROBE, "Find Sensor PAS106");
6706 sd->sensor = SENSOR_PAS106; 6704 sd->sensor = SENSOR_PAS106;
6707 vga = 0; /* SIF */
6708 break; 6705 break;
6709 case 0x10: 6706 case 0x10:
6710 case 0x12: 6707 case 0x12:
@@ -6770,31 +6767,38 @@ static int sd_config(struct gspca_dev *gspca_dev,
6770 if (sensor < 0x20) { 6767 if (sensor < 0x20) {
6771 if (sensor == -1 || sensor == 0x10 || sensor == 0x12) 6768 if (sensor == -1 || sensor == 0x10 || sensor == 0x12)
6772 reg_w(gspca_dev->dev, 0x02, 0x0010); 6769 reg_w(gspca_dev->dev, 0x02, 0x0010);
6773 else
6774 reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010);
6775 reg_r(gspca_dev, 0x0010); 6770 reg_r(gspca_dev, 0x0010);
6776 } 6771 }
6777 6772
6778 cam = &gspca_dev->cam; 6773 cam = &gspca_dev->cam;
6779/*fixme:test*/ 6774/*fixme:test*/
6780 gspca_dev->nbalt--; 6775 gspca_dev->nbalt--;
6781 if (vga) { 6776 switch (mode_tb[sd->sensor]) {
6782 cam->cam_mode = vga_mode; 6777 case 0:
6783 cam->nmodes = ARRAY_SIZE(vga_mode);
6784 } else {
6785 cam->cam_mode = sif_mode; 6778 cam->cam_mode = sif_mode;
6786 cam->nmodes = ARRAY_SIZE(sif_mode); 6779 cam->nmodes = ARRAY_SIZE(sif_mode);
6780 break;
6781 case 1:
6782 cam->cam_mode = vga_mode;
6783 cam->nmodes = ARRAY_SIZE(vga_mode);
6784 break;
6785 default:
6786/* case 2: */
6787 cam->cam_mode = broken_vga_mode;
6788 cam->nmodes = ARRAY_SIZE(broken_vga_mode);
6789 break;
6787 } 6790 }
6788 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 6791 sd->brightness = BRIGHTNESS_DEF;
6789 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 6792 sd->contrast = CONTRAST_DEF;
6790 sd->gamma = gamma[(int) sd->sensor]; 6793 sd->gamma = gamma[sd->sensor];
6791 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; 6794 sd->autogain = AUTOGAIN_DEF;
6792 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; 6795 sd->lightfreq = FREQ_DEF;
6793 sd->quality = QUALITY_DEF; 6796 sd->quality = QUALITY_DEF;
6794 6797
6795 switch (sd->sensor) { 6798 switch (sd->sensor) {
6796 case SENSOR_GC0305: 6799 case SENSOR_GC0305:
6797 case SENSOR_OV7620: 6800 case SENSOR_OV7620:
6801 case SENSOR_PAS202B:
6798 case SENSOR_PO2030: 6802 case SENSOR_PO2030:
6799 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); 6803 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
6800 break; 6804 break;
@@ -6805,14 +6809,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
6805 break; 6809 break;
6806 } 6810 }
6807 6811
6808 /* switch the led off */
6809 reg_w(gspca_dev->dev, 0x01, 0x0000);
6810 return 0; 6812 return 0;
6811} 6813}
6812 6814
6813/* this function is called at probe and resume time */ 6815/* this function is called at probe and resume time */
6814static int sd_init(struct gspca_dev *gspca_dev) 6816static int sd_init(struct gspca_dev *gspca_dev)
6815{ 6817{
6818 /* switch off the led */
6816 reg_w(gspca_dev->dev, 0x01, 0x0000); 6819 reg_w(gspca_dev->dev, 0x01, 0x0000);
6817 return 0; 6820 return 0;
6818} 6821}
@@ -6821,28 +6824,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
6821{ 6824{
6822 struct sd *sd = (struct sd *) gspca_dev; 6825 struct sd *sd = (struct sd *) gspca_dev;
6823 struct usb_device *dev = gspca_dev->dev; 6826 struct usb_device *dev = gspca_dev->dev;
6824 const struct usb_action *zc3_init;
6825 int mode; 6827 int mode;
6826 static const struct usb_action *init_tb[SENSOR_MAX][2] = { 6828 static const struct usb_action *init_tb[SENSOR_MAX][2] = {
6827 {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */ 6829 {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */
6828 {cs2102_InitialScale, cs2102_Initial}, /* 1 */ 6830 {cs2102_Initial, cs2102_InitialScale}, /* 1 */
6829 {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */ 6831 {cs2102K_Initial, cs2102K_InitialScale}, /* 2 */
6830 {gc0305_Initial, gc0305_InitialScale}, /* 3 */ 6832 {gc0305_Initial, gc0305_InitialScale}, /* 3 */
6831 {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ 6833 {hdcs2020b_Initial, hdcs2020b_InitialScale}, /* 4 */
6832 {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ 6834 {hv7131b_Initial, hv7131b_InitialScale}, /* 5 */
6833 {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ 6835 {hv7131r_Initial, hv7131r_InitialScale}, /* 6 */
6834 {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ 6836 {icm105a_Initial, icm105a_InitialScale}, /* 7 */
6835 {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */ 6837 {mc501cb_Initial, mc501cb_InitialScale}, /* 8 */
6836 {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */ 6838 {mi0360soc_Initial, mi0360soc_InitialScale}, /* 9 */
6837 {OV7620_mode0, OV7620_mode1}, /* 10 */ 6839 {ov7620_Initial, ov7620_InitialScale}, /* 10 */
6838 {ov7630c_InitialScale, ov7630c_Initial}, /* 11 */ 6840 {ov7630c_Initial, ov7630c_InitialScale}, /* 11 */
6839 {pas106b_InitialScale, pas106b_Initial}, /* 12 */ 6841 {pas106b_Initial, pas106b_InitialScale}, /* 12 */
6840 {pas202b_Initial, pas202b_InitialScale}, /* 13 */ 6842 {pas202b_Initial, pas202b_InitialScale}, /* 13 */
6841 {pb0330_Initial, pb0330_InitialScale}, /* 14 */ 6843 {pb0330_Initial, pb0330_InitialScale}, /* 14 */
6842 {PO2030_mode0, PO2030_mode1}, /* 15 */ 6844 {po2030_Initial, po2030_InitialScale}, /* 15 */
6843 {tas5130CK_InitialScale, tas5130CK_Initial}, /* 16 */ 6845 {tas5130cK_Initial, tas5130cK_InitialScale}, /* 16 */
6844 {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */ 6846 {tas5130cxx_Initial, tas5130cxx_InitialScale}, /* 17 */
6845 {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, 6847 {tas5130c_vf0250_Initial, tas5130c_vf0250_InitialScale},
6846 /* 18 */ 6848 /* 18 */
6847 }; 6849 };
6848 6850
@@ -6854,8 +6856,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6854 0x21); /* JPEG 422 */ 6856 0x21); /* JPEG 422 */
6855 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 6857 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6856 6858
6857 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 6859 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6858 zc3_init = init_tb[(int) sd->sensor][mode];
6859 switch (sd->sensor) { 6860 switch (sd->sensor) {
6860 case SENSOR_HV7131C: 6861 case SENSOR_HV7131C:
6861 zcxx_probeSensor(gspca_dev); 6862 zcxx_probeSensor(gspca_dev);
@@ -6864,7 +6865,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6864 usb_exchange(gspca_dev, pas106b_Initial_com); 6865 usb_exchange(gspca_dev, pas106b_Initial_com);
6865 break; 6866 break;
6866 } 6867 }
6867 usb_exchange(gspca_dev, zc3_init); 6868 usb_exchange(gspca_dev, init_tb[sd->sensor][mode]);
6868 6869
6869 switch (sd->sensor) { 6870 switch (sd->sensor) {
6870 case SENSOR_ADCM2700: 6871 case SENSOR_ADCM2700:
@@ -6883,6 +6884,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
6883 reg_w(dev, 0x02, 0x003b); 6884 reg_w(dev, 0x02, 0x003b);
6884 reg_w(dev, 0x00, 0x0038); 6885 reg_w(dev, 0x00, 0x0038);
6885 break; 6886 break;
6887 case SENSOR_PAS202B:
6888 reg_w(dev, 0x03, 0x003b);
6889 reg_w(dev, 0x0c, 0x003a);
6890 reg_w(dev, 0x0b, 0x0039);
6891 break;
6886 } 6892 }
6887 6893
6888 setmatrix(gspca_dev); 6894 setmatrix(gspca_dev);
@@ -6961,13 +6967,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
6961 switch (sd->sensor) { 6967 switch (sd->sensor) {
6962 case SENSOR_PO2030: 6968 case SENSOR_PO2030:
6963 msleep(50); 6969 msleep(50);
6964 reg_r(gspca_dev, 0x0008);
6965 reg_r(gspca_dev, 0x0007);
6966 /*fall thru*/
6967 case SENSOR_PAS202B:
6968 reg_w(dev, 0x00, 0x0007); /* (from win traces) */ 6970 reg_w(dev, 0x00, 0x0007); /* (from win traces) */
6969 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING); 6971 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
6970 break; 6972 break;
6973 case SENSOR_PAS202B:
6974 reg_w(dev, 0x32, 0x0007); /* (from win traces) */
6975 reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
6976 break;
6971 } 6977 }
6972 return 0; 6978 return 0;
6973} 6979}
@@ -7165,6 +7171,22 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
7165 return 0; 7171 return 0;
7166} 7172}
7167 7173
7174#ifdef CONFIG_INPUT
7175static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
7176 u8 *data, /* interrupt packet data */
7177 int len) /* interrput packet length */
7178{
7179 if (len == 8 && data[4] == 1) {
7180 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
7181 input_sync(gspca_dev->input_dev);
7182 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
7183 input_sync(gspca_dev->input_dev);
7184 }
7185
7186 return 0;
7187}
7188#endif
7189
7168static const struct sd_desc sd_desc = { 7190static const struct sd_desc sd_desc = {
7169 .name = MODULE_NAME, 7191 .name = MODULE_NAME,
7170 .ctrls = sd_ctrls, 7192 .ctrls = sd_ctrls,
@@ -7177,6 +7199,9 @@ static const struct sd_desc sd_desc = {
7177 .querymenu = sd_querymenu, 7199 .querymenu = sd_querymenu,
7178 .get_jcomp = sd_get_jcomp, 7200 .get_jcomp = sd_get_jcomp,
7179 .set_jcomp = sd_set_jcomp, 7201 .set_jcomp = sd_set_jcomp,
7202#ifdef CONFIG_INPUT
7203 .int_pkt_scan = sd_int_pkt_scan,
7204#endif
7180}; 7205};
7181 7206
7182static const __devinitdata struct usb_device_id device_table[] = { 7207static const __devinitdata struct usb_device_id device_table[] = {
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 51f393d03a46..2fc9865fd486 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -39,12 +39,12 @@ int hdpvr_debug;
39module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR); 39module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
40MODULE_PARM_DESC(hdpvr_debug, "enable debugging output"); 40MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
41 41
42uint default_video_input = HDPVR_VIDEO_INPUTS; 42static uint default_video_input = HDPVR_VIDEO_INPUTS;
43module_param(default_video_input, uint, S_IRUGO|S_IWUSR); 43module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
44MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / " 44MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
45 "1=S-Video / 2=Composite"); 45 "1=S-Video / 2=Composite");
46 46
47uint default_audio_input = HDPVR_AUDIO_INPUTS; 47static uint default_audio_input = HDPVR_AUDIO_INPUTS;
48module_param(default_audio_input, uint, S_IRUGO|S_IWUSR); 48module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
49MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / " 49MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
50 "1=RCA front / 2=S/PDIF"); 50 "1=RCA front / 2=S/PDIF");
@@ -59,6 +59,7 @@ static struct usb_device_id hdpvr_table[] = {
59 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) }, 59 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
60 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, 60 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
61 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, 61 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
62 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID3) },
62 { } /* Terminating entry */ 63 { } /* Terminating entry */
63}; 64};
64MODULE_DEVICE_TABLE(usb, hdpvr_table); 65MODULE_DEVICE_TABLE(usb, hdpvr_table);
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index fdd782039e9d..196f82de48f0 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -302,7 +302,8 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
302/* function expects dev->io_mutex to be hold by caller */ 302/* function expects dev->io_mutex to be hold by caller */
303static int hdpvr_stop_streaming(struct hdpvr_device *dev) 303static int hdpvr_stop_streaming(struct hdpvr_device *dev)
304{ 304{
305 uint actual_length, c = 0; 305 int actual_length;
306 uint c = 0;
306 u8 *buf; 307 u8 *buf;
307 308
308 if (dev->status == STATUS_IDLE) 309 if (dev->status == STATUS_IDLE)
@@ -572,7 +573,7 @@ static int vidioc_querycap(struct file *file, void *priv,
572 struct hdpvr_device *dev = video_drvdata(file); 573 struct hdpvr_device *dev = video_drvdata(file);
573 574
574 strcpy(cap->driver, "hdpvr"); 575 strcpy(cap->driver, "hdpvr");
575 strcpy(cap->card, "Haupauge HD PVR"); 576 strcpy(cap->card, "Hauppauge HD PVR");
576 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); 577 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
577 cap->version = HDPVR_VERSION; 578 cap->version = HDPVR_VERSION;
578 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 579 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index 1edd8759121e..49ae25d83d10 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -30,6 +30,7 @@
30#define HD_PVR_PRODUCT_ID 0x4900 30#define HD_PVR_PRODUCT_ID 0x4900
31#define HD_PVR_PRODUCT_ID1 0x4901 31#define HD_PVR_PRODUCT_ID1 0x4901
32#define HD_PVR_PRODUCT_ID2 0x4902 32#define HD_PVR_PRODUCT_ID2 0x4902
33#define HD_PVR_PRODUCT_ID3 0x4982
33 34
34#define UNSET (-1U) 35#define UNSET (-1U)
35 36
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 60d992ee2589..e620a3a92f25 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -352,9 +352,13 @@ static struct saa7146_ext_vv vv_data;
352static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) 352static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
353{ 353{
354 struct hexium *hexium = (struct hexium *) dev->ext_priv; 354 struct hexium *hexium = (struct hexium *) dev->ext_priv;
355 int ret;
355 356
356 DEB_EE((".\n")); 357 DEB_EE((".\n"));
357 358
359 ret = saa7146_vv_devinit(dev);
360 if (ret)
361 return ret;
358 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL); 362 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
359 if (NULL == hexium) { 363 if (NULL == hexium) {
360 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n"); 364 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
@@ -400,9 +404,10 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
400 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 404 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
401 vv_data.ops.vidioc_g_input = vidioc_g_input; 405 vv_data.ops.vidioc_g_input = vidioc_g_input;
402 vv_data.ops.vidioc_s_input = vidioc_s_input; 406 vv_data.ops.vidioc_s_input = vidioc_s_input;
403 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) { 407 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
408 if (ret < 0) {
404 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n"); 409 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
405 return -1; 410 return ret;
406 } 411 }
407 412
408 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num); 413 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 938a1f8f880a..fe596a1c12a8 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -216,6 +216,10 @@ static int hexium_probe(struct saa7146_dev *dev)
216 return -EFAULT; 216 return -EFAULT;
217 } 217 }
218 218
219 err = saa7146_vv_devinit(dev);
220 if (err)
221 return err;
222
219 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL); 223 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
220 if (NULL == hexium) { 224 if (NULL == hexium) {
221 printk("hexium_orion: hexium_probe: not enough kernel memory.\n"); 225 printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index b86e35386cee..da18d698e7f2 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -299,7 +299,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
299{ 299{
300 struct ir_scancode_table *ir_codes = NULL; 300 struct ir_scancode_table *ir_codes = NULL;
301 const char *name = NULL; 301 const char *name = NULL;
302 int ir_type = 0; 302 u64 ir_type = 0;
303 struct IR_i2c *ir; 303 struct IR_i2c *ir;
304 struct input_dev *input_dev; 304 struct input_dev *input_dev;
305 struct i2c_adapter *adap = client->adapter; 305 struct i2c_adapter *adap = client->adapter;
@@ -331,6 +331,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
331 ir_codes = &ir_codes_pv951_table; 331 ir_codes = &ir_codes_pv951_table;
332 break; 332 break;
333 case 0x18: 333 case 0x18:
334 case 0x1f:
334 case 0x1a: 335 case 0x1a:
335 name = "Hauppauge"; 336 name = "Hauppauge";
336 ir->get_key = get_key_haup; 337 ir->get_key = get_key_haup;
@@ -446,7 +447,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
446 input_dev->name = ir->name; 447 input_dev->name = ir->name;
447 input_dev->phys = ir->phys; 448 input_dev->phys = ir->phys;
448 449
449 err = ir_input_register(ir->input, ir->ir_codes); 450 err = ir_input_register(ir->input, ir->ir_codes, NULL);
450 if (err) 451 if (err)
451 goto err_out_free; 452 goto err_out_free;
452 453
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 79d0fe4990d6..ca1fd3227a93 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -1210,6 +1210,53 @@ static const struct ivtv_card ivtv_card_buffalo = {
1210 .i2c = &ivtv_i2c_std, 1210 .i2c = &ivtv_i2c_std,
1211}; 1211};
1212 1212
1213/* ------------------------------------------------------------------------- */
1214/* Sony Kikyou */
1215
1216static const struct ivtv_card_pci_info ivtv_pci_kikyou[] = {
1217 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_SONY, 0x813d },
1218 { 0, 0, 0 }
1219};
1220
1221static const struct ivtv_card ivtv_card_kikyou = {
1222 .type = IVTV_CARD_KIKYOU,
1223 .name = "Sony VAIO Giga Pocket (ENX Kikyou)",
1224 .v4l2_capabilities = IVTV_CAP_ENCODER,
1225 .hw_video = IVTV_HW_SAA7115,
1226 .hw_audio = IVTV_HW_GPIO,
1227 .hw_audio_ctrl = IVTV_HW_GPIO,
1228 .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
1229 .video_inputs = {
1230 { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 },
1231 { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE1 },
1232 { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
1233 },
1234 .audio_inputs = {
1235 { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
1236 { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
1237 { IVTV_CARD_INPUT_LINE_IN2, IVTV_GPIO_LINE_IN },
1238 },
1239 .gpio_init = { .direction = 0x03e1, .initial_value = 0x0320 },
1240 .gpio_audio_input = { .mask = 0x0060,
1241 .tuner = 0x0020,
1242 .linein = 0x0000,
1243 .radio = 0x0060 },
1244 .gpio_audio_mute = { .mask = 0x0000,
1245 .mute = 0x0000 }, /* 0x200? Disable for now. */
1246 .gpio_audio_mode = { .mask = 0x0080,
1247 .mono = 0x0000,
1248 .stereo = 0x0000, /* SAP */
1249 .lang1 = 0x0080,
1250 .lang2 = 0x0000,
1251 .both = 0x0080 },
1252 .tuners = {
1253 { .std = V4L2_STD_ALL, .tuner = TUNER_SONY_BTF_PXN01Z },
1254 },
1255 .pci_list = ivtv_pci_kikyou,
1256 .i2c = &ivtv_i2c_std,
1257};
1258
1259
1213static const struct ivtv_card *ivtv_card_list[] = { 1260static const struct ivtv_card *ivtv_card_list[] = {
1214 &ivtv_card_pvr250, 1261 &ivtv_card_pvr250,
1215 &ivtv_card_pvr350, 1262 &ivtv_card_pvr350,
@@ -1238,6 +1285,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
1238 &ivtv_card_aver_m104, 1285 &ivtv_card_aver_m104,
1239 &ivtv_card_buffalo, 1286 &ivtv_card_buffalo,
1240 &ivtv_card_aver_ultra1500mce, 1287 &ivtv_card_aver_ultra1500mce,
1288 &ivtv_card_kikyou,
1241 1289
1242 /* Variations of standard cards but with the same PCI IDs. 1290 /* Variations of standard cards but with the same PCI IDs.
1243 These cards must come last in this list. */ 1291 These cards must come last in this list. */
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 6148827ec885..78eca992e1fd 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -51,7 +51,8 @@
51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */ 51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
52#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */ 52#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
53#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */ 53#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */
54#define IVTV_CARD_LAST 26 54#define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
55#define IVTV_CARD_LAST 27
55 56
56/* Variants of existing cards but with the same PCI IDs. The driver 57/* Variants of existing cards but with the same PCI IDs. The driver
57 detects these based on other device information. 58 detects these based on other device information.
@@ -86,6 +87,7 @@
86#define IVTV_PCI_ID_MELCO 0x1154 87#define IVTV_PCI_ID_MELCO 0x1154
87#define IVTV_PCI_ID_GOTVIEW1 0xffac 88#define IVTV_PCI_ID_GOTVIEW1 0xffac
88#define IVTV_PCI_ID_GOTVIEW2 0xffad 89#define IVTV_PCI_ID_GOTVIEW2 0xffad
90#define IVTV_PCI_ID_SONY 0x104d
89 91
90/* hardware flags, no gaps allowed */ 92/* hardware flags, no gaps allowed */
91#define IVTV_HW_CX25840 (1 << 0) 93#define IVTV_HW_CX25840 (1 << 0)
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 347c3344f56d..9a250548be4d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -193,6 +193,7 @@ MODULE_PARM_DESC(cardtype,
193 "\t\t\t25 = AverMedia M104 (not yet working)\n" 193 "\t\t\t25 = AverMedia M104 (not yet working)\n"
194 "\t\t\t26 = Buffalo PC-MV5L/PCI\n" 194 "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
195 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n" 195 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
196 "\t\t\t28 = Sony VAIO Giga Pocket (ENX Kikyou)\n"
196 "\t\t\t 0 = Autodetect (default)\n" 197 "\t\t\t 0 = Autodetect (default)\n"
197 "\t\t\t-1 = Ignore this card\n\t\t"); 198 "\t\t\t-1 = Ignore this card\n\t\t");
198MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); 199MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index c1b7ec475c27..a71e8ba306b0 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -258,7 +258,7 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
258 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n"); 258 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
259 return; 259 return;
260 } 260 }
261 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data); 261 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
262 mem_offset = itv->dec_mem + data[1]; 262 mem_offset = itv->dec_mem + data[1];
263 263
264 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME, 264 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index cd9db0bf33bf..12d36ca91d53 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -562,7 +562,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
562 u32 data[CX2341X_MBOX_MAX_DATA]; 562 u32 data[CX2341X_MBOX_MAX_DATA];
563 struct ivtv_stream *s; 563 struct ivtv_stream *s;
564 564
565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); 565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); 566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
567 567
568 del_timer(&itv->dma_timer); 568 del_timer(&itv->dma_timer);
@@ -638,7 +638,7 @@ static void ivtv_irq_dma_err(struct ivtv *itv)
638 u32 data[CX2341X_MBOX_MAX_DATA]; 638 u32 data[CX2341X_MBOX_MAX_DATA];
639 639
640 del_timer(&itv->dma_timer); 640 del_timer(&itv->dma_timer);
641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); 641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], 642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); 643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); 644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
@@ -669,7 +669,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
669 struct ivtv_stream *s; 669 struct ivtv_stream *s;
670 670
671 /* Get DMA destination and size arguments from card */ 671 /* Get DMA destination and size arguments from card */
672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); 672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); 673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
674 674
675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) { 675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
@@ -713,9 +713,9 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
713 struct ivtv_stream *s; 713 struct ivtv_stream *s;
714 714
715 /* YUV or MPG */ 715 /* YUV or MPG */
716 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
717 716
718 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) { 717 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
718 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
719 itv->dma_data_req_size = 719 itv->dma_data_req_size =
720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
721 itv->dma_data_req_offset = data[1]; 721 itv->dma_data_req_offset = data[1];
@@ -724,6 +724,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; 724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
725 } 725 }
726 else { 726 else {
727 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
727 itv->dma_data_req_size = min_t(u32, data[2], 0x10000); 728 itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
728 itv->dma_data_req_offset = data[1]; 729 itv->dma_data_req_offset = data[1];
729 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; 730 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
@@ -940,9 +941,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
940 ivtv_dma_enc_start(s); 941 ivtv_dma_enc_start(s);
941 break; 942 break;
942 } 943 }
943 if (i == IVTV_MAX_STREAMS && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) { 944
945 if (i == IVTV_MAX_STREAMS &&
946 test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
944 ivtv_udma_start(itv); 947 ivtv_udma_start(itv);
945 }
946 } 948 }
947 949
948 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) { 950 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
index 1b5c0ac09a85..84577f6f41a2 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ b/drivers/media/video/ivtv/ivtv-mailbox.c
@@ -369,10 +369,11 @@ int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
369} 369}
370 370
371/* This one is for stuff that can't sleep.. irq handlers, etc.. */ 371/* This one is for stuff that can't sleep.. irq handlers, etc.. */
372void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[]) 372void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
373 int argc, u32 data[])
373{ 374{
375 volatile u32 __iomem *p = mbdata->mbox[mb].data;
374 int i; 376 int i;
375 377 for (i = 0; i < argc; i++, p++)
376 for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) 378 data[i] = readl(p);
377 data[i] = readl(&mbdata->mbox[mb].data[i]);
378} 379}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
index 6ef12091e3f3..8247662c928e 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ b/drivers/media/video/ivtv/ivtv-mailbox.h
@@ -24,7 +24,8 @@
24#define IVTV_MBOX_DMA_END 8 24#define IVTV_MBOX_DMA_END 8
25#define IVTV_MBOX_DMA 9 25#define IVTV_MBOX_DMA 9
26 26
27void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]); 27void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
28 int argc, u32 data[]);
28int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); 29int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
29int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); 30int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
30int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); 31int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index e12c6022373e..1f9387f6ca24 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -577,10 +577,14 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
577 clear_bit(IVTV_F_I_EOS, &itv->i_flags); 577 clear_bit(IVTV_F_I_EOS, &itv->i_flags);
578 578
579 /* Initialize Digitizer for Capture */ 579 /* Initialize Digitizer for Capture */
580 /* Avoid tinny audio problem - ensure audio clocks are going */
581 v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
582 /* Avoid unpredictable PCI bus hang - disable video clocks */
580 v4l2_subdev_call(itv->sd_video, video, s_stream, 0); 583 v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
581 ivtv_msleep_timeout(300, 1); 584 ivtv_msleep_timeout(150, 1);
582 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); 585 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
583 v4l2_subdev_call(itv->sd_video, video, s_stream, 1); 586 v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
587 ivtv_msleep_timeout(150, 1);
584 } 588 }
585 589
586 /* begin_capture */ 590 /* begin_capture */
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index d07ad6c39024..1daf1dd65bf7 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -213,6 +213,7 @@ void ivtv_udma_start(struct ivtv *itv)
213 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); 213 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
214 set_bit(IVTV_F_I_DMA, &itv->i_flags); 214 set_bit(IVTV_F_I_DMA, &itv->i_flags);
215 set_bit(IVTV_F_I_UDMA, &itv->i_flags); 215 set_bit(IVTV_F_I_UDMA, &itv->i_flags);
216 clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
216} 217}
217 218
218void ivtv_udma_prepare(struct ivtv *itv) 219void ivtv_udma_prepare(struct ivtv *itv)
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 91df7ec91fb6..1a34d2993e94 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -257,19 +257,18 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) 257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
258{ 258{
259 struct soc_camera_link *icl = to_soc_camera_link(icd); 259 struct soc_camera_link *icl = to_soc_camera_link(icd);
260 unsigned int width_flag; 260 unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
261 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
262 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
263 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
264 SOCAM_DATA_ACTIVE_HIGH;
261 265
262 if (icl->query_bus_param) 266 if (icl->query_bus_param)
263 width_flag = icl->query_bus_param(icl) & 267 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
264 SOCAM_DATAWIDTH_MASK;
265 else 268 else
266 width_flag = SOCAM_DATAWIDTH_10; 269 flags |= SOCAM_DATAWIDTH_10;
267 270
268 return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | 271 return soc_camera_apply_sensor_flags(icl, flags);
269 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
270 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
271 SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
272 width_flag;
273} 272}
274 273
275static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 274static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index c1fc6dc776f5..9f01f14e4aa2 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -169,7 +169,11 @@ static struct saa7146_extension extension;
169static int mxb_probe(struct saa7146_dev *dev) 169static int mxb_probe(struct saa7146_dev *dev)
170{ 170{
171 struct mxb *mxb = NULL; 171 struct mxb *mxb = NULL;
172 int err;
172 173
174 err = saa7146_vv_devinit(dev);
175 if (err)
176 return err;
173 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); 177 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
174 if (mxb == NULL) { 178 if (mxb == NULL) {
175 DEB_D(("not enough kernel memory.\n")); 179 DEB_D(("not enough kernel memory.\n"));
@@ -294,7 +298,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
294 /* select tuner-output on saa7111a */ 298 /* select tuner-output on saa7111a */
295 i = 0; 299 i = 0;
296 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0, 300 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
297 SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0); 301 SAA7111_FMT_CCIR, 0);
298 302
299 /* select a tuner type */ 303 /* select a tuner type */
300 tun_setup.mode_mask = T_ANALOG_TV; 304 tun_setup.mode_mask = T_ANALOG_TV;
@@ -518,8 +522,8 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
518 return err; 522 return err;
519 523
520 /* switch video in saa7111a */ 524 /* switch video in saa7111a */
521 if (saa7111a_call(mxb, video, s_routing, i, 0, 0)) 525 if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
522 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n"); 526 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a.\n");
523 527
524 /* switch the audio-source only if necessary */ 528 /* switch the audio-source only if necessary */
525 if (0 == mxb->cur_mute) 529 if (0 == mxb->cur_mute)
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 3a45e945a528..7f8ece30c77b 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -547,7 +547,6 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
547 }, 547 },
548}; 548};
549 549
550
551/* 550/*
552 * general function 551 * general function
553 */ 552 */
@@ -634,7 +633,12 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
634 struct soc_camera_link *icl = to_soc_camera_link(icd); 633 struct soc_camera_link *icl = to_soc_camera_link(icd);
635 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 634 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
636 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 635 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
637 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 636 SOCAM_DATA_ACTIVE_HIGH;
637
638 if (priv->info->flags & OV772X_FLAG_8BIT)
639 flags |= SOCAM_DATAWIDTH_8;
640 else
641 flags |= SOCAM_DATAWIDTH_10;
638 642
639 return soc_camera_apply_sensor_flags(icl, flags); 643 return soc_camera_apply_sensor_flags(icl, flags);
640} 644}
@@ -1040,15 +1044,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1040 return -ENODEV; 1044 return -ENODEV;
1041 1045
1042 /* 1046 /*
1043 * ov772x only use 8 or 10 bit bus width
1044 */
1045 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
1046 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
1047 dev_err(&client->dev, "bus width error\n");
1048 return -ENODEV;
1049 }
1050
1051 /*
1052 * check and show product ID and manufacturer ID 1047 * check and show product ID and manufacturer ID
1053 */ 1048 */
1054 pid = i2c_smbus_read_byte_data(client, PID); 1049 pid = i2c_smbus_read_byte_data(client, PID);
@@ -1130,7 +1125,6 @@ static int ov772x_probe(struct i2c_client *client,
1130 const struct i2c_device_id *did) 1125 const struct i2c_device_id *did)
1131{ 1126{
1132 struct ov772x_priv *priv; 1127 struct ov772x_priv *priv;
1133 struct ov772x_camera_info *info;
1134 struct soc_camera_device *icd = client->dev.platform_data; 1128 struct soc_camera_device *icd = client->dev.platform_data;
1135 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1129 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1136 struct soc_camera_link *icl; 1130 struct soc_camera_link *icl;
@@ -1145,8 +1139,6 @@ static int ov772x_probe(struct i2c_client *client,
1145 if (!icl || !icl->priv) 1139 if (!icl || !icl->priv)
1146 return -EINVAL; 1140 return -EINVAL;
1147 1141
1148 info = icl->priv;
1149
1150 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1142 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1151 dev_err(&adapter->dev, 1143 dev_err(&adapter->dev,
1152 "I2C-Adapter doesn't support " 1144 "I2C-Adapter doesn't support "
@@ -1158,7 +1150,7 @@ static int ov772x_probe(struct i2c_client *client,
1158 if (!priv) 1150 if (!priv)
1159 return -ENOMEM; 1151 return -ENOMEM;
1160 1152
1161 priv->info = info; 1153 priv->info = icl->priv;
1162 1154
1163 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1155 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1164 1156
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index de5485f506b1..cb4057bb07a0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -233,8 +233,9 @@ struct pvr2_hdw {
233 int state_encoder_waitok; /* Encoder pre-wait done */ 233 int state_encoder_waitok; /* Encoder pre-wait done */
234 int state_encoder_runok; /* Encoder has run for >= .25 sec */ 234 int state_encoder_runok; /* Encoder has run for >= .25 sec */
235 int state_decoder_run; /* Decoder is running */ 235 int state_decoder_run; /* Decoder is running */
236 int state_decoder_ready; /* Decoder is stabilized & streamable */
236 int state_usbstream_run; /* FX2 is streaming */ 237 int state_usbstream_run; /* FX2 is streaming */
237 int state_decoder_quiescent; /* Decoder idle for > 50msec */ 238 int state_decoder_quiescent; /* Decoder idle for minimal interval */
238 int state_pipeline_config; /* Pipeline is configured */ 239 int state_pipeline_config; /* Pipeline is configured */
239 int state_pipeline_req; /* Somebody wants to stream */ 240 int state_pipeline_req; /* Somebody wants to stream */
240 int state_pipeline_pause; /* Pipeline must be paused */ 241 int state_pipeline_pause; /* Pipeline must be paused */
@@ -255,9 +256,16 @@ struct pvr2_hdw {
255 void (*state_func)(void *); 256 void (*state_func)(void *);
256 void *state_data; 257 void *state_data;
257 258
258 /* Timer for measuring decoder settling time */ 259 /* Timer for measuring required decoder settling time before we're
260 allowed to fire it up again. */
259 struct timer_list quiescent_timer; 261 struct timer_list quiescent_timer;
260 262
263 /* Timer for measuring decoder stabilization time, which is the
264 amount of time we need to let the decoder run before we can
265 trust its output (otherwise the encoder might see garbage and
266 then fail to start correctly). */
267 struct timer_list decoder_stabilization_timer;
268
261 /* Timer for measuring encoder pre-wait time */ 269 /* Timer for measuring encoder pre-wait time */
262 struct timer_list encoder_wait_timer; 270 struct timer_list encoder_wait_timer;
263 271
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 1bbdab08fe0e..712b300f723f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -48,11 +48,13 @@
48 before we are allowed to start it running. */ 48 before we are allowed to start it running. */
49#define TIME_MSEC_DECODER_WAIT 50 49#define TIME_MSEC_DECODER_WAIT 50
50 50
51/* This defines a minimum interval that the decoder must be allowed to run
52 before we can safely begin using its streaming output. */
53#define TIME_MSEC_DECODER_STABILIZATION_WAIT 300
54
51/* This defines a minimum interval that the encoder must remain quiet 55/* This defines a minimum interval that the encoder must remain quiet
52 before we are allowed to configure it. I had this originally set to 56 before we are allowed to configure it. */
53 50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that 57#define TIME_MSEC_ENCODER_WAIT 50
54 things work better when it's set to 100msec. */
55#define TIME_MSEC_ENCODER_WAIT 100
56 58
57/* This defines the minimum interval that the encoder must successfully run 59/* This defines the minimum interval that the encoder must successfully run
58 before we consider that the encoder has run at least once since its 60 before we consider that the encoder has run at least once since its
@@ -334,6 +336,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
334static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); 336static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
335static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); 337static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
336static void pvr2_hdw_quiescent_timeout(unsigned long); 338static void pvr2_hdw_quiescent_timeout(unsigned long);
339static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
337static void pvr2_hdw_encoder_wait_timeout(unsigned long); 340static void pvr2_hdw_encoder_wait_timeout(unsigned long);
338static void pvr2_hdw_encoder_run_timeout(unsigned long); 341static void pvr2_hdw_encoder_run_timeout(unsigned long);
339static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); 342static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
@@ -1705,6 +1708,7 @@ static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
1705 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s", 1708 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
1706 (enablefl ? "on" : "off")); 1709 (enablefl ? "on" : "off"));
1707 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl); 1710 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
1711 v4l2_device_call_all(&hdw->v4l2_dev, 0, audio, s_stream, enablefl);
1708 if (hdw->decoder_client_id) { 1712 if (hdw->decoder_client_id) {
1709 /* We get here if the encoder has been noticed. Otherwise 1713 /* We get here if the encoder has been noticed. Otherwise
1710 we'll issue a warning to the user (which should 1714 we'll issue a warning to the user (which should
@@ -2461,6 +2465,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2461 hdw->quiescent_timer.data = (unsigned long)hdw; 2465 hdw->quiescent_timer.data = (unsigned long)hdw;
2462 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout; 2466 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
2463 2467
2468 init_timer(&hdw->decoder_stabilization_timer);
2469 hdw->decoder_stabilization_timer.data = (unsigned long)hdw;
2470 hdw->decoder_stabilization_timer.function =
2471 pvr2_hdw_decoder_stabilization_timeout;
2472
2464 init_timer(&hdw->encoder_wait_timer); 2473 init_timer(&hdw->encoder_wait_timer);
2465 hdw->encoder_wait_timer.data = (unsigned long)hdw; 2474 hdw->encoder_wait_timer.data = (unsigned long)hdw;
2466 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; 2475 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
@@ -2674,6 +2683,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2674 fail: 2683 fail:
2675 if (hdw) { 2684 if (hdw) {
2676 del_timer_sync(&hdw->quiescent_timer); 2685 del_timer_sync(&hdw->quiescent_timer);
2686 del_timer_sync(&hdw->decoder_stabilization_timer);
2677 del_timer_sync(&hdw->encoder_run_timer); 2687 del_timer_sync(&hdw->encoder_run_timer);
2678 del_timer_sync(&hdw->encoder_wait_timer); 2688 del_timer_sync(&hdw->encoder_wait_timer);
2679 if (hdw->workqueue) { 2689 if (hdw->workqueue) {
@@ -2741,6 +2751,7 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2741 hdw->workqueue = NULL; 2751 hdw->workqueue = NULL;
2742 } 2752 }
2743 del_timer_sync(&hdw->quiescent_timer); 2753 del_timer_sync(&hdw->quiescent_timer);
2754 del_timer_sync(&hdw->decoder_stabilization_timer);
2744 del_timer_sync(&hdw->encoder_run_timer); 2755 del_timer_sync(&hdw->encoder_run_timer);
2745 del_timer_sync(&hdw->encoder_wait_timer); 2756 del_timer_sync(&hdw->encoder_wait_timer);
2746 if (hdw->fw_buffer) { 2757 if (hdw->fw_buffer) {
@@ -4452,7 +4463,7 @@ static int state_check_enable_encoder_run(struct pvr2_hdw *hdw)
4452 4463
4453 switch (hdw->pathway_state) { 4464 switch (hdw->pathway_state) {
4454 case PVR2_PATHWAY_ANALOG: 4465 case PVR2_PATHWAY_ANALOG:
4455 if (hdw->state_decoder_run) { 4466 if (hdw->state_decoder_run && hdw->state_decoder_ready) {
4456 /* In analog mode, if the decoder is running, then 4467 /* In analog mode, if the decoder is running, then
4457 run the encoder. */ 4468 run the encoder. */
4458 return !0; 4469 return !0;
@@ -4519,6 +4530,17 @@ static void pvr2_hdw_quiescent_timeout(unsigned long data)
4519} 4530}
4520 4531
4521 4532
4533/* Timeout function for decoder stabilization timer. */
4534static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
4535{
4536 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
4537 hdw->state_decoder_ready = !0;
4538 trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
4539 hdw->state_stale = !0;
4540 queue_work(hdw->workqueue, &hdw->workpoll);
4541}
4542
4543
4522/* Timeout function for encoder wait timer. */ 4544/* Timeout function for encoder wait timer. */
4523static void pvr2_hdw_encoder_wait_timeout(unsigned long data) 4545static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
4524{ 4546{
@@ -4557,8 +4579,13 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
4557 } 4579 }
4558 hdw->state_decoder_quiescent = 0; 4580 hdw->state_decoder_quiescent = 0;
4559 hdw->state_decoder_run = 0; 4581 hdw->state_decoder_run = 0;
4560 /* paranoia - solve race if timer just completed */ 4582 /* paranoia - solve race if timer(s) just completed */
4561 del_timer_sync(&hdw->quiescent_timer); 4583 del_timer_sync(&hdw->quiescent_timer);
4584 /* Kill the stabilization timer, in case we're killing the
4585 encoder before the previous stabilization interval has
4586 been properly timed. */
4587 del_timer_sync(&hdw->decoder_stabilization_timer);
4588 hdw->state_decoder_ready = 0;
4562 } else { 4589 } else {
4563 if (!hdw->state_decoder_quiescent) { 4590 if (!hdw->state_decoder_quiescent) {
4564 if (!timer_pending(&hdw->quiescent_timer)) { 4591 if (!timer_pending(&hdw->quiescent_timer)) {
@@ -4596,10 +4623,21 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
4596 if (hdw->flag_decoder_missed) return 0; 4623 if (hdw->flag_decoder_missed) return 0;
4597 if (pvr2_decoder_enable(hdw,!0) < 0) return 0; 4624 if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
4598 hdw->state_decoder_quiescent = 0; 4625 hdw->state_decoder_quiescent = 0;
4626 hdw->state_decoder_ready = 0;
4599 hdw->state_decoder_run = !0; 4627 hdw->state_decoder_run = !0;
4628 if (hdw->decoder_client_id == PVR2_CLIENT_ID_SAA7115) {
4629 hdw->decoder_stabilization_timer.expires =
4630 jiffies +
4631 (HZ * TIME_MSEC_DECODER_STABILIZATION_WAIT /
4632 1000);
4633 add_timer(&hdw->decoder_stabilization_timer);
4634 } else {
4635 hdw->state_decoder_ready = !0;
4636 }
4600 } 4637 }
4601 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); 4638 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
4602 trace_stbit("state_decoder_run",hdw->state_decoder_run); 4639 trace_stbit("state_decoder_run",hdw->state_decoder_run);
4640 trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
4603 return !0; 4641 return !0;
4604} 4642}
4605 4643
@@ -4797,7 +4835,8 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
4797 buf,acnt, 4835 buf,acnt,
4798 "worker:%s%s%s%s%s%s%s", 4836 "worker:%s%s%s%s%s%s%s",
4799 (hdw->state_decoder_run ? 4837 (hdw->state_decoder_run ?
4800 " <decode:run>" : 4838 (hdw->state_decoder_ready ?
4839 "<decode:run>" : " <decode:start>") :
4801 (hdw->state_decoder_quiescent ? 4840 (hdw->state_decoder_quiescent ?
4802 "" : " <decode:stop>")), 4841 "" : " <decode:stop>")),
4803 (hdw->state_decoder_quiescent ? 4842 (hdw->state_decoder_quiescent ?
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 56e70eae20c1..51d3009ab57f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -306,6 +306,7 @@ struct pvr2_hdw_debug_info {
306 int state_encoder_ok; 306 int state_encoder_ok;
307 int state_encoder_run; 307 int state_encoder_run;
308 int state_decoder_run; 308 int state_decoder_run;
309 int state_decoder_ready;
309 int state_usbstream_run; 310 int state_usbstream_run;
310 int state_decoder_quiescent; 311 int state_decoder_quiescent;
311 int state_pipeline_config; 312 int state_pipeline_config;
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 294f860ce2b0..322ac4eecf0a 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -898,18 +898,8 @@ static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
898 898
899static void pxa_camera_activate(struct pxa_camera_dev *pcdev) 899static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
900{ 900{
901 struct pxacamera_platform_data *pdata = pcdev->pdata;
902 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
903 u32 cicr4 = 0; 901 u32 cicr4 = 0;
904 902
905 dev_dbg(dev, "Registered platform device at %p data %p\n",
906 pcdev, pdata);
907
908 if (pdata && pdata->init) {
909 dev_dbg(dev, "%s: Init gpios\n", __func__);
910 pdata->init(dev);
911 }
912
913 /* disable all interrupts */ 903 /* disable all interrupts */
914 __raw_writel(0x3ff, pcdev->base + CICR0); 904 __raw_writel(0x3ff, pcdev->base + CICR0);
915 905
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index 805226e0d9c1..9277194cd821 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -165,7 +165,7 @@ struct rj54n1_reg_val {
165 u8 val; 165 u8 val;
166}; 166};
167 167
168const static struct rj54n1_reg_val bank_4[] = { 168static const struct rj54n1_reg_val bank_4[] = {
169 {0x417, 0}, 169 {0x417, 0},
170 {0x42c, 0}, 170 {0x42c, 0},
171 {0x42d, 0xf0}, 171 {0x42d, 0xf0},
@@ -186,7 +186,7 @@ const static struct rj54n1_reg_val bank_4[] = {
186 {0x4fe, 2}, 186 {0x4fe, 2},
187}; 187};
188 188
189const static struct rj54n1_reg_val bank_5[] = { 189static const struct rj54n1_reg_val bank_5[] = {
190 {0x514, 0}, 190 {0x514, 0},
191 {0x516, 0}, 191 {0x516, 0},
192 {0x518, 0}, 192 {0x518, 0},
@@ -207,7 +207,7 @@ const static struct rj54n1_reg_val bank_5[] = {
207 {0x5fe, 2}, 207 {0x5fe, 2},
208}; 208};
209 209
210const static struct rj54n1_reg_val bank_7[] = { 210static const struct rj54n1_reg_val bank_7[] = {
211 {0x70a, 0}, 211 {0x70a, 0},
212 {0x714, 0xff}, 212 {0x714, 0xff},
213 {0x715, 0xff}, 213 {0x715, 0xff},
@@ -215,7 +215,7 @@ const static struct rj54n1_reg_val bank_7[] = {
215 {0x7FE, 2}, 215 {0x7FE, 2},
216}; 216};
217 217
218const static struct rj54n1_reg_val bank_8[] = { 218static const struct rj54n1_reg_val bank_8[] = {
219 {0x800, 0x00}, 219 {0x800, 0x00},
220 {0x801, 0x01}, 220 {0x801, 0x01},
221 {0x802, 0x61}, 221 {0x802, 0x61},
@@ -403,12 +403,12 @@ const static struct rj54n1_reg_val bank_8[] = {
403 {0x8FE, 2}, 403 {0x8FE, 2},
404}; 404};
405 405
406const static struct rj54n1_reg_val bank_10[] = { 406static const struct rj54n1_reg_val bank_10[] = {
407 {0x10bf, 0x69} 407 {0x10bf, 0x69}
408}; 408};
409 409
410/* Clock dividers - these are default register values, divider = register + 1 */ 410/* Clock dividers - these are default register values, divider = register + 1 */
411const static struct rj54n1_clock_div clk_div = { 411static const struct rj54n1_clock_div clk_div = {
412 .ratio_tg = 3 /* default: 5 */, 412 .ratio_tg = 3 /* default: 5 */,
413 .ratio_t = 4 /* default: 1 */, 413 .ratio_t = 4 /* default: 1 */,
414 .ratio_r = 4 /* default: 0 */, 414 .ratio_r = 4 /* default: 0 */,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 44873a016c2c..c0a7f8a369f4 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -104,6 +104,10 @@ static int saa711x_has_reg(const int id, const u8 reg)
104 if (id == V4L2_IDENT_SAA7111) 104 if (id == V4L2_IDENT_SAA7111)
105 return reg < 0x20 && reg != 0x01 && reg != 0x0f && 105 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
106 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e; 106 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
107 if (id == V4L2_IDENT_SAA7111A)
108 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
109 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
110 reg != 0x1d && reg != 0x1e;
107 111
108 /* common for saa7113/4/5/8 */ 112 /* common for saa7113/4/5/8 */
109 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f || 113 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
@@ -954,8 +958,7 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
954 011 NTSC N (3.58MHz) PAL M (3.58MHz) 958 011 NTSC N (3.58MHz) PAL M (3.58MHz)
955 100 reserved NTSC-Japan (3.58MHz) 959 100 reserved NTSC-Japan (3.58MHz)
956 */ 960 */
957 if (state->ident == V4L2_IDENT_SAA7111 || 961 if (state->ident <= V4L2_IDENT_SAA7113) {
958 state->ident == V4L2_IDENT_SAA7113) {
959 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f; 962 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
960 963
961 if (std == V4L2_STD_PAL_M) { 964 if (std == V4L2_STD_PAL_M) {
@@ -1232,22 +1235,19 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
1232 u32 input, u32 output, u32 config) 1235 u32 input, u32 output, u32 config)
1233{ 1236{
1234 struct saa711x_state *state = to_state(sd); 1237 struct saa711x_state *state = to_state(sd);
1235 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0; 1238 u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
1236 1239
1237 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", 1240 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
1238 input, output); 1241 input, output);
1239 1242
1240 /* saa7111/3 does not have these inputs */ 1243 /* saa7111/3 does not have these inputs */
1241 if ((state->ident == V4L2_IDENT_SAA7113 || 1244 if (state->ident <= V4L2_IDENT_SAA7113 &&
1242 state->ident == V4L2_IDENT_SAA7111) &&
1243 (input == SAA7115_COMPOSITE4 || 1245 (input == SAA7115_COMPOSITE4 ||
1244 input == SAA7115_COMPOSITE5)) { 1246 input == SAA7115_COMPOSITE5)) {
1245 return -EINVAL; 1247 return -EINVAL;
1246 } 1248 }
1247 if (input > SAA7115_SVIDEO3) 1249 if (input > SAA7115_SVIDEO3)
1248 return -EINVAL; 1250 return -EINVAL;
1249 if (output > SAA7115_IPORT_ON)
1250 return -EINVAL;
1251 if (state->input == input && state->output == output) 1251 if (state->input == input && state->output == output)
1252 return 0; 1252 return 0;
1253 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n", 1253 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
@@ -1256,7 +1256,7 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
1256 state->input = input; 1256 state->input = input;
1257 1257
1258 /* saa7111 has slightly different input numbering */ 1258 /* saa7111 has slightly different input numbering */
1259 if (state->ident == V4L2_IDENT_SAA7111) { 1259 if (state->ident <= V4L2_IDENT_SAA7111A) {
1260 if (input >= SAA7115_COMPOSITE4) 1260 if (input >= SAA7115_COMPOSITE4)
1261 input -= 2; 1261 input -= 2;
1262 /* saa7111 specific */ 1262 /* saa7111 specific */
@@ -1292,7 +1292,7 @@ static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1292{ 1292{
1293 struct saa711x_state *state = to_state(sd); 1293 struct saa711x_state *state = to_state(sd);
1294 1294
1295 if (state->ident != V4L2_IDENT_SAA7111) 1295 if (state->ident > V4L2_IDENT_SAA7111A)
1296 return -EINVAL; 1296 return -EINVAL;
1297 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) | 1297 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1298 (val ? 0x80 : 0)); 1298 (val ? 0x80 : 0));
@@ -1596,6 +1596,10 @@ static int saa711x_probe(struct i2c_client *client,
1596 switch (chip_id) { 1596 switch (chip_id) {
1597 case '1': 1597 case '1':
1598 state->ident = V4L2_IDENT_SAA7111; 1598 state->ident = V4L2_IDENT_SAA7111;
1599 if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
1600 v4l_info(client, "saa7111a variant found\n");
1601 state->ident = V4L2_IDENT_SAA7111A;
1602 }
1599 break; 1603 break;
1600 case '3': 1604 case '3':
1601 state->ident = V4L2_IDENT_SAA7113; 1605 state->ident = V4L2_IDENT_SAA7113;
@@ -1612,7 +1616,7 @@ static int saa711x_probe(struct i2c_client *client,
1612 default: 1616 default:
1613 state->ident = V4L2_IDENT_SAA7111; 1617 state->ident = V4L2_IDENT_SAA7111;
1614 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n"); 1618 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
1615 1619 break;
1616 } 1620 }
1617 1621
1618 state->audclk_freq = 48000; 1622 state->audclk_freq = 48000;
@@ -1623,6 +1627,7 @@ static int saa711x_probe(struct i2c_client *client,
1623 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1627 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1624 switch (state->ident) { 1628 switch (state->ident) {
1625 case V4L2_IDENT_SAA7111: 1629 case V4L2_IDENT_SAA7111:
1630 case V4L2_IDENT_SAA7111A:
1626 saa711x_writeregs(sd, saa7111_init); 1631 saa711x_writeregs(sd, saa7111_init);
1627 break; 1632 break;
1628 case V4L2_IDENT_SAA7113: 1633 case V4L2_IDENT_SAA7113:
@@ -1632,7 +1637,7 @@ static int saa711x_probe(struct i2c_client *client,
1632 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; 1637 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1633 saa711x_writeregs(sd, saa7115_init_auto_input); 1638 saa711x_writeregs(sd, saa7115_init_auto_input);
1634 } 1639 }
1635 if (state->ident != V4L2_IDENT_SAA7111) 1640 if (state->ident > V4L2_IDENT_SAA7111A)
1636 saa711x_writeregs(sd, saa7115_init_misc); 1641 saa711x_writeregs(sd, saa7115_init_misc);
1637 saa711x_set_v4lstd(sd, V4L2_STD_NTSC); 1642 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1638 1643
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 2fe7a701b954..250ef84cf5ca 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -181,7 +181,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
181#define SAA7127_60HZ_DAC_CONTROL 0x15 181#define SAA7127_60HZ_DAC_CONTROL 0x15
182static const struct i2c_reg_value saa7127_init_config_60hz[] = { 182static const struct i2c_reg_value saa7127_init_config_60hz[] = {
183 { SAA7127_REG_BURST_START, 0x19 }, 183 { SAA7127_REG_BURST_START, 0x19 },
184 /* BURST_END is also used as a chip ID in saa7127_detect_client */ 184 /* BURST_END is also used as a chip ID in saa7127_probe */
185 { SAA7127_REG_BURST_END, 0x1d }, 185 { SAA7127_REG_BURST_END, 0x1d },
186 { SAA7127_REG_CHROMA_PHASE, 0xa3 }, 186 { SAA7127_REG_CHROMA_PHASE, 0xa3 },
187 { SAA7127_REG_GAINU, 0x98 }, 187 { SAA7127_REG_GAINU, 0x98 },
@@ -200,10 +200,10 @@ static const struct i2c_reg_value saa7127_init_config_60hz[] = {
200 { 0, 0 } 200 { 0, 0 }
201}; 201};
202 202
203#define SAA7127_50HZ_DAC_CONTROL 0x02 203#define SAA7127_50HZ_PAL_DAC_CONTROL 0x02
204static struct i2c_reg_value saa7127_init_config_50hz[] = { 204static struct i2c_reg_value saa7127_init_config_50hz_pal[] = {
205 { SAA7127_REG_BURST_START, 0x21 }, 205 { SAA7127_REG_BURST_START, 0x21 },
206 /* BURST_END is also used as a chip ID in saa7127_detect_client */ 206 /* BURST_END is also used as a chip ID in saa7127_probe */
207 { SAA7127_REG_BURST_END, 0x1d }, 207 { SAA7127_REG_BURST_END, 0x1d },
208 { SAA7127_REG_CHROMA_PHASE, 0x3f }, 208 { SAA7127_REG_CHROMA_PHASE, 0x3f },
209 { SAA7127_REG_GAINU, 0x7d }, 209 { SAA7127_REG_GAINU, 0x7d },
@@ -222,6 +222,28 @@ static struct i2c_reg_value saa7127_init_config_50hz[] = {
222 { 0, 0 } 222 { 0, 0 }
223}; 223};
224 224
225#define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08
226static struct i2c_reg_value saa7127_init_config_50hz_secam[] = {
227 { SAA7127_REG_BURST_START, 0x21 },
228 /* BURST_END is also used as a chip ID in saa7127_probe */
229 { SAA7127_REG_BURST_END, 0x1d },
230 { SAA7127_REG_CHROMA_PHASE, 0x3f },
231 { SAA7127_REG_GAINU, 0x6a },
232 { SAA7127_REG_GAINV, 0x81 },
233 { SAA7127_REG_BLACK_LEVEL, 0x33 },
234 { SAA7127_REG_BLANKING_LEVEL, 0x35 },
235 { SAA7127_REG_VBI_BLANKING, 0x35 },
236 { SAA7127_REG_DAC_CONTROL, 0x08 },
237 { SAA7127_REG_BURST_AMP, 0x2f },
238 { SAA7127_REG_SUBC3, 0xb2 },
239 { SAA7127_REG_SUBC2, 0x3b },
240 { SAA7127_REG_SUBC1, 0xa3 },
241 { SAA7127_REG_SUBC0, 0x28 },
242 { SAA7127_REG_MULTI, 0x90 },
243 { SAA7127_REG_CLOSED_CAPTION, 0x00 },
244 { 0, 0 }
245};
246
225/* 247/*
226 ********************************************************************** 248 **********************************************************************
227 * 249 *
@@ -463,10 +485,21 @@ static int saa7127_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
463 v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n"); 485 v4l2_dbg(1, debug, sd, "Selecting 60 Hz video Standard\n");
464 inittab = saa7127_init_config_60hz; 486 inittab = saa7127_init_config_60hz;
465 state->reg_61 = SAA7127_60HZ_DAC_CONTROL; 487 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
488
489 } else if (state->ident == V4L2_IDENT_SAA7129 &&
490 (std & V4L2_STD_SECAM) &&
491 !(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
492
493 /* If and only if SECAM, with a SAA712[89] */
494 v4l2_dbg(1, debug, sd,
495 "Selecting 50 Hz SECAM video Standard\n");
496 inittab = saa7127_init_config_50hz_secam;
497 state->reg_61 = SAA7127_50HZ_SECAM_DAC_CONTROL;
498
466 } else { 499 } else {
467 v4l2_dbg(1, debug, sd, "Selecting 50 Hz video Standard\n"); 500 v4l2_dbg(1, debug, sd, "Selecting 50 Hz PAL video Standard\n");
468 inittab = saa7127_init_config_50hz; 501 inittab = saa7127_init_config_50hz_pal;
469 state->reg_61 = SAA7127_50HZ_DAC_CONTROL; 502 state->reg_61 = SAA7127_50HZ_PAL_DAC_CONTROL;
470 } 503 }
471 504
472 /* Write Table */ 505 /* Write Table */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 03f572708b85..297833fb3b4a 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4160,7 +4160,7 @@ struct saa7134_board saa7134_boards[] = {
4160 .amux = LINE2, 4160 .amux = LINE2,
4161 }, 4161 },
4162 }, 4162 },
4163 [SAA7134_BOARD_BEHOLD_505RDS] = { 4163 [SAA7134_BOARD_BEHOLD_505RDS_MK5] = {
4164 /* Beholder Intl. Ltd. 2008 */ 4164 /* Beholder Intl. Ltd. 2008 */
4165 /*Dmitry Belimov <d.belimov@gmail.com> */ 4165 /*Dmitry Belimov <d.belimov@gmail.com> */
4166 .name = "Beholder BeholdTV 505 RDS", 4166 .name = "Beholder BeholdTV 505 RDS",
@@ -5320,6 +5320,41 @@ struct saa7134_board saa7134_boards[] = {
5320 .vmux = 8, 5320 .vmux = 8,
5321 } }, 5321 } },
5322 }, 5322 },
5323 [SAA7134_BOARD_BEHOLD_505RDS_MK3] = {
5324 /* Beholder Intl. Ltd. 2008 */
5325 /*Dmitry Belimov <d.belimov@gmail.com> */
5326 .name = "Beholder BeholdTV 505 RDS",
5327 .audio_clock = 0x00200000,
5328 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
5329 .radio_type = UNSET,
5330 .tuner_addr = ADDR_UNSET,
5331 .radio_addr = ADDR_UNSET,
5332 .rds_addr = 0x10,
5333 .tda9887_conf = TDA9887_PRESENT,
5334 .gpiomask = 0x00008000,
5335 .inputs = {{
5336 .name = name_tv,
5337 .vmux = 3,
5338 .amux = LINE2,
5339 .tv = 1,
5340 }, {
5341 .name = name_comp1,
5342 .vmux = 1,
5343 .amux = LINE1,
5344 }, {
5345 .name = name_svideo,
5346 .vmux = 8,
5347 .amux = LINE1,
5348 } },
5349 .mute = {
5350 .name = name_mute,
5351 .amux = LINE1,
5352 },
5353 .radio = {
5354 .name = name_radio,
5355 .amux = LINE2,
5356 },
5357 },
5323 5358
5324}; 5359};
5325 5360
@@ -6235,7 +6270,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
6235 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 6270 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6236 .subvendor = 0x0000, 6271 .subvendor = 0x0000,
6237 .subdevice = 0x505B, 6272 .subdevice = 0x505B,
6238 .driver_data = SAA7134_BOARD_BEHOLD_505RDS, 6273 .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK5,
6274 }, {
6275 .vendor = PCI_VENDOR_ID_PHILIPS,
6276 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6277 .subvendor = 0x0000,
6278 .subdevice = 0x5051,
6279 .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK3,
6239 },{ 6280 },{
6240 .vendor = PCI_VENDOR_ID_PHILIPS, 6281 .vendor = PCI_VENDOR_ID_PHILIPS,
6241 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 6282 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -6792,7 +6833,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6792 case SAA7134_BOARD_BEHOLD_407FM: 6833 case SAA7134_BOARD_BEHOLD_407FM:
6793 case SAA7134_BOARD_BEHOLD_409: 6834 case SAA7134_BOARD_BEHOLD_409:
6794 case SAA7134_BOARD_BEHOLD_505FM: 6835 case SAA7134_BOARD_BEHOLD_505FM:
6795 case SAA7134_BOARD_BEHOLD_505RDS: 6836 case SAA7134_BOARD_BEHOLD_505RDS_MK5:
6837 case SAA7134_BOARD_BEHOLD_505RDS_MK3:
6796 case SAA7134_BOARD_BEHOLD_507_9FM: 6838 case SAA7134_BOARD_BEHOLD_507_9FM:
6797 case SAA7134_BOARD_BEHOLD_507RDS_MK3: 6839 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
6798 case SAA7134_BOARD_BEHOLD_507RDS_MK5: 6840 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
@@ -6953,8 +6995,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6953 break; 6995 break;
6954 case SAA7134_BOARD_VIDEOMATE_S350: 6996 case SAA7134_BOARD_VIDEOMATE_S350:
6955 dev->has_remote = SAA7134_REMOTE_GPIO; 6997 dev->has_remote = SAA7134_REMOTE_GPIO;
6956 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00008000, 0x00008000); 6998 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000);
6957 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); 6999 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000);
6958 break; 7000 break;
6959 } 7001 }
6960 return 0; 7002 return 0;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index f8e985989ca0..9499000f66b6 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -460,7 +460,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
460 int polling = 0; 460 int polling = 0;
461 int rc5_gpio = 0; 461 int rc5_gpio = 0;
462 int nec_gpio = 0; 462 int nec_gpio = 0;
463 int ir_type = IR_TYPE_OTHER; 463 u64 ir_type = IR_TYPE_OTHER;
464 int err; 464 int err;
465 465
466 if (dev->has_remote != SAA7134_REMOTE_GPIO) 466 if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -568,7 +568,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
568 case SAA7134_BOARD_BEHOLD_407FM: 568 case SAA7134_BOARD_BEHOLD_407FM:
569 case SAA7134_BOARD_BEHOLD_409: 569 case SAA7134_BOARD_BEHOLD_409:
570 case SAA7134_BOARD_BEHOLD_505FM: 570 case SAA7134_BOARD_BEHOLD_505FM:
571 case SAA7134_BOARD_BEHOLD_505RDS: 571 case SAA7134_BOARD_BEHOLD_505RDS_MK5:
572 case SAA7134_BOARD_BEHOLD_505RDS_MK3:
572 case SAA7134_BOARD_BEHOLD_507_9FM: 573 case SAA7134_BOARD_BEHOLD_507_9FM:
573 case SAA7134_BOARD_BEHOLD_507RDS_MK3: 574 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
574 case SAA7134_BOARD_BEHOLD_507RDS_MK5: 575 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
@@ -728,7 +729,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
728 dev->remote = ir; 729 dev->remote = ir;
729 saa7134_ir_start(dev, ir); 730 saa7134_ir_start(dev, ir);
730 731
731 err = ir_input_register(ir->dev, ir_codes); 732 err = ir_input_register(ir->dev, ir_codes, NULL);
732 if (err) 733 if (err)
733 goto err_out_stop; 734 goto err_out_stop;
734 735
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index cb732640ac4a..31138d3e51bb 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -205,7 +205,7 @@ static struct saa7134_format formats[] = {
205 205
206#define NORM_525_60 \ 206#define NORM_525_60 \
207 .h_start = 0, \ 207 .h_start = 0, \
208 .h_stop = 703, \ 208 .h_stop = 719, \
209 .video_v_start = 23, \ 209 .video_v_start = 23, \
210 .video_v_stop = 262, \ 210 .video_v_stop = 262, \
211 .vbi_v_start_0 = 10, \ 211 .vbi_v_start_0 = 10, \
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 53b7e0b8a2fb..bf130967ed17 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -282,7 +282,7 @@ struct saa7134_format {
282#define SAA7134_BOARD_HAUPPAUGE_HVR1120 156 282#define SAA7134_BOARD_HAUPPAUGE_HVR1120 156
283#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157 283#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
284#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158 284#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
285#define SAA7134_BOARD_BEHOLD_505RDS 159 285#define SAA7134_BOARD_BEHOLD_505RDS_MK5 159
286#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160 286#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160
287#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161 287#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161
288#define SAA7134_BOARD_BEHOLD_607FM_MK5 162 288#define SAA7134_BOARD_BEHOLD_607FM_MK5 162
@@ -299,6 +299,7 @@ struct saa7134_format {
299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173 299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174 300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175 301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
302#define SAA7134_BOARD_BEHOLD_505RDS_MK3 176
302 303
303#define SAA7134_MAXBOARDS 32 304#define SAA7134_MAXBOARDS 32
304#define SAA7134_INPUT_MAX 8 305#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index 6f094a96ac81..1d487c150340 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -523,7 +523,7 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
523 } 523 }
524 524
525 reglen = saa7164_i2caddr_to_reglen(bus, addr); 525 reglen = saa7164_i2caddr_to_reglen(bus, addr);
526 if (unitid < 0) { 526 if (reglen < 0) {
527 printk(KERN_ERR 527 printk(KERN_ERR
528 "%s() error, cannot translate regaddr to reglen\n", 528 "%s() error, cannot translate regaddr to reglen\n",
529 __func__); 529 __func__);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index f09c7140d6b2..fb88c63188f3 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -1748,6 +1748,22 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
1748 icd); 1748 icd);
1749} 1749}
1750 1750
1751static int sh_mobile_ceu_get_parm(struct soc_camera_device *icd,
1752 struct v4l2_streamparm *parm)
1753{
1754 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1755
1756 return v4l2_subdev_call(sd, video, g_parm, parm);
1757}
1758
1759static int sh_mobile_ceu_set_parm(struct soc_camera_device *icd,
1760 struct v4l2_streamparm *parm)
1761{
1762 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1763
1764 return v4l2_subdev_call(sd, video, s_parm, parm);
1765}
1766
1751static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, 1767static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1752 struct v4l2_control *ctrl) 1768 struct v4l2_control *ctrl)
1753{ 1769{
@@ -1808,6 +1824,8 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1808 .try_fmt = sh_mobile_ceu_try_fmt, 1824 .try_fmt = sh_mobile_ceu_try_fmt,
1809 .set_ctrl = sh_mobile_ceu_set_ctrl, 1825 .set_ctrl = sh_mobile_ceu_set_ctrl,
1810 .get_ctrl = sh_mobile_ceu_get_ctrl, 1826 .get_ctrl = sh_mobile_ceu_get_ctrl,
1827 .set_parm = sh_mobile_ceu_set_parm,
1828 .get_parm = sh_mobile_ceu_get_parm,
1811 .reqbufs = sh_mobile_ceu_reqbufs, 1829 .reqbufs = sh_mobile_ceu_reqbufs,
1812 .poll = sh_mobile_ceu_poll, 1830 .poll = sh_mobile_ceu_poll,
1813 .querycap = sh_mobile_ceu_querycap, 1831 .querycap = sh_mobile_ceu_querycap,
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig
index f71f272776de..6ebaf2940d06 100644
--- a/drivers/media/video/sn9c102/Kconfig
+++ b/drivers/media/video/sn9c102/Kconfig
@@ -1,7 +1,10 @@
1config USB_SN9C102 1config USB_SN9C102
2 tristate "USB SN9C1xx PC Camera Controller support" 2 tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 ---help--- 4 ---help---
5 This driver is DEPRECATED please use the gspca sonixb and
6 sonixj modules instead.
7
5 Say Y here if you want support for cameras based on SONiX SN9C101, 8 Say Y here if you want support for cameras based on SONiX SN9C101,
6 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. 9 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
7 10
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 36ee43a9ee95..cc40d6ba9f22 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -45,20 +45,24 @@ static const struct usb_device_id sn9c102_id_table[] = {
45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, 45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
46#endif 46#endif
47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, 47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
48#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
48 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, 49 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
49 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, 50 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
50/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ 51/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
52#endif
51 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, 53 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
52 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, 54 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
53 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, 55 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
56#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
54 { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, 57 { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
55 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, 58 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
59#endif
56 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, 60 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
57 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, 61 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
58#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 62#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
59 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, 63 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
60#endif
61/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ 64/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
65#endif
62 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, 66 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
63 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, 67 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
64 /* SN9C103 */ 68 /* SN9C103 */
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 6b3fbcca7747..80f6bfa2632b 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -781,6 +781,32 @@ static int soc_camera_s_crop(struct file *file, void *fh,
781 return ret; 781 return ret;
782} 782}
783 783
784static int soc_camera_g_parm(struct file *file, void *fh,
785 struct v4l2_streamparm *a)
786{
787 struct soc_camera_file *icf = file->private_data;
788 struct soc_camera_device *icd = icf->icd;
789 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
790
791 if (ici->ops->get_parm)
792 return ici->ops->get_parm(icd, a);
793
794 return -ENOIOCTLCMD;
795}
796
797static int soc_camera_s_parm(struct file *file, void *fh,
798 struct v4l2_streamparm *a)
799{
800 struct soc_camera_file *icf = file->private_data;
801 struct soc_camera_device *icd = icf->icd;
802 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
803
804 if (ici->ops->set_parm)
805 return ici->ops->set_parm(icd, a);
806
807 return -ENOIOCTLCMD;
808}
809
784static int soc_camera_g_chip_ident(struct file *file, void *fh, 810static int soc_camera_g_chip_ident(struct file *file, void *fh,
785 struct v4l2_dbg_chip_ident *id) 811 struct v4l2_dbg_chip_ident *id)
786{ 812{
@@ -846,10 +872,8 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
846 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 872 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
847 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id); 873 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
848 struct v4l2_subdev *subdev; 874 struct v4l2_subdev *subdev;
849 int ret;
850 875
851 if (!adap) { 876 if (!adap) {
852 ret = -ENODEV;
853 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n", 877 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
854 icl->i2c_adapter_id); 878 icl->i2c_adapter_id);
855 goto ei2cga; 879 goto ei2cga;
@@ -859,10 +883,8 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
859 883
860 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, 884 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
861 icl->module_name, icl->board_info, NULL); 885 icl->module_name, icl->board_info, NULL);
862 if (!subdev) { 886 if (!subdev)
863 ret = -ENOMEM;
864 goto ei2cnd; 887 goto ei2cnd;
865 }
866 888
867 client = subdev->priv; 889 client = subdev->priv;
868 890
@@ -873,7 +895,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
873ei2cnd: 895ei2cnd:
874 i2c_put_adapter(adap); 896 i2c_put_adapter(adap);
875ei2cga: 897ei2cga:
876 return ret; 898 return -ENODEV;
877} 899}
878 900
879static void soc_camera_free_i2c(struct soc_camera_device *icd) 901static void soc_camera_free_i2c(struct soc_camera_device *icd)
@@ -1260,6 +1282,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1260 .vidioc_cropcap = soc_camera_cropcap, 1282 .vidioc_cropcap = soc_camera_cropcap,
1261 .vidioc_g_crop = soc_camera_g_crop, 1283 .vidioc_g_crop = soc_camera_g_crop,
1262 .vidioc_s_crop = soc_camera_s_crop, 1284 .vidioc_s_crop = soc_camera_s_crop,
1285 .vidioc_g_parm = soc_camera_g_parm,
1286 .vidioc_s_parm = soc_camera_s_parm,
1263 .vidioc_g_chip_ident = soc_camera_g_chip_ident, 1287 .vidioc_g_chip_ident = soc_camera_g_chip_ident,
1264#ifdef CONFIG_VIDEO_ADV_DEBUG 1288#ifdef CONFIG_VIDEO_ADV_DEBUG
1265 .vidioc_g_register = soc_camera_g_register, 1289 .vidioc_g_register = soc_camera_g_register,
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index f8d5c87dc2aa..8b63b6545e76 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -24,91 +24,106 @@ static const struct soc_mbus_pixelfmt mbus_fmt[] = {
24 .bits_per_sample = 8, 24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI, 25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE, 26 .order = SOC_MBUS_ORDER_LE,
27 }, [MBUS_IDX(YVYU8_2X8_LE)] = { 27 },
28 [MBUS_IDX(YVYU8_2X8_LE)] = {
28 .fourcc = V4L2_PIX_FMT_YVYU, 29 .fourcc = V4L2_PIX_FMT_YVYU,
29 .name = "YVYU", 30 .name = "YVYU",
30 .bits_per_sample = 8, 31 .bits_per_sample = 8,
31 .packing = SOC_MBUS_PACKING_2X8_PADHI, 32 .packing = SOC_MBUS_PACKING_2X8_PADHI,
32 .order = SOC_MBUS_ORDER_LE, 33 .order = SOC_MBUS_ORDER_LE,
33 }, [MBUS_IDX(YUYV8_2X8_BE)] = { 34 },
35 [MBUS_IDX(YUYV8_2X8_BE)] = {
34 .fourcc = V4L2_PIX_FMT_UYVY, 36 .fourcc = V4L2_PIX_FMT_UYVY,
35 .name = "UYVY", 37 .name = "UYVY",
36 .bits_per_sample = 8, 38 .bits_per_sample = 8,
37 .packing = SOC_MBUS_PACKING_2X8_PADHI, 39 .packing = SOC_MBUS_PACKING_2X8_PADHI,
38 .order = SOC_MBUS_ORDER_LE, 40 .order = SOC_MBUS_ORDER_LE,
39 }, [MBUS_IDX(YVYU8_2X8_BE)] = { 41 },
42 [MBUS_IDX(YVYU8_2X8_BE)] = {
40 .fourcc = V4L2_PIX_FMT_VYUY, 43 .fourcc = V4L2_PIX_FMT_VYUY,
41 .name = "VYUY", 44 .name = "VYUY",
42 .bits_per_sample = 8, 45 .bits_per_sample = 8,
43 .packing = SOC_MBUS_PACKING_2X8_PADHI, 46 .packing = SOC_MBUS_PACKING_2X8_PADHI,
44 .order = SOC_MBUS_ORDER_LE, 47 .order = SOC_MBUS_ORDER_LE,
45 }, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { 48 },
49 [MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
46 .fourcc = V4L2_PIX_FMT_RGB555, 50 .fourcc = V4L2_PIX_FMT_RGB555,
47 .name = "RGB555", 51 .name = "RGB555",
48 .bits_per_sample = 8, 52 .bits_per_sample = 8,
49 .packing = SOC_MBUS_PACKING_2X8_PADHI, 53 .packing = SOC_MBUS_PACKING_2X8_PADHI,
50 .order = SOC_MBUS_ORDER_LE, 54 .order = SOC_MBUS_ORDER_LE,
51 }, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { 55 },
56 [MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
52 .fourcc = V4L2_PIX_FMT_RGB555X, 57 .fourcc = V4L2_PIX_FMT_RGB555X,
53 .name = "RGB555X", 58 .name = "RGB555X",
54 .bits_per_sample = 8, 59 .bits_per_sample = 8,
55 .packing = SOC_MBUS_PACKING_2X8_PADHI, 60 .packing = SOC_MBUS_PACKING_2X8_PADHI,
56 .order = SOC_MBUS_ORDER_LE, 61 .order = SOC_MBUS_ORDER_LE,
57 }, [MBUS_IDX(RGB565_2X8_LE)] = { 62 },
63 [MBUS_IDX(RGB565_2X8_LE)] = {
58 .fourcc = V4L2_PIX_FMT_RGB565, 64 .fourcc = V4L2_PIX_FMT_RGB565,
59 .name = "RGB565", 65 .name = "RGB565",
60 .bits_per_sample = 8, 66 .bits_per_sample = 8,
61 .packing = SOC_MBUS_PACKING_2X8_PADHI, 67 .packing = SOC_MBUS_PACKING_2X8_PADHI,
62 .order = SOC_MBUS_ORDER_LE, 68 .order = SOC_MBUS_ORDER_LE,
63 }, [MBUS_IDX(RGB565_2X8_BE)] = { 69 },
70 [MBUS_IDX(RGB565_2X8_BE)] = {
64 .fourcc = V4L2_PIX_FMT_RGB565X, 71 .fourcc = V4L2_PIX_FMT_RGB565X,
65 .name = "RGB565X", 72 .name = "RGB565X",
66 .bits_per_sample = 8, 73 .bits_per_sample = 8,
67 .packing = SOC_MBUS_PACKING_2X8_PADHI, 74 .packing = SOC_MBUS_PACKING_2X8_PADHI,
68 .order = SOC_MBUS_ORDER_LE, 75 .order = SOC_MBUS_ORDER_LE,
69 }, [MBUS_IDX(SBGGR8_1X8)] = { 76 },
77 [MBUS_IDX(SBGGR8_1X8)] = {
70 .fourcc = V4L2_PIX_FMT_SBGGR8, 78 .fourcc = V4L2_PIX_FMT_SBGGR8,
71 .name = "Bayer 8 BGGR", 79 .name = "Bayer 8 BGGR",
72 .bits_per_sample = 8, 80 .bits_per_sample = 8,
73 .packing = SOC_MBUS_PACKING_NONE, 81 .packing = SOC_MBUS_PACKING_NONE,
74 .order = SOC_MBUS_ORDER_LE, 82 .order = SOC_MBUS_ORDER_LE,
75 }, [MBUS_IDX(SBGGR10_1X10)] = { 83 },
84 [MBUS_IDX(SBGGR10_1X10)] = {
76 .fourcc = V4L2_PIX_FMT_SBGGR10, 85 .fourcc = V4L2_PIX_FMT_SBGGR10,
77 .name = "Bayer 10 BGGR", 86 .name = "Bayer 10 BGGR",
78 .bits_per_sample = 10, 87 .bits_per_sample = 10,
79 .packing = SOC_MBUS_PACKING_EXTEND16, 88 .packing = SOC_MBUS_PACKING_EXTEND16,
80 .order = SOC_MBUS_ORDER_LE, 89 .order = SOC_MBUS_ORDER_LE,
81 }, [MBUS_IDX(GREY8_1X8)] = { 90 },
91 [MBUS_IDX(GREY8_1X8)] = {
82 .fourcc = V4L2_PIX_FMT_GREY, 92 .fourcc = V4L2_PIX_FMT_GREY,
83 .name = "Grey", 93 .name = "Grey",
84 .bits_per_sample = 8, 94 .bits_per_sample = 8,
85 .packing = SOC_MBUS_PACKING_NONE, 95 .packing = SOC_MBUS_PACKING_NONE,
86 .order = SOC_MBUS_ORDER_LE, 96 .order = SOC_MBUS_ORDER_LE,
87 }, [MBUS_IDX(Y10_1X10)] = { 97 },
98 [MBUS_IDX(Y10_1X10)] = {
88 .fourcc = V4L2_PIX_FMT_Y10, 99 .fourcc = V4L2_PIX_FMT_Y10,
89 .name = "Grey 10bit", 100 .name = "Grey 10bit",
90 .bits_per_sample = 10, 101 .bits_per_sample = 10,
91 .packing = SOC_MBUS_PACKING_EXTEND16, 102 .packing = SOC_MBUS_PACKING_EXTEND16,
92 .order = SOC_MBUS_ORDER_LE, 103 .order = SOC_MBUS_ORDER_LE,
93 }, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { 104 },
105 [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
94 .fourcc = V4L2_PIX_FMT_SBGGR10, 106 .fourcc = V4L2_PIX_FMT_SBGGR10,
95 .name = "Bayer 10 BGGR", 107 .name = "Bayer 10 BGGR",
96 .bits_per_sample = 8, 108 .bits_per_sample = 8,
97 .packing = SOC_MBUS_PACKING_2X8_PADHI, 109 .packing = SOC_MBUS_PACKING_2X8_PADHI,
98 .order = SOC_MBUS_ORDER_LE, 110 .order = SOC_MBUS_ORDER_LE,
99 }, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { 111 },
112 [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
100 .fourcc = V4L2_PIX_FMT_SBGGR10, 113 .fourcc = V4L2_PIX_FMT_SBGGR10,
101 .name = "Bayer 10 BGGR", 114 .name = "Bayer 10 BGGR",
102 .bits_per_sample = 8, 115 .bits_per_sample = 8,
103 .packing = SOC_MBUS_PACKING_2X8_PADLO, 116 .packing = SOC_MBUS_PACKING_2X8_PADLO,
104 .order = SOC_MBUS_ORDER_LE, 117 .order = SOC_MBUS_ORDER_LE,
105 }, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { 118 },
119 [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
106 .fourcc = V4L2_PIX_FMT_SBGGR10, 120 .fourcc = V4L2_PIX_FMT_SBGGR10,
107 .name = "Bayer 10 BGGR", 121 .name = "Bayer 10 BGGR",
108 .bits_per_sample = 8, 122 .bits_per_sample = 8,
109 .packing = SOC_MBUS_PACKING_2X8_PADHI, 123 .packing = SOC_MBUS_PACKING_2X8_PADHI,
110 .order = SOC_MBUS_ORDER_BE, 124 .order = SOC_MBUS_ORDER_BE,
111 }, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { 125 },
126 [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
112 .fourcc = V4L2_PIX_FMT_SBGGR10, 127 .fourcc = V4L2_PIX_FMT_SBGGR10,
113 .name = "Bayer 10 BGGR", 128 .name = "Bayer 10 BGGR",
114 .bits_per_sample = 8, 129 .bits_per_sample = 8,
@@ -134,7 +149,8 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line);
134const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 149const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
135 enum v4l2_mbus_pixelcode code) 150 enum v4l2_mbus_pixelcode code)
136{ 151{
137 if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt)) 152 if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) ||
153 code <= V4L2_MBUS_FMT_FIXED)
138 return NULL; 154 return NULL;
139 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1; 155 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
140} 156}
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/video/tlg2300/Kconfig
new file mode 100644
index 000000000000..2c29ec659b4e
--- /dev/null
+++ b/drivers/media/video/tlg2300/Kconfig
@@ -0,0 +1,16 @@
1config VIDEO_TLG2300
2 tristate "Telegent TLG2300 USB video capture support"
3 depends on VIDEO_DEV && I2C && INPUT && SND && DVB_CORE
4 select VIDEO_TUNER
5 select VIDEO_TVEEPROM
6 select VIDEO_IR
7 select VIDEOBUF_VMALLOC
8 select SND_PCM
9 select VIDEOBUF_DVB
10
11 ---help---
12 This is a video4linux driver for Telegent tlg2300 based TV cards.
13 The driver supports V4L2, DVB-T and radio.
14
15 To compile this driver as a module, choose M here: the
16 module will be called poseidon
diff --git a/drivers/media/video/tlg2300/Makefile b/drivers/media/video/tlg2300/Makefile
new file mode 100644
index 000000000000..81bb7fdd1e3d
--- /dev/null
+++ b/drivers/media/video/tlg2300/Makefile
@@ -0,0 +1,9 @@
1poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
2
3obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
4
5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/common/tuners
7EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
8EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
9
diff --git a/drivers/media/video/tlg2300/pd-alsa.c b/drivers/media/video/tlg2300/pd-alsa.c
new file mode 100644
index 000000000000..6f42621ad478
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-alsa.c
@@ -0,0 +1,332 @@
1#include <linux/kernel.h>
2#include <linux/usb.h>
3#include <linux/init.h>
4#include <linux/sound.h>
5#include <linux/spinlock.h>
6#include <linux/soundcard.h>
7#include <linux/slab.h>
8#include <linux/vmalloc.h>
9#include <linux/proc_fs.h>
10#include <linux/module.h>
11#include <sound/core.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14#include <sound/info.h>
15#include <sound/initval.h>
16#include <sound/control.h>
17#include <media/v4l2-common.h>
18#include "pd-common.h"
19#include "vendorcmds.h"
20
21static void complete_handler_audio(struct urb *urb);
22#define AUDIO_EP (0x83)
23#define AUDIO_BUF_SIZE (512)
24#define PERIOD_SIZE (1024 * 8)
25#define PERIOD_MIN (4)
26#define PERIOD_MAX PERIOD_MIN
27
28static struct snd_pcm_hardware snd_pd_hw_capture = {
29 .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
30 SNDRV_PCM_INFO_MMAP |
31 SNDRV_PCM_INFO_INTERLEAVED |
32 SNDRV_PCM_INFO_MMAP_VALID,
33
34 .formats = SNDRV_PCM_FMTBIT_S16_LE,
35 .rates = SNDRV_PCM_RATE_48000,
36
37 .rate_min = 48000,
38 .rate_max = 48000,
39 .channels_min = 2,
40 .channels_max = 2,
41 .buffer_bytes_max = PERIOD_SIZE * PERIOD_MIN,
42 .period_bytes_min = PERIOD_SIZE,
43 .period_bytes_max = PERIOD_SIZE,
44 .periods_min = PERIOD_MIN,
45 .periods_max = PERIOD_MAX,
46 /*
47 .buffer_bytes_max = 62720 * 8,
48 .period_bytes_min = 64,
49 .period_bytes_max = 12544,
50 .periods_min = 2,
51 .periods_max = 98
52 */
53};
54
55static int snd_pd_capture_open(struct snd_pcm_substream *substream)
56{
57 struct poseidon *p = snd_pcm_substream_chip(substream);
58 struct poseidon_audio *pa = &p->audio;
59 struct snd_pcm_runtime *runtime = substream->runtime;
60
61 if (!p)
62 return -ENODEV;
63 pa->users++;
64 pa->card_close = 0;
65 pa->capture_pcm_substream = substream;
66 runtime->private_data = p;
67
68 runtime->hw = snd_pd_hw_capture;
69 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
70 usb_autopm_get_interface(p->interface);
71 kref_get(&p->kref);
72 return 0;
73}
74
75static int snd_pd_pcm_close(struct snd_pcm_substream *substream)
76{
77 struct poseidon *p = snd_pcm_substream_chip(substream);
78 struct poseidon_audio *pa = &p->audio;
79
80 pa->users--;
81 pa->card_close = 1;
82 usb_autopm_put_interface(p->interface);
83 kref_put(&p->kref, poseidon_delete);
84 return 0;
85}
86
87static int snd_pd_hw_capture_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *hw_params)
89{
90 struct snd_pcm_runtime *runtime = substream->runtime;
91 unsigned int size;
92
93 size = params_buffer_bytes(hw_params);
94 if (runtime->dma_area) {
95 if (runtime->dma_bytes > size)
96 return 0;
97 vfree(runtime->dma_area);
98 }
99 runtime->dma_area = vmalloc(size);
100 if (!runtime->dma_area)
101 return -ENOMEM;
102 else
103 runtime->dma_bytes = size;
104 return 0;
105}
106
107static int audio_buf_free(struct poseidon *p)
108{
109 struct poseidon_audio *pa = &p->audio;
110 int i;
111
112 for (i = 0; i < AUDIO_BUFS; i++)
113 if (pa->urb_array[i])
114 usb_kill_urb(pa->urb_array[i]);
115 free_all_urb_generic(pa->urb_array, AUDIO_BUFS);
116 logpm();
117 return 0;
118}
119
120static int snd_pd_hw_capture_free(struct snd_pcm_substream *substream)
121{
122 struct poseidon *p = snd_pcm_substream_chip(substream);
123
124 logpm();
125 audio_buf_free(p);
126 return 0;
127}
128
129static int snd_pd_prepare(struct snd_pcm_substream *substream)
130{
131 return 0;
132}
133
134#define AUDIO_TRAILER_SIZE (16)
135static inline void handle_audio_data(struct urb *urb, int *period_elapsed)
136{
137 struct poseidon_audio *pa = urb->context;
138 struct snd_pcm_runtime *runtime = pa->capture_pcm_substream->runtime;
139
140 int stride = runtime->frame_bits >> 3;
141 int len = urb->actual_length / stride;
142 unsigned char *cp = urb->transfer_buffer;
143 unsigned int oldptr = pa->rcv_position;
144
145 if (urb->actual_length == AUDIO_BUF_SIZE - 4)
146 len -= (AUDIO_TRAILER_SIZE / stride);
147
148 /* do the copy */
149 if (oldptr + len >= runtime->buffer_size) {
150 unsigned int cnt = runtime->buffer_size - oldptr;
151
152 memcpy(runtime->dma_area + oldptr * stride, cp, cnt * stride);
153 memcpy(runtime->dma_area, (cp + cnt * stride),
154 (len * stride - cnt * stride));
155 } else
156 memcpy(runtime->dma_area + oldptr * stride, cp, len * stride);
157
158 /* update the statas */
159 snd_pcm_stream_lock(pa->capture_pcm_substream);
160 pa->rcv_position += len;
161 if (pa->rcv_position >= runtime->buffer_size)
162 pa->rcv_position -= runtime->buffer_size;
163
164 pa->copied_position += (len);
165 if (pa->copied_position >= runtime->period_size) {
166 pa->copied_position -= runtime->period_size;
167 *period_elapsed = 1;
168 }
169 snd_pcm_stream_unlock(pa->capture_pcm_substream);
170}
171
172static void complete_handler_audio(struct urb *urb)
173{
174 struct poseidon_audio *pa = urb->context;
175 struct snd_pcm_substream *substream = pa->capture_pcm_substream;
176 int period_elapsed = 0;
177 int ret;
178
179 if (1 == pa->card_close || pa->capture_stream != STREAM_ON)
180 return;
181
182 if (urb->status != 0) {
183 /*if (urb->status == -ESHUTDOWN)*/
184 return;
185 }
186
187 if (substream) {
188 if (urb->actual_length) {
189 handle_audio_data(urb, &period_elapsed);
190 if (period_elapsed)
191 snd_pcm_period_elapsed(substream);
192 }
193 }
194
195 ret = usb_submit_urb(urb, GFP_ATOMIC);
196 if (ret < 0)
197 log("audio urb failed (errcod = %i)", ret);
198 return;
199}
200
201static int fire_audio_urb(struct poseidon *p)
202{
203 int i, ret = 0;
204 struct poseidon_audio *pa = &p->audio;
205
206 alloc_bulk_urbs_generic(pa->urb_array, AUDIO_BUFS,
207 p->udev, AUDIO_EP,
208 AUDIO_BUF_SIZE, GFP_ATOMIC,
209 complete_handler_audio, pa);
210
211 for (i = 0; i < AUDIO_BUFS; i++) {
212 ret = usb_submit_urb(pa->urb_array[i], GFP_KERNEL);
213 if (ret)
214 log("urb err : %d", ret);
215 }
216 log();
217 return ret;
218}
219
220static int snd_pd_capture_trigger(struct snd_pcm_substream *substream, int cmd)
221{
222 struct poseidon *p = snd_pcm_substream_chip(substream);
223 struct poseidon_audio *pa = &p->audio;
224
225 if (debug_mode)
226 log("cmd %d, audio stat : %d\n", cmd, pa->capture_stream);
227
228 switch (cmd) {
229 case SNDRV_PCM_TRIGGER_RESUME:
230 case SNDRV_PCM_TRIGGER_START:
231 if (pa->capture_stream == STREAM_ON)
232 return 0;
233
234 pa->rcv_position = pa->copied_position = 0;
235 pa->capture_stream = STREAM_ON;
236
237 if (in_hibernation(p))
238 return 0;
239 fire_audio_urb(p);
240 return 0;
241
242 case SNDRV_PCM_TRIGGER_SUSPEND:
243 pa->capture_stream = STREAM_SUSPEND;
244 return 0;
245 case SNDRV_PCM_TRIGGER_STOP:
246 pa->capture_stream = STREAM_OFF;
247 return 0;
248 default:
249 return -EINVAL;
250 }
251}
252
253static snd_pcm_uframes_t
254snd_pd_capture_pointer(struct snd_pcm_substream *substream)
255{
256 struct poseidon *p = snd_pcm_substream_chip(substream);
257 struct poseidon_audio *pa = &p->audio;
258 return pa->rcv_position;
259}
260
261static struct page *snd_pcm_pd_get_page(struct snd_pcm_substream *subs,
262 unsigned long offset)
263{
264 void *pageptr = subs->runtime->dma_area + offset;
265 return vmalloc_to_page(pageptr);
266}
267
268static struct snd_pcm_ops pcm_capture_ops = {
269 .open = snd_pd_capture_open,
270 .close = snd_pd_pcm_close,
271 .ioctl = snd_pcm_lib_ioctl,
272 .hw_params = snd_pd_hw_capture_params,
273 .hw_free = snd_pd_hw_capture_free,
274 .prepare = snd_pd_prepare,
275 .trigger = snd_pd_capture_trigger,
276 .pointer = snd_pd_capture_pointer,
277 .page = snd_pcm_pd_get_page,
278};
279
280#ifdef CONFIG_PM
281int pm_alsa_suspend(struct poseidon *p)
282{
283 logpm(p);
284 audio_buf_free(p);
285 return 0;
286}
287
288int pm_alsa_resume(struct poseidon *p)
289{
290 logpm(p);
291 fire_audio_urb(p);
292 return 0;
293}
294#endif
295
296int poseidon_audio_init(struct poseidon *p)
297{
298 struct poseidon_audio *pa = &p->audio;
299 struct snd_card *card;
300 struct snd_pcm *pcm;
301 int ret;
302
303 ret = snd_card_create(-1, "Telegent", THIS_MODULE, 0, &card);
304 if (ret != 0)
305 return ret;
306
307 ret = snd_pcm_new(card, "poseidon audio", 0, 0, 1, &pcm);
308 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
309 pcm->info_flags = 0;
310 pcm->private_data = p;
311 strcpy(pcm->name, "poseidon audio capture");
312
313 strcpy(card->driver, "ALSA driver");
314 strcpy(card->shortname, "poseidon Audio");
315 strcpy(card->longname, "poseidon ALSA Audio");
316
317 if (snd_card_register(card)) {
318 snd_card_free(card);
319 return -ENOMEM;
320 }
321 pa->card = card;
322 return 0;
323}
324
325int poseidon_audio_free(struct poseidon *p)
326{
327 struct poseidon_audio *pa = &p->audio;
328
329 if (pa->card)
330 snd_card_free(pa->card);
331 return 0;
332}
diff --git a/drivers/media/video/tlg2300/pd-common.h b/drivers/media/video/tlg2300/pd-common.h
new file mode 100644
index 000000000000..46066bdc73f9
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-common.h
@@ -0,0 +1,282 @@
1#ifndef PD_COMMON_H
2#define PD_COMMON_H
3
4#include <linux/version.h>
5#include <linux/fs.h>
6#include <linux/wait.h>
7#include <linux/list.h>
8#include <linux/videodev2.h>
9#include <linux/semaphore.h>
10#include <linux/usb.h>
11#include <linux/poll.h>
12#include <media/videobuf-vmalloc.h>
13#include <media/v4l2-device.h>
14
15#include "dvb_frontend.h"
16#include "dvbdev.h"
17#include "dvb_demux.h"
18#include "dmxdev.h"
19
20#define SBUF_NUM 8
21#define MAX_BUFFER_NUM 6
22#define PK_PER_URB 32
23#define ISO_PKT_SIZE 3072
24
25#define POSEIDON_STATE_NONE (0x0000)
26#define POSEIDON_STATE_ANALOG (0x0001)
27#define POSEIDON_STATE_FM (0x0002)
28#define POSEIDON_STATE_DVBT (0x0004)
29#define POSEIDON_STATE_VBI (0x0008)
30#define POSEIDON_STATE_DISCONNECT (0x0080)
31
32#define PM_SUSPEND_DELAY 3
33
34#define V4L_PAL_VBI_LINES 18
35#define V4L_NTSC_VBI_LINES 12
36#define V4L_PAL_VBI_FRAMESIZE (V4L_PAL_VBI_LINES * 1440 * 2)
37#define V4L_NTSC_VBI_FRAMESIZE (V4L_NTSC_VBI_LINES * 1440 * 2)
38
39#define TUNER_FREQ_MIN (45000000)
40#define TUNER_FREQ_MAX (862000000)
41
42struct vbi_data {
43 struct video_device *v_dev;
44 struct video_data *video;
45 struct front_face *front;
46
47 unsigned int copied;
48 unsigned int vbi_size; /* the whole size of two fields */
49 int users;
50};
51
52/*
53 * This is the running context of the video, it is useful for
54 * resume()
55 */
56struct running_context {
57 u32 freq; /* VIDIOC_S_FREQUENCY */
58 int audio_idx; /* VIDIOC_S_TUNER */
59 v4l2_std_id tvnormid; /* VIDIOC_S_STD */
60 int sig_index; /* VIDIOC_S_INPUT */
61 struct v4l2_pix_format pix; /* VIDIOC_S_FMT */
62};
63
64struct video_data {
65 /* v4l2 video device */
66 struct video_device *v_dev;
67
68 /* the working context */
69 struct running_context context;
70
71 /* for data copy */
72 int field_count;
73
74 char *dst;
75 int lines_copied;
76 int prev_left;
77
78 int lines_per_field;
79 int lines_size;
80
81 /* for communication */
82 u8 endpoint_addr;
83 struct urb *urb_array[SBUF_NUM];
84 struct vbi_data *vbi;
85 struct poseidon *pd;
86 struct front_face *front;
87
88 int is_streaming;
89 int users;
90
91 /* for bubble handler */
92 struct work_struct bubble_work;
93};
94
95enum pcm_stream_state {
96 STREAM_OFF,
97 STREAM_ON,
98 STREAM_SUSPEND,
99};
100
101#define AUDIO_BUFS (3)
102#define CAPTURE_STREAM_EN 1
103struct poseidon_audio {
104 struct urb *urb_array[AUDIO_BUFS];
105 unsigned int copied_position;
106 struct snd_pcm_substream *capture_pcm_substream;
107
108 unsigned int rcv_position;
109 struct snd_card *card;
110 int card_close;
111
112 int users;
113 int pm_state;
114 enum pcm_stream_state capture_stream;
115};
116
117struct radio_data {
118 __u32 fm_freq;
119 int users;
120 unsigned int is_radio_streaming;
121 int pre_emphasis;
122 struct video_device *fm_dev;
123};
124
125#define DVB_SBUF_NUM 4
126#define DVB_URB_BUF_SIZE 0x2000
127struct pd_dvb_adapter {
128 struct dvb_adapter dvb_adap;
129 struct dvb_frontend dvb_fe;
130 struct dmxdev dmxdev;
131 struct dvb_demux demux;
132
133 atomic_t users;
134 atomic_t active_feed;
135
136 /* data transfer */
137 s32 is_streaming;
138 struct urb *urb_array[DVB_SBUF_NUM];
139 struct poseidon *pd_device;
140 u8 ep_addr;
141 u8 reserved[3];
142
143 /* data for power resume*/
144 struct dvb_frontend_parameters fe_param;
145
146 /* for channel scanning */
147 int prev_freq;
148 int bandwidth;
149 unsigned long last_jiffies;
150};
151
152struct front_face {
153 /* use this field to distinguish VIDEO and VBI */
154 enum v4l2_buf_type type;
155
156 /* for host */
157 struct videobuf_queue q;
158
159 /* the bridge for host and device */
160 struct videobuf_buffer *curr_frame;
161
162 /* for device */
163 spinlock_t queue_lock;
164 struct list_head active;
165 struct poseidon *pd;
166};
167
168struct poseidon {
169 struct list_head device_list;
170
171 struct mutex lock;
172 struct kref kref;
173
174 /* for V4L2 */
175 struct v4l2_device v4l2_dev;
176
177 /* hardware info */
178 struct usb_device *udev;
179 struct usb_interface *interface;
180 int cur_transfer_mode;
181
182 struct video_data video_data; /* video */
183 struct vbi_data vbi_data; /* vbi */
184 struct poseidon_audio audio; /* audio (alsa) */
185 struct radio_data radio_data; /* FM */
186 struct pd_dvb_adapter dvb_data; /* DVB */
187
188 u32 state;
189 struct file *file_for_stream; /* the active stream*/
190
191#ifdef CONFIG_PM
192 int (*pm_suspend)(struct poseidon *);
193 int (*pm_resume)(struct poseidon *);
194 pm_message_t msg;
195
196 struct work_struct pm_work;
197 u8 portnum;
198#endif
199};
200
201struct poseidon_format {
202 char *name;
203 int fourcc; /* video4linux 2 */
204 int depth; /* bit/pixel */
205 int flags;
206};
207
208struct poseidon_tvnorm {
209 v4l2_std_id v4l2_id;
210 char name[12];
211 u32 tlg_tvnorm;
212};
213
214/* video */
215int pd_video_init(struct poseidon *);
216void pd_video_exit(struct poseidon *);
217int stop_all_video_stream(struct poseidon *);
218
219/* alsa audio */
220int poseidon_audio_init(struct poseidon *);
221int poseidon_audio_free(struct poseidon *);
222#ifdef CONFIG_PM
223int pm_alsa_suspend(struct poseidon *);
224int pm_alsa_resume(struct poseidon *);
225#endif
226
227/* dvb */
228int pd_dvb_usb_device_init(struct poseidon *);
229void pd_dvb_usb_device_exit(struct poseidon *);
230void pd_dvb_usb_device_cleanup(struct poseidon *);
231int pd_dvb_get_adapter_num(struct pd_dvb_adapter *);
232void dvb_stop_streaming(struct pd_dvb_adapter *);
233
234/* FM */
235int poseidon_fm_init(struct poseidon *);
236int poseidon_fm_exit(struct poseidon *);
237struct video_device *vdev_init(struct poseidon *, struct video_device *);
238
239/* vendor command ops */
240int send_set_req(struct poseidon*, u8, s32, s32*);
241int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32);
242s32 set_tuner_mode(struct poseidon*, unsigned char);
243
244/* bulk urb alloc/free */
245int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
246 struct usb_device *udev, u8 ep_addr,
247 int buf_size, gfp_t gfp_flags,
248 usb_complete_t complete_fn, void *context);
249void free_all_urb_generic(struct urb **urb_array, int num);
250
251/* misc */
252void poseidon_delete(struct kref *kref);
253void destroy_video_device(struct video_device **v_dev);
254extern int debug_mode;
255void set_debug_mode(struct video_device *vfd, int debug_mode);
256
257#ifdef CONFIG_PM
258#define in_hibernation(pd) (pd->msg.event == PM_EVENT_FREEZE)
259#else
260#define in_hibernation(pd) (0)
261#endif
262#define get_pm_count(p) (atomic_read(&(p)->interface->pm_usage_cnt))
263
264#define log(a, ...) printk(KERN_DEBUG "\t[ %s : %.3d ] "a"\n", \
265 __func__, __LINE__, ## __VA_ARGS__)
266
267/* for power management */
268#define logpm(pd) do {\
269 if (debug_mode & 0x10)\
270 log();\
271 } while (0)
272
273#define logs(f) do { \
274 if ((debug_mode & 0x4) && \
275 (f)->type == V4L2_BUF_TYPE_VBI_CAPTURE) \
276 log("type : VBI");\
277 \
278 if ((debug_mode & 0x8) && \
279 (f)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) \
280 log("type : VIDEO");\
281 } while (0)
282#endif
diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/video/tlg2300/pd-dvb.c
new file mode 100644
index 000000000000..4133aee568bf
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-dvb.c
@@ -0,0 +1,593 @@
1#include "pd-common.h"
2#include <linux/kernel.h>
3#include <linux/usb.h>
4#include <linux/dvb/dmx.h>
5#include <linux/delay.h>
6
7#include "vendorcmds.h"
8#include <linux/sched.h>
9#include <asm/atomic.h>
10
11static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
12
13static int dvb_bandwidth[][2] = {
14 { TLG_BW_8, BANDWIDTH_8_MHZ },
15 { TLG_BW_7, BANDWIDTH_7_MHZ },
16 { TLG_BW_6, BANDWIDTH_6_MHZ }
17};
18static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
19
20static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
21static int poseidon_check_mode_dvbt(struct poseidon *pd)
22{
23 s32 ret = 0, cmd_status = 0;
24
25 set_current_state(TASK_INTERRUPTIBLE);
26 schedule_timeout(HZ/4);
27
28 ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
29 if (ret != 0)
30 return ret;
31
32 ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
33 if (ret)
34 return ret;
35
36 /* signal source */
37 ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
38 if (ret|cmd_status)
39 return ret;
40
41 return 0;
42}
43
44/* acquire :
45 * 1 == open
46 * 0 == release
47 */
48static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
49{
50 struct poseidon *pd = fe->demodulator_priv;
51 struct pd_dvb_adapter *pd_dvb;
52 int ret = 0;
53
54 if (!pd)
55 return -ENODEV;
56
57 pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
58 if (acquire) {
59 mutex_lock(&pd->lock);
60 if (pd->state & POSEIDON_STATE_DISCONNECT) {
61 ret = -ENODEV;
62 goto open_out;
63 }
64
65 if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
66 ret = -EBUSY;
67 goto open_out;
68 }
69
70 usb_autopm_get_interface(pd->interface);
71 if (0 == pd->state) {
72 ret = poseidon_check_mode_dvbt(pd);
73 if (ret < 0) {
74 usb_autopm_put_interface(pd->interface);
75 goto open_out;
76 }
77 pd->state |= POSEIDON_STATE_DVBT;
78 pd_dvb->bandwidth = 0;
79 pd_dvb->prev_freq = 0;
80 }
81 atomic_inc(&pd_dvb->users);
82 kref_get(&pd->kref);
83open_out:
84 mutex_unlock(&pd->lock);
85 } else {
86 dvb_stop_streaming(pd_dvb);
87
88 if (atomic_dec_and_test(&pd_dvb->users)) {
89 mutex_lock(&pd->lock);
90 pd->state &= ~POSEIDON_STATE_DVBT;
91 mutex_unlock(&pd->lock);
92 }
93 kref_put(&pd->kref, poseidon_delete);
94 usb_autopm_put_interface(pd->interface);
95 }
96 return ret;
97}
98
99static void poseidon_fe_release(struct dvb_frontend *fe)
100{
101 struct poseidon *pd = fe->demodulator_priv;
102
103#ifdef CONFIG_PM
104 pd->pm_suspend = NULL;
105 pd->pm_resume = NULL;
106#endif
107}
108
109static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
110{
111 return 0;
112}
113
114/*
115 * return true if we can satisfy the conditions, else return false.
116 */
117static bool check_scan_ok(__u32 freq, int bandwidth,
118 struct pd_dvb_adapter *adapter)
119{
120 if (bandwidth < 0)
121 return false;
122
123 if (adapter->prev_freq == freq
124 && adapter->bandwidth == bandwidth) {
125 long nl = jiffies - adapter->last_jiffies;
126 unsigned int msec ;
127
128 msec = jiffies_to_msecs(abs(nl));
129 return msec > 15000 ? true : false;
130 }
131 return true;
132}
133
134/*
135 * Check if the firmware delays too long for an invalid frequency.
136 */
137static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
138{
139 long nl = jiffies - adapter->last_jiffies;
140 unsigned int msec ;
141
142 msec = jiffies_to_msecs(abs(nl));
143 return msec > 800 ? true : false;
144}
145
146static int poseidon_set_fe(struct dvb_frontend *fe,
147 struct dvb_frontend_parameters *fep)
148{
149 s32 ret = 0, cmd_status = 0;
150 s32 i, bandwidth = -1;
151 struct poseidon *pd = fe->demodulator_priv;
152 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
153
154 if (in_hibernation(pd))
155 return -EBUSY;
156
157 mutex_lock(&pd->lock);
158 for (i = 0; i < dvb_bandwidth_length; i++)
159 if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1])
160 bandwidth = dvb_bandwidth[i][0];
161
162 if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) {
163 ret = send_set_req(pd, TUNE_FREQ_SELECT,
164 fep->frequency / 1000, &cmd_status);
165 if (ret | cmd_status) {
166 log("error line");
167 goto front_out;
168 }
169
170 ret = send_set_req(pd, DVBT_BANDW_SEL,
171 bandwidth, &cmd_status);
172 if (ret | cmd_status) {
173 log("error line");
174 goto front_out;
175 }
176
177 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
178 if (ret | cmd_status) {
179 log("error line");
180 goto front_out;
181 }
182
183 /* save the context for future */
184 memcpy(&pd_dvb->fe_param, fep, sizeof(*fep));
185 pd_dvb->bandwidth = bandwidth;
186 pd_dvb->prev_freq = fep->frequency;
187 pd_dvb->last_jiffies = jiffies;
188 }
189front_out:
190 mutex_unlock(&pd->lock);
191 return ret;
192}
193
194#ifdef CONFIG_PM
195static int pm_dvb_suspend(struct poseidon *pd)
196{
197 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
198 dvb_stop_streaming(pd_dvb);
199 dvb_urb_cleanup(pd_dvb);
200 msleep(500);
201 return 0;
202}
203
204static int pm_dvb_resume(struct poseidon *pd)
205{
206 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
207
208 poseidon_check_mode_dvbt(pd);
209 msleep(300);
210 poseidon_set_fe(&pd_dvb->dvb_fe, &pd_dvb->fe_param);
211
212 dvb_start_streaming(pd_dvb);
213 return 0;
214}
215#endif
216
217static s32 poseidon_fe_init(struct dvb_frontend *fe)
218{
219 struct poseidon *pd = fe->demodulator_priv;
220 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
221
222#ifdef CONFIG_PM
223 pd->pm_suspend = pm_dvb_suspend;
224 pd->pm_resume = pm_dvb_resume;
225#endif
226 memset(&pd_dvb->fe_param, 0,
227 sizeof(struct dvb_frontend_parameters));
228 return 0;
229}
230
231static int poseidon_get_fe(struct dvb_frontend *fe,
232 struct dvb_frontend_parameters *fep)
233{
234 struct poseidon *pd = fe->demodulator_priv;
235 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
236
237 memcpy(fep, &pd_dvb->fe_param, sizeof(*fep));
238 return 0;
239}
240
241static int poseidon_fe_get_tune_settings(struct dvb_frontend *fe,
242 struct dvb_frontend_tune_settings *tune)
243{
244 tune->min_delay_ms = 1000;
245 return 0;
246}
247
248static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat)
249{
250 struct poseidon *pd = fe->demodulator_priv;
251 s32 ret = -1, cmd_status;
252 struct tuner_dtv_sig_stat_s status = {};
253
254 if (in_hibernation(pd))
255 return -EBUSY;
256 mutex_lock(&pd->lock);
257
258 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
259 &status, &cmd_status, sizeof(status));
260 if (ret | cmd_status) {
261 log("get tuner status error");
262 goto out;
263 }
264
265 if (debug_mode)
266 log("P : %d, L %d, LB :%d", status.sig_present,
267 status.sig_locked, status.sig_lock_busy);
268
269 if (status.sig_lock_busy) {
270 goto out;
271 } else if (status.sig_present || status.sig_locked) {
272 *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER
273 | FE_HAS_SYNC | FE_HAS_VITERBI;
274 } else {
275 if (fw_delay_overflow(&pd->dvb_data))
276 *stat |= FE_TIMEDOUT;
277 }
278out:
279 mutex_unlock(&pd->lock);
280 return ret;
281}
282
283static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber)
284{
285 struct poseidon *pd = fe->demodulator_priv;
286 struct tuner_ber_rate_s tlg_ber = {};
287 s32 ret = -1, cmd_status;
288
289 mutex_lock(&pd->lock);
290 ret = send_get_req(pd, TUNER_BER_RATE, 0,
291 &tlg_ber, &cmd_status, sizeof(tlg_ber));
292 if (ret | cmd_status)
293 goto out;
294 *ber = tlg_ber.ber_rate;
295out:
296 mutex_unlock(&pd->lock);
297 return ret;
298}
299
300static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
301{
302 struct poseidon *pd = fe->demodulator_priv;
303 struct tuner_dtv_sig_stat_s status = {};
304 s32 ret = 0, cmd_status;
305
306 mutex_lock(&pd->lock);
307 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T,
308 &status, &cmd_status, sizeof(status));
309 if (ret | cmd_status)
310 goto out;
311 if ((status.sig_present || status.sig_locked) && !status.sig_strength)
312 *strength = 0xFFFF;
313 else
314 *strength = status.sig_strength;
315out:
316 mutex_unlock(&pd->lock);
317 return ret;
318}
319
320static int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr)
321{
322 return 0;
323}
324
325static int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
326{
327 *unc = 0;
328 return 0;
329}
330
331static struct dvb_frontend_ops poseidon_frontend_ops = {
332 .info = {
333 .name = "Poseidon DVB-T",
334 .type = FE_OFDM,
335 .frequency_min = 174000000,
336 .frequency_max = 862000000,
337 .frequency_stepsize = 62500,/* FIXME */
338 .caps = FE_CAN_INVERSION_AUTO |
339 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
340 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
341 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
342 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
343 FE_CAN_GUARD_INTERVAL_AUTO |
344 FE_CAN_RECOVER |
345 FE_CAN_HIERARCHY_AUTO,
346 },
347
348 .release = poseidon_fe_release,
349
350 .init = poseidon_fe_init,
351 .sleep = poseidon_fe_sleep,
352
353 .set_frontend = poseidon_set_fe,
354 .get_frontend = poseidon_get_fe,
355 .get_tune_settings = poseidon_fe_get_tune_settings,
356
357 .read_status = poseidon_read_status,
358 .read_ber = poseidon_read_ber,
359 .read_signal_strength = poseidon_read_signal_strength,
360 .read_snr = poseidon_read_snr,
361 .read_ucblocks = poseidon_read_unc_blocks,
362
363 .ts_bus_ctrl = poseidon_ts_bus_ctrl,
364};
365
366static void dvb_urb_irq(struct urb *urb)
367{
368 struct pd_dvb_adapter *pd_dvb = urb->context;
369 int len = urb->transfer_buffer_length;
370 struct dvb_demux *demux = &pd_dvb->demux;
371 s32 ret;
372
373 if (!pd_dvb->is_streaming || urb->status) {
374 if (urb->status == -EPROTO)
375 goto resend;
376 return;
377 }
378
379 if (urb->actual_length == len)
380 dvb_dmx_swfilter(demux, urb->transfer_buffer, len);
381 else if (urb->actual_length == len - 4) {
382 int offset;
383 u8 *buf = urb->transfer_buffer;
384
385 /*
386 * The packet size is 512,
387 * last packet contains 456 bytes tsp data
388 */
389 for (offset = 456; offset < len; offset += 512) {
390 if (!strncmp(buf + offset, "DVHS", 4)) {
391 dvb_dmx_swfilter(demux, buf, offset);
392 if (len > offset + 52 + 4) {
393 /*16 bytes trailer + 36 bytes padding */
394 buf += offset + 52;
395 len -= offset + 52 + 4;
396 dvb_dmx_swfilter(demux, buf, len);
397 }
398 break;
399 }
400 }
401 }
402
403resend:
404 ret = usb_submit_urb(urb, GFP_ATOMIC);
405 if (ret)
406 log(" usb_submit_urb failed: error %d", ret);
407}
408
409static int dvb_urb_init(struct pd_dvb_adapter *pd_dvb)
410{
411 if (pd_dvb->urb_array[0])
412 return 0;
413
414 alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM,
415 pd_dvb->pd_device->udev, pd_dvb->ep_addr,
416 DVB_URB_BUF_SIZE, GFP_KERNEL,
417 dvb_urb_irq, pd_dvb);
418 return 0;
419}
420
421static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb)
422{
423 free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM);
424}
425
426static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb)
427{
428 struct poseidon *pd = pd_dvb->pd_device;
429 int ret = 0;
430
431 if (pd->state & POSEIDON_STATE_DISCONNECT)
432 return -ENODEV;
433
434 mutex_lock(&pd->lock);
435 if (!pd_dvb->is_streaming) {
436 s32 i, cmd_status = 0;
437 /*
438 * Once upon a time, there was a difficult bug lying here.
439 * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
440 */
441
442 ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status);
443 if (ret | cmd_status)
444 goto out;
445
446 ret = dvb_urb_init(pd_dvb);
447 if (ret < 0)
448 goto out;
449
450 pd_dvb->is_streaming = 1;
451 for (i = 0; i < DVB_SBUF_NUM; i++) {
452 ret = usb_submit_urb(pd_dvb->urb_array[i],
453 GFP_KERNEL);
454 if (ret) {
455 log(" submit urb error %d", ret);
456 goto out;
457 }
458 }
459 }
460out:
461 mutex_unlock(&pd->lock);
462 return ret;
463}
464
465void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb)
466{
467 struct poseidon *pd = pd_dvb->pd_device;
468
469 mutex_lock(&pd->lock);
470 if (pd_dvb->is_streaming) {
471 s32 i, ret, cmd_status = 0;
472
473 pd_dvb->is_streaming = 0;
474
475 for (i = 0; i < DVB_SBUF_NUM; i++)
476 if (pd_dvb->urb_array[i])
477 usb_kill_urb(pd_dvb->urb_array[i]);
478
479 ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
480 &cmd_status);
481 if (ret | cmd_status)
482 log("error");
483 }
484 mutex_unlock(&pd->lock);
485}
486
487static int pd_start_feed(struct dvb_demux_feed *feed)
488{
489 struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
490 int ret = 0;
491
492 if (!pd_dvb)
493 return -1;
494 if (atomic_inc_return(&pd_dvb->active_feed) == 1)
495 ret = dvb_start_streaming(pd_dvb);
496 return ret;
497}
498
499static int pd_stop_feed(struct dvb_demux_feed *feed)
500{
501 struct pd_dvb_adapter *pd_dvb = feed->demux->priv;
502
503 if (!pd_dvb)
504 return -1;
505 if (atomic_dec_and_test(&pd_dvb->active_feed))
506 dvb_stop_streaming(pd_dvb);
507 return 0;
508}
509
510DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
511int pd_dvb_usb_device_init(struct poseidon *pd)
512{
513 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
514 struct dvb_demux *dvbdemux;
515 int ret = 0;
516
517 pd_dvb->ep_addr = 0x82;
518 atomic_set(&pd_dvb->users, 0);
519 atomic_set(&pd_dvb->active_feed, 0);
520 pd_dvb->pd_device = pd;
521
522 ret = dvb_register_adapter(&pd_dvb->dvb_adap,
523 "Poseidon dvbt adapter",
524 THIS_MODULE,
525 NULL /* for hibernation correctly*/,
526 adapter_nr);
527 if (ret < 0)
528 goto error1;
529
530 /* register frontend */
531 pd_dvb->dvb_fe.demodulator_priv = pd;
532 memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops,
533 sizeof(struct dvb_frontend_ops));
534 ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe);
535 if (ret < 0)
536 goto error2;
537
538 /* register demux device */
539 dvbdemux = &pd_dvb->demux;
540 dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
541 dvbdemux->priv = pd_dvb;
542 dvbdemux->feednum = dvbdemux->filternum = 64;
543 dvbdemux->start_feed = pd_start_feed;
544 dvbdemux->stop_feed = pd_stop_feed;
545 dvbdemux->write_to_decoder = NULL;
546
547 ret = dvb_dmx_init(dvbdemux);
548 if (ret < 0)
549 goto error3;
550
551 pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum;
552 pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx;
553 pd_dvb->dmxdev.capabilities = 0;
554
555 ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap);
556 if (ret < 0)
557 goto error3;
558 return 0;
559
560error3:
561 dvb_unregister_frontend(&pd_dvb->dvb_fe);
562error2:
563 dvb_unregister_adapter(&pd_dvb->dvb_adap);
564error1:
565 return ret;
566}
567
568void pd_dvb_usb_device_exit(struct poseidon *pd)
569{
570 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
571
572 while (atomic_read(&pd_dvb->users) != 0
573 || atomic_read(&pd_dvb->active_feed) != 0) {
574 set_current_state(TASK_INTERRUPTIBLE);
575 schedule_timeout(HZ);
576 }
577 dvb_dmxdev_release(&pd_dvb->dmxdev);
578 dvb_unregister_frontend(&pd_dvb->dvb_fe);
579 dvb_unregister_adapter(&pd_dvb->dvb_adap);
580 pd_dvb_usb_device_cleanup(pd);
581}
582
583void pd_dvb_usb_device_cleanup(struct poseidon *pd)
584{
585 struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
586
587 dvb_urb_cleanup(pd_dvb);
588}
589
590int pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb)
591{
592 return pd_dvb->dvb_adap.num;
593}
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c
new file mode 100644
index 000000000000..2cf0ebf9f28b
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-main.c
@@ -0,0 +1,539 @@
1/*
2 * device driver for Telegent tlg2300 based TV cards
3 *
4 * Author :
5 * Kang Yong <kangyong@telegent.com>
6 * Zhang Xiaobing <xbzhang@telegent.com>
7 * Huang Shijie <zyziii@telegent.com> or <shijie8@gmail.com>
8 *
9 * (c) 2009 Telegent Systems
10 * (c) 2010 Telegent Systems
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/version.h>
28#include <linux/kernel.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/module.h>
33#include <linux/kref.h>
34#include <linux/suspend.h>
35#include <linux/usb/quirks.h>
36#include <linux/ctype.h>
37#include <linux/string.h>
38#include <linux/types.h>
39#include <linux/firmware.h>
40#include <linux/smp_lock.h>
41
42#include "vendorcmds.h"
43#include "pd-common.h"
44
45#define VENDOR_ID 0x1B24
46#define PRODUCT_ID 0x4001
47static struct usb_device_id id_table[] = {
48 { USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 0) },
49 { USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ID, PRODUCT_ID, 255, 1, 1) },
50 { },
51};
52MODULE_DEVICE_TABLE(usb, id_table);
53
54int debug_mode;
55module_param(debug_mode, int, 0644);
56MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose");
57
58const char *firmware_name = "tlg2300_firmware.bin";
59struct usb_driver poseidon_driver;
60static LIST_HEAD(pd_device_list);
61
62/*
63 * send set request to USB firmware.
64 */
65s32 send_set_req(struct poseidon *pd, u8 cmdid, s32 param, s32 *cmd_status)
66{
67 s32 ret;
68 s8 data[32] = {};
69 u16 lower_16, upper_16;
70
71 if (pd->state & POSEIDON_STATE_DISCONNECT)
72 return -ENODEV;
73
74 mdelay(30);
75
76 if (param == 0) {
77 upper_16 = lower_16 = 0;
78 } else {
79 /* send 32 bit param as two 16 bit param,little endian */
80 lower_16 = (unsigned short)(param & 0xffff);
81 upper_16 = (unsigned short)((param >> 16) & 0xffff);
82 }
83 ret = usb_control_msg(pd->udev,
84 usb_rcvctrlpipe(pd->udev, 0),
85 REQ_SET_CMD | cmdid,
86 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
87 lower_16,
88 upper_16,
89 &data,
90 sizeof(*cmd_status),
91 USB_CTRL_GET_TIMEOUT);
92
93 if (!ret) {
94 return -ENXIO;
95 } else {
96 /* 1st 4 bytes into cmd_status */
97 memcpy((char *)cmd_status, &(data[0]), sizeof(*cmd_status));
98 }
99 return 0;
100}
101
102/*
103 * send get request to Poseidon firmware.
104 */
105s32 send_get_req(struct poseidon *pd, u8 cmdid, s32 param,
106 void *buf, s32 *cmd_status, s32 datalen)
107{
108 s32 ret;
109 s8 data[128] = {};
110 u16 lower_16, upper_16;
111
112 if (pd->state & POSEIDON_STATE_DISCONNECT)
113 return -ENODEV;
114
115 mdelay(30);
116 if (param == 0) {
117 upper_16 = lower_16 = 0;
118 } else {
119 /*send 32 bit param as two 16 bit param, little endian */
120 lower_16 = (unsigned short)(param & 0xffff);
121 upper_16 = (unsigned short)((param >> 16) & 0xffff);
122 }
123 ret = usb_control_msg(pd->udev,
124 usb_rcvctrlpipe(pd->udev, 0),
125 REQ_GET_CMD | cmdid,
126 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
127 lower_16,
128 upper_16,
129 &data,
130 (datalen + sizeof(*cmd_status)),
131 USB_CTRL_GET_TIMEOUT);
132
133 if (ret < 0) {
134 return -ENXIO;
135 } else {
136 /* 1st 4 bytes into cmd_status, remaining data into cmd_data */
137 memcpy((char *)cmd_status, &data[0], sizeof(*cmd_status));
138 memcpy((char *)buf, &data[sizeof(*cmd_status)], datalen);
139 }
140 return 0;
141}
142
143static int pm_notifier_block(struct notifier_block *nb,
144 unsigned long event, void *dummy)
145{
146 struct poseidon *pd = NULL;
147 struct list_head *node, *next;
148
149 switch (event) {
150 case PM_POST_HIBERNATION:
151 list_for_each_safe(node, next, &pd_device_list) {
152 struct usb_device *udev;
153 struct usb_interface *iface;
154 int rc = 0;
155
156 pd = container_of(node, struct poseidon, device_list);
157 udev = pd->udev;
158 iface = pd->interface;
159
160 /* It will cause the system to reload the firmware */
161 rc = usb_lock_device_for_reset(udev, iface);
162 if (rc >= 0) {
163 usb_reset_device(udev);
164 usb_unlock_device(udev);
165 }
166 }
167 break;
168 default:
169 break;
170 }
171 log("event :%ld\n", event);
172 return 0;
173}
174
175static struct notifier_block pm_notifer = {
176 .notifier_call = pm_notifier_block,
177};
178
179int set_tuner_mode(struct poseidon *pd, unsigned char mode)
180{
181 s32 ret, cmd_status;
182
183 if (pd->state & POSEIDON_STATE_DISCONNECT)
184 return -ENODEV;
185
186 ret = send_set_req(pd, TUNE_MODE_SELECT, mode, &cmd_status);
187 if (ret || cmd_status)
188 return -ENXIO;
189 return 0;
190}
191
192void poseidon_delete(struct kref *kref)
193{
194 struct poseidon *pd = container_of(kref, struct poseidon, kref);
195
196 if (!pd)
197 return;
198 list_del_init(&pd->device_list);
199
200 pd_dvb_usb_device_cleanup(pd);
201 /* clean_audio_data(&pd->audio_data);*/
202
203 if (pd->udev) {
204 usb_put_dev(pd->udev);
205 pd->udev = NULL;
206 }
207 if (pd->interface) {
208 usb_put_intf(pd->interface);
209 pd->interface = NULL;
210 }
211 kfree(pd);
212 log();
213}
214
215static int firmware_download(struct usb_device *udev)
216{
217 int ret = 0, actual_length;
218 const struct firmware *fw = NULL;
219 void *fwbuf = NULL;
220 size_t fwlength = 0, offset;
221 size_t max_packet_size;
222
223 ret = request_firmware(&fw, firmware_name, &udev->dev);
224 if (ret) {
225 log("download err : %d", ret);
226 return ret;
227 }
228
229 fwlength = fw->size;
230
231 fwbuf = kzalloc(fwlength, GFP_KERNEL);
232 if (!fwbuf) {
233 ret = -ENOMEM;
234 goto out;
235 }
236 memcpy(fwbuf, fw->data, fwlength);
237
238 max_packet_size = udev->ep_out[0x1]->desc.wMaxPacketSize;
239 log("\t\t download size : %d", (int)max_packet_size);
240
241 for (offset = 0; offset < fwlength; offset += max_packet_size) {
242 actual_length = 0;
243 ret = usb_bulk_msg(udev,
244 usb_sndbulkpipe(udev, 0x01), /* ep 1 */
245 fwbuf + offset,
246 min(max_packet_size, fwlength - offset),
247 &actual_length,
248 HZ * 10);
249 if (ret)
250 break;
251 }
252 kfree(fwbuf);
253out:
254 release_firmware(fw);
255 return ret;
256}
257
258static inline struct poseidon *get_pd(struct usb_interface *intf)
259{
260 return usb_get_intfdata(intf);
261}
262
263#ifdef CONFIG_PM
264/* one-to-one map : poseidon{} <----> usb_device{}'s port */
265static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
266{
267 pd->portnum = udev->portnum;
268}
269
270static inline int get_autopm_ref(struct poseidon *pd)
271{
272 return pd->video_data.users + pd->vbi_data.users + pd->audio.users
273 + atomic_read(&pd->dvb_data.users) + pd->radio_data.users;
274}
275
276/* fixup something for poseidon */
277static inline struct poseidon *fixup(struct poseidon *pd)
278{
279 int count;
280
281 /* old udev and interface have gone, so put back reference . */
282 count = get_autopm_ref(pd);
283 log("count : %d, ref count : %d", count, get_pm_count(pd));
284 while (count--)
285 usb_autopm_put_interface(pd->interface);
286 /*usb_autopm_set_interface(pd->interface); */
287
288 usb_put_dev(pd->udev);
289 usb_put_intf(pd->interface);
290 log("event : %d\n", pd->msg.event);
291 return pd;
292}
293
294static struct poseidon *find_old_poseidon(struct usb_device *udev)
295{
296 struct poseidon *pd;
297
298 list_for_each_entry(pd, &pd_device_list, device_list) {
299 if (pd->portnum == udev->portnum && in_hibernation(pd))
300 return fixup(pd);
301 }
302 return NULL;
303}
304
305/* Is the card working now ? */
306static inline int is_working(struct poseidon *pd)
307{
308 return get_pm_count(pd) > 0;
309}
310
311static int poseidon_suspend(struct usb_interface *intf, pm_message_t msg)
312{
313 struct poseidon *pd = get_pd(intf);
314
315 if (!pd)
316 return 0;
317 if (!is_working(pd)) {
318 if (get_pm_count(pd) <= 0 && !in_hibernation(pd)) {
319 pd->msg.event = PM_EVENT_AUTO_SUSPEND;
320 pd->pm_resume = NULL; /* a good guard */
321 printk(KERN_DEBUG "\n\t+ TLG2300 auto suspend +\n\n");
322 }
323 return 0;
324 }
325 pd->msg = msg; /* save it here */
326 logpm(pd);
327 return pd->pm_suspend ? pd->pm_suspend(pd) : 0;
328}
329
330static int poseidon_resume(struct usb_interface *intf)
331{
332 struct poseidon *pd = get_pd(intf);
333
334 if (!pd)
335 return 0;
336 printk(KERN_DEBUG "\n\t ++ TLG2300 resume ++\n\n");
337
338 if (!is_working(pd)) {
339 if (PM_EVENT_AUTO_SUSPEND == pd->msg.event)
340 pd->msg = PMSG_ON;
341 return 0;
342 }
343 if (in_hibernation(pd)) {
344 logpm(pd);
345 return 0;
346 }
347 logpm(pd);
348 return pd->pm_resume ? pd->pm_resume(pd) : 0;
349}
350
351static void hibernation_resume(struct work_struct *w)
352{
353 struct poseidon *pd = container_of(w, struct poseidon, pm_work);
354 int count;
355
356 pd->msg.event = 0; /* clear it here */
357 pd->state &= ~POSEIDON_STATE_DISCONNECT;
358
359 /* set the new interface's reference */
360 count = get_autopm_ref(pd);
361 while (count--)
362 usb_autopm_get_interface(pd->interface);
363
364 /* resume the context */
365 logpm(pd);
366 if (pd->pm_resume)
367 pd->pm_resume(pd);
368}
369#else /* CONFIG_PM is not enabled: */
370static inline struct poseidon *find_old_poseidon(struct usb_device *udev)
371{
372 return NULL;
373}
374
375static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev)
376{
377}
378#endif
379
380static bool check_firmware(struct usb_device *udev, int *down_firmware)
381{
382 void *buf;
383 int ret;
384 struct cmd_firmware_vers_s *cmd_firm;
385
386 buf = kzalloc(sizeof(*cmd_firm) + sizeof(u32), GFP_KERNEL);
387 if (!buf)
388 return -ENOMEM;
389 ret = usb_control_msg(udev,
390 usb_rcvctrlpipe(udev, 0),
391 REQ_GET_CMD | GET_FW_ID,
392 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
393 0,
394 0,
395 buf,
396 sizeof(*cmd_firm) + sizeof(u32),
397 USB_CTRL_GET_TIMEOUT);
398 kfree(buf);
399
400 if (ret < 0) {
401 *down_firmware = 1;
402 return firmware_download(udev);
403 }
404 return ret;
405}
406
407static int poseidon_probe(struct usb_interface *interface,
408 const struct usb_device_id *id)
409{
410 struct usb_device *udev = interface_to_usbdev(interface);
411 struct poseidon *pd = NULL;
412 int ret = 0;
413 int new_one = 0;
414
415 /* download firmware */
416 check_firmware(udev, &ret);
417 if (ret)
418 return 0;
419
420 /* Do I recovery from the hibernate ? */
421 pd = find_old_poseidon(udev);
422 if (!pd) {
423 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
424 if (!pd)
425 return -ENOMEM;
426 kref_init(&pd->kref);
427 set_map_flags(pd, udev);
428 new_one = 1;
429 }
430
431 pd->udev = usb_get_dev(udev);
432 pd->interface = usb_get_intf(interface);
433 usb_set_intfdata(interface, pd);
434
435 if (new_one) {
436 struct device *dev = &interface->dev;
437
438 logpm(pd);
439 mutex_init(&pd->lock);
440
441 /* register v4l2 device */
442 snprintf(pd->v4l2_dev.name, sizeof(pd->v4l2_dev.name), "%s %s",
443 dev->driver->name, dev_name(dev));
444 ret = v4l2_device_register(NULL, &pd->v4l2_dev);
445
446 /* register devices in directory /dev */
447 ret = pd_video_init(pd);
448 poseidon_audio_init(pd);
449 poseidon_fm_init(pd);
450 pd_dvb_usb_device_init(pd);
451
452 INIT_LIST_HEAD(&pd->device_list);
453 list_add_tail(&pd->device_list, &pd_device_list);
454 }
455
456 device_init_wakeup(&udev->dev, 1);
457#ifdef CONFIG_PM
458 pd->udev->autosuspend_disabled = 0;
459 pd->udev->autosuspend_delay = HZ * PM_SUSPEND_DELAY;
460
461 if (in_hibernation(pd)) {
462 INIT_WORK(&pd->pm_work, hibernation_resume);
463 schedule_work(&pd->pm_work);
464 }
465#endif
466 return 0;
467}
468
469static void poseidon_disconnect(struct usb_interface *interface)
470{
471 struct poseidon *pd = get_pd(interface);
472
473 if (!pd)
474 return;
475 logpm(pd);
476 if (in_hibernation(pd))
477 return;
478
479 mutex_lock(&pd->lock);
480 pd->state |= POSEIDON_STATE_DISCONNECT;
481 mutex_unlock(&pd->lock);
482
483 /* stop urb transferring */
484 stop_all_video_stream(pd);
485 dvb_stop_streaming(&pd->dvb_data);
486
487 /*unregister v4l2 device */
488 v4l2_device_unregister(&pd->v4l2_dev);
489
490 lock_kernel();
491 {
492 pd_dvb_usb_device_exit(pd);
493 poseidon_fm_exit(pd);
494
495 poseidon_audio_free(pd);
496 pd_video_exit(pd);
497 }
498 unlock_kernel();
499
500 usb_set_intfdata(interface, NULL);
501 kref_put(&pd->kref, poseidon_delete);
502}
503
504struct usb_driver poseidon_driver = {
505 .name = "poseidon",
506 .probe = poseidon_probe,
507 .disconnect = poseidon_disconnect,
508 .id_table = id_table,
509#ifdef CONFIG_PM
510 .suspend = poseidon_suspend,
511 .resume = poseidon_resume,
512#endif
513 .supports_autosuspend = 1,
514};
515
516static int __init poseidon_init(void)
517{
518 int ret;
519
520 ret = usb_register(&poseidon_driver);
521 if (ret)
522 return ret;
523 register_pm_notifier(&pm_notifer);
524 return ret;
525}
526
527static void __exit poseidon_exit(void)
528{
529 log();
530 unregister_pm_notifier(&pm_notifer);
531 usb_deregister(&poseidon_driver);
532}
533
534module_init(poseidon_init);
535module_exit(poseidon_exit);
536
537MODULE_AUTHOR("Telegent Systems");
538MODULE_DESCRIPTION("For tlg2300-based USB device ");
539MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tlg2300/pd-radio.c b/drivers/media/video/tlg2300/pd-radio.c
new file mode 100644
index 000000000000..755766b15157
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-radio.c
@@ -0,0 +1,420 @@
1#include <linux/init.h>
2#include <linux/list.h>
3#include <linux/module.h>
4#include <linux/kernel.h>
5#include <linux/bitmap.h>
6#include <linux/usb.h>
7#include <linux/i2c.h>
8#include <media/v4l2-dev.h>
9#include <linux/version.h>
10#include <linux/mm.h>
11#include <linux/mutex.h>
12#include <media/v4l2-ioctl.h>
13#include <linux/sched.h>
14
15#include "pd-common.h"
16#include "vendorcmds.h"
17
18static int set_frequency(struct poseidon *p, __u32 frequency);
19static int poseidon_fm_close(struct file *filp);
20static int poseidon_fm_open(struct file *filp);
21
22#define TUNER_FREQ_MIN_FM 76000000
23#define TUNER_FREQ_MAX_FM 108000000
24
25#define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1)
26static int preemphasis[MAX_PREEMPHASIS] = {
27 TLG_TUNE_ASTD_NONE, /* V4L2_PREEMPHASIS_DISABLED */
28 TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS */
29 TLG_TUNE_ASTD_FM_US, /* V4L2_PREEMPHASIS_75_uS */
30};
31
32static int poseidon_check_mode_radio(struct poseidon *p)
33{
34 int ret;
35 u32 status;
36
37 set_current_state(TASK_INTERRUPTIBLE);
38 schedule_timeout(HZ/2);
39 ret = usb_set_interface(p->udev, 0, BULK_ALTERNATE_IFACE);
40 if (ret < 0)
41 goto out;
42
43 ret = set_tuner_mode(p, TLG_MODE_FM_RADIO);
44 if (ret != 0)
45 goto out;
46
47 ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status);
48 ret = send_set_req(p, TUNER_AUD_ANA_STD,
49 p->radio_data.pre_emphasis, &status);
50 ret |= send_set_req(p, TUNER_AUD_MODE,
51 TLG_TUNE_TVAUDIO_MODE_STEREO, &status);
52 ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL,
53 ATV_AUDIO_RATE_48K, &status);
54 ret |= send_set_req(p, TUNE_FREQ_SELECT, TUNER_FREQ_MIN_FM, &status);
55out:
56 return ret;
57}
58
59#ifdef CONFIG_PM
60static int pm_fm_suspend(struct poseidon *p)
61{
62 logpm(p);
63 pm_alsa_suspend(p);
64 usb_set_interface(p->udev, 0, 0);
65 msleep(300);
66 return 0;
67}
68
69static int pm_fm_resume(struct poseidon *p)
70{
71 logpm(p);
72 poseidon_check_mode_radio(p);
73 set_frequency(p, p->radio_data.fm_freq);
74 pm_alsa_resume(p);
75 return 0;
76}
77#endif
78
79static int poseidon_fm_open(struct file *filp)
80{
81 struct video_device *vfd = video_devdata(filp);
82 struct poseidon *p = video_get_drvdata(vfd);
83 int ret = 0;
84
85 if (!p)
86 return -1;
87
88 mutex_lock(&p->lock);
89 if (p->state & POSEIDON_STATE_DISCONNECT) {
90 ret = -ENODEV;
91 goto out;
92 }
93
94 if (p->state && !(p->state & POSEIDON_STATE_FM)) {
95 ret = -EBUSY;
96 goto out;
97 }
98
99 usb_autopm_get_interface(p->interface);
100 if (0 == p->state) {
101 /* default pre-emphasis */
102 if (p->radio_data.pre_emphasis == 0)
103 p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR;
104 set_debug_mode(vfd, debug_mode);
105
106 ret = poseidon_check_mode_radio(p);
107 if (ret < 0) {
108 usb_autopm_put_interface(p->interface);
109 goto out;
110 }
111 p->state |= POSEIDON_STATE_FM;
112 }
113 p->radio_data.users++;
114 kref_get(&p->kref);
115 filp->private_data = p;
116out:
117 mutex_unlock(&p->lock);
118 return ret;
119}
120
121static int poseidon_fm_close(struct file *filp)
122{
123 struct poseidon *p = filp->private_data;
124 struct radio_data *fm = &p->radio_data;
125 uint32_t status;
126
127 mutex_lock(&p->lock);
128 fm->users--;
129 if (0 == fm->users)
130 p->state &= ~POSEIDON_STATE_FM;
131
132 if (fm->is_radio_streaming && filp == p->file_for_stream) {
133 fm->is_radio_streaming = 0;
134 send_set_req(p, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, &status);
135 }
136 usb_autopm_put_interface(p->interface);
137 mutex_unlock(&p->lock);
138
139 kref_put(&p->kref, poseidon_delete);
140 filp->private_data = NULL;
141 return 0;
142}
143
144static int vidioc_querycap(struct file *file, void *priv,
145 struct v4l2_capability *v)
146{
147 struct poseidon *p = file->private_data;
148
149 strlcpy(v->driver, "tele-radio", sizeof(v->driver));
150 strlcpy(v->card, "Telegent Poseidon", sizeof(v->card));
151 usb_make_path(p->udev, v->bus_info, sizeof(v->bus_info));
152 v->version = KERNEL_VERSION(0, 0, 1);
153 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
154 return 0;
155}
156
157static const struct v4l2_file_operations poseidon_fm_fops = {
158 .owner = THIS_MODULE,
159 .open = poseidon_fm_open,
160 .release = poseidon_fm_close,
161 .ioctl = video_ioctl2,
162};
163
164int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
165{
166 struct tuner_fm_sig_stat_s fm_stat = {};
167 int ret, status, count = 5;
168 struct poseidon *p = file->private_data;
169
170 if (vt->index != 0)
171 return -EINVAL;
172
173 vt->type = V4L2_TUNER_RADIO;
174 vt->capability = V4L2_TUNER_CAP_STEREO;
175 vt->rangelow = TUNER_FREQ_MIN_FM / 62500;
176 vt->rangehigh = TUNER_FREQ_MAX_FM / 62500;
177 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
178 vt->audmode = V4L2_TUNER_MODE_STEREO;
179 vt->signal = 0;
180 vt->afc = 0;
181
182 mutex_lock(&p->lock);
183 ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
184 &fm_stat, &status, sizeof(fm_stat));
185
186 while (fm_stat.sig_lock_busy && count-- && !ret) {
187 set_current_state(TASK_INTERRUPTIBLE);
188 schedule_timeout(HZ);
189
190 ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO,
191 &fm_stat, &status, sizeof(fm_stat));
192 }
193 mutex_unlock(&p->lock);
194
195 if (ret || status) {
196 vt->signal = 0;
197 } else if ((fm_stat.sig_present || fm_stat.sig_locked)
198 && fm_stat.sig_strength == 0) {
199 vt->signal = 0xffff;
200 } else
201 vt->signal = (fm_stat.sig_strength * 255 / 10) << 8;
202
203 return 0;
204}
205
206int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
207{
208 struct poseidon *p = file->private_data;
209
210 argp->frequency = p->radio_data.fm_freq;
211 return 0;
212}
213
214static int set_frequency(struct poseidon *p, __u32 frequency)
215{
216 __u32 freq ;
217 int ret, status;
218
219 mutex_lock(&p->lock);
220
221 ret = send_set_req(p, TUNER_AUD_ANA_STD,
222 p->radio_data.pre_emphasis, &status);
223
224 freq = (frequency * 125) * 500 / 1000;/* kHZ */
225 if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) {
226 ret = -EINVAL;
227 goto error;
228 }
229
230 ret = send_set_req(p, TUNE_FREQ_SELECT, freq, &status);
231 if (ret < 0)
232 goto error ;
233 ret = send_set_req(p, TAKE_REQUEST, 0, &status);
234
235 set_current_state(TASK_INTERRUPTIBLE);
236 schedule_timeout(HZ/4);
237 if (!p->radio_data.is_radio_streaming) {
238 ret = send_set_req(p, TAKE_REQUEST, 0, &status);
239 ret = send_set_req(p, PLAY_SERVICE,
240 TLG_TUNE_PLAY_SVC_START, &status);
241 p->radio_data.is_radio_streaming = 1;
242 }
243 p->radio_data.fm_freq = frequency;
244error:
245 mutex_unlock(&p->lock);
246 return ret;
247}
248
249int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
250{
251 struct poseidon *p = file->private_data;
252
253 p->file_for_stream = file;
254#ifdef CONFIG_PM
255 p->pm_suspend = pm_fm_suspend;
256 p->pm_resume = pm_fm_resume;
257#endif
258 return set_frequency(p, argp->frequency);
259}
260
261int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
262 struct v4l2_control *arg)
263{
264 return 0;
265}
266
267int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
268 struct v4l2_ext_controls *ctrls)
269{
270 struct poseidon *p = file->private_data;
271 int i;
272
273 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
274 return -EINVAL;
275
276 for (i = 0; i < ctrls->count; i++) {
277 struct v4l2_ext_control *ctrl = ctrls->controls + i;
278
279 if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
280 continue;
281
282 if (i < MAX_PREEMPHASIS)
283 ctrl->value = p->radio_data.pre_emphasis;
284 }
285 return 0;
286}
287
288int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
289 struct v4l2_ext_controls *ctrls)
290{
291 int i;
292
293 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
294 return -EINVAL;
295
296 for (i = 0; i < ctrls->count; i++) {
297 struct v4l2_ext_control *ctrl = ctrls->controls + i;
298
299 if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS)
300 continue;
301
302 if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) {
303 struct poseidon *p = file->private_data;
304 int pre_emphasis = preemphasis[ctrl->value];
305 u32 status;
306
307 send_set_req(p, TUNER_AUD_ANA_STD,
308 pre_emphasis, &status);
309 p->radio_data.pre_emphasis = pre_emphasis;
310 }
311 }
312 return 0;
313}
314
315int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
316 struct v4l2_control *ctrl)
317{
318 return 0;
319}
320
321int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
322 struct v4l2_queryctrl *ctrl)
323{
324 if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
325 return -EINVAL;
326
327 ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
328 if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) {
329 /* return the next supported control */
330 ctrl->id = V4L2_CID_TUNE_PREEMPHASIS;
331 v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED,
332 V4L2_PREEMPHASIS_75_uS, 1,
333 V4L2_PREEMPHASIS_50_uS);
334 ctrl->flags = V4L2_CTRL_FLAG_UPDATE;
335 return 0;
336 }
337 return -EINVAL;
338}
339
340int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
341 struct v4l2_querymenu *qmenu)
342{
343 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
344}
345
346static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
347{
348 return vt->index > 0 ? -EINVAL : 0;
349}
350static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *va)
351{
352 return (va->index != 0) ? -EINVAL : 0;
353}
354
355static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
356{
357 a->index = 0;
358 a->mode = 0;
359 a->capability = V4L2_AUDCAP_STEREO;
360 strcpy(a->name, "Radio");
361 return 0;
362}
363
364static int vidioc_s_input(struct file *filp, void *priv, u32 i)
365{
366 return (i != 0) ? -EINVAL : 0;
367}
368
369static int vidioc_g_input(struct file *filp, void *priv, u32 *i)
370{
371 return (*i != 0) ? -EINVAL : 0;
372}
373
374static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = {
375 .vidioc_querycap = vidioc_querycap,
376 .vidioc_g_audio = vidioc_g_audio,
377 .vidioc_s_audio = vidioc_s_audio,
378 .vidioc_g_input = vidioc_g_input,
379 .vidioc_s_input = vidioc_s_input,
380 .vidioc_queryctrl = tlg_fm_vidioc_queryctrl,
381 .vidioc_querymenu = tlg_fm_vidioc_querymenu,
382 .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl,
383 .vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl,
384 .vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl,
385 .vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl,
386 .vidioc_s_tuner = vidioc_s_tuner,
387 .vidioc_g_tuner = tlg_fm_vidioc_g_tuner,
388 .vidioc_g_frequency = fm_get_freq,
389 .vidioc_s_frequency = fm_set_freq,
390};
391
392static struct video_device poseidon_fm_template = {
393 .name = "Telegent-Radio",
394 .fops = &poseidon_fm_fops,
395 .minor = -1,
396 .release = video_device_release,
397 .ioctl_ops = &poseidon_fm_ioctl_ops,
398};
399
400int poseidon_fm_init(struct poseidon *p)
401{
402 struct video_device *fm_dev;
403
404 fm_dev = vdev_init(p, &poseidon_fm_template);
405 if (fm_dev == NULL)
406 return -1;
407
408 if (video_register_device(fm_dev, VFL_TYPE_RADIO, -1) < 0) {
409 video_device_release(fm_dev);
410 return -1;
411 }
412 p->radio_data.fm_dev = fm_dev;
413 return 0;
414}
415
416int poseidon_fm_exit(struct poseidon *p)
417{
418 destroy_video_device(&p->radio_data.fm_dev);
419 return 0;
420}
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
new file mode 100644
index 000000000000..becfba6a3041
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -0,0 +1,1667 @@
1#include <linux/fs.h>
2#include <linux/vmalloc.h>
3#include <linux/videodev2.h>
4#include <linux/usb.h>
5#include <linux/mm.h>
6#include <linux/sched.h>
7
8#include <media/v4l2-ioctl.h>
9#include <media/v4l2-dev.h>
10
11#include "pd-common.h"
12#include "vendorcmds.h"
13
14static int pm_video_suspend(struct poseidon *pd);
15static int pm_video_resume(struct poseidon *pd);
16static void iso_bubble_handler(struct work_struct *w);
17
18int usb_transfer_mode;
19module_param(usb_transfer_mode, int, 0644);
20MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous");
21
22static const struct poseidon_format poseidon_formats[] = {
23 { "YUV 422", V4L2_PIX_FMT_YUYV, 16, 0},
24 { "RGB565", V4L2_PIX_FMT_RGB565, 16, 0},
25};
26
27static const struct poseidon_tvnorm poseidon_tvnorms[] = {
28 { V4L2_STD_PAL_D, "PAL-D", TLG_TUNE_VSTD_PAL_D },
29 { V4L2_STD_PAL_B, "PAL-B", TLG_TUNE_VSTD_PAL_B },
30 { V4L2_STD_PAL_G, "PAL-G", TLG_TUNE_VSTD_PAL_G },
31 { V4L2_STD_PAL_H, "PAL-H", TLG_TUNE_VSTD_PAL_H },
32 { V4L2_STD_PAL_I, "PAL-I", TLG_TUNE_VSTD_PAL_I },
33 { V4L2_STD_PAL_M, "PAL-M", TLG_TUNE_VSTD_PAL_M },
34 { V4L2_STD_PAL_N, "PAL-N", TLG_TUNE_VSTD_PAL_N_COMBO },
35 { V4L2_STD_PAL_Nc, "PAL-Nc", TLG_TUNE_VSTD_PAL_N_COMBO },
36 { V4L2_STD_NTSC_M, "NTSC-M", TLG_TUNE_VSTD_NTSC_M },
37 { V4L2_STD_NTSC_M_JP, "NTSC-JP", TLG_TUNE_VSTD_NTSC_M_J },
38 { V4L2_STD_SECAM_B, "SECAM-B", TLG_TUNE_VSTD_SECAM_B },
39 { V4L2_STD_SECAM_D, "SECAM-D", TLG_TUNE_VSTD_SECAM_D },
40 { V4L2_STD_SECAM_G, "SECAM-G", TLG_TUNE_VSTD_SECAM_G },
41 { V4L2_STD_SECAM_H, "SECAM-H", TLG_TUNE_VSTD_SECAM_H },
42 { V4L2_STD_SECAM_K, "SECAM-K", TLG_TUNE_VSTD_SECAM_K },
43 { V4L2_STD_SECAM_K1, "SECAM-K1", TLG_TUNE_VSTD_SECAM_K1 },
44 { V4L2_STD_SECAM_L, "SECAM-L", TLG_TUNE_VSTD_SECAM_L },
45 { V4L2_STD_SECAM_LC, "SECAM-LC", TLG_TUNE_VSTD_SECAM_L1 },
46};
47static const unsigned int POSEIDON_TVNORMS = ARRAY_SIZE(poseidon_tvnorms);
48
49struct pd_audio_mode {
50 u32 tlg_audio_mode;
51 u32 v4l2_audio_sub;
52 u32 v4l2_audio_mode;
53};
54
55static const struct pd_audio_mode pd_audio_modes[] = {
56 { TLG_TUNE_TVAUDIO_MODE_MONO, V4L2_TUNER_SUB_MONO,
57 V4L2_TUNER_MODE_MONO },
58 { TLG_TUNE_TVAUDIO_MODE_STEREO, V4L2_TUNER_SUB_STEREO,
59 V4L2_TUNER_MODE_STEREO },
60 { TLG_TUNE_TVAUDIO_MODE_LANG_A, V4L2_TUNER_SUB_LANG1,
61 V4L2_TUNER_MODE_LANG1 },
62 { TLG_TUNE_TVAUDIO_MODE_LANG_B, V4L2_TUNER_SUB_LANG2,
63 V4L2_TUNER_MODE_LANG2 },
64 { TLG_TUNE_TVAUDIO_MODE_LANG_C, V4L2_TUNER_SUB_LANG1,
65 V4L2_TUNER_MODE_LANG1_LANG2 }
66};
67static const unsigned int POSEIDON_AUDIOMODS = ARRAY_SIZE(pd_audio_modes);
68
69struct pd_input {
70 char *name;
71 uint32_t tlg_src;
72};
73
74static const struct pd_input pd_inputs[] = {
75 { "TV Antenna", TLG_SIG_SRC_ANTENNA },
76 { "TV Cable", TLG_SIG_SRC_CABLE },
77 { "TV SVideo", TLG_SIG_SRC_SVIDEO },
78 { "TV Composite", TLG_SIG_SRC_COMPOSITE }
79};
80static const unsigned int POSEIDON_INPUTS = ARRAY_SIZE(pd_inputs);
81
82struct poseidon_control {
83 struct v4l2_queryctrl v4l2_ctrl;
84 enum cmd_custom_param_id vc_id;
85};
86
87static struct poseidon_control controls[] = {
88 {
89 { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER,
90 "brightness", 0, 10000, 1, 100, 0, },
91 CUST_PARM_ID_BRIGHTNESS_CTRL
92 }, {
93 { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER,
94 "contrast", 0, 10000, 1, 100, 0, },
95 CUST_PARM_ID_CONTRAST_CTRL,
96 }, {
97 { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER,
98 "hue", 0, 10000, 1, 100, 0, },
99 CUST_PARM_ID_HUE_CTRL,
100 }, {
101 { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER,
102 "saturation", 0, 10000, 1, 100, 0, },
103 CUST_PARM_ID_SATURATION_CTRL,
104 },
105};
106
107struct video_std_to_audio_std {
108 v4l2_std_id video_std;
109 int audio_std;
110};
111
112static const struct video_std_to_audio_std video_to_audio_map[] = {
113 /* country : { 27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64,
114 65, 86, 351, 352, 353, 354, 358, 372, 852, 972 } */
115 { (V4L2_STD_PAL_I | V4L2_STD_PAL_B | V4L2_STD_PAL_D |
116 V4L2_STD_SECAM_L | V4L2_STD_SECAM_D), TLG_TUNE_ASTD_NICAM },
117
118 /* country : { 1, 52, 54, 55, 886 } */
119 {V4L2_STD_NTSC_M | V4L2_STD_PAL_N | V4L2_STD_PAL_M, TLG_TUNE_ASTD_BTSC},
120
121 /* country : { 81 } */
122 { V4L2_STD_NTSC_M_JP, TLG_TUNE_ASTD_EIAJ },
123
124 /* other country : TLG_TUNE_ASTD_A2 */
125};
126static const unsigned int map_size = ARRAY_SIZE(video_to_audio_map);
127
128static int get_audio_std(v4l2_std_id v4l2_std)
129{
130 int i = 0;
131
132 for (; i < map_size; i++) {
133 if (v4l2_std & video_to_audio_map[i].video_std)
134 return video_to_audio_map[i].audio_std;
135 }
136 return TLG_TUNE_ASTD_A2;
137}
138
139static int vidioc_querycap(struct file *file, void *fh,
140 struct v4l2_capability *cap)
141{
142 struct front_face *front = fh;
143 struct poseidon *p = front->pd;
144
145 logs(front);
146
147 strcpy(cap->driver, "tele-video");
148 strcpy(cap->card, "Telegent Poseidon");
149 usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info));
150 cap->version = KERNEL_VERSION(0, 0, 1);
151 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
152 V4L2_CAP_AUDIO | V4L2_CAP_STREAMING |
153 V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
154 return 0;
155}
156
157/*====================================================================*/
158static void init_copy(struct video_data *video, bool index)
159{
160 struct front_face *front = video->front;
161
162 video->field_count = index;
163 video->lines_copied = 0;
164 video->prev_left = 0 ;
165 video->dst = (char *)videobuf_to_vmalloc(front->curr_frame)
166 + index * video->lines_size;
167 video->vbi->copied = 0; /* set it here */
168}
169
170static bool get_frame(struct front_face *front, int *need_init)
171{
172 struct videobuf_buffer *vb = front->curr_frame;
173
174 if (vb)
175 return true;
176
177 spin_lock(&front->queue_lock);
178 if (!list_empty(&front->active)) {
179 vb = list_entry(front->active.next,
180 struct videobuf_buffer, queue);
181 if (need_init)
182 *need_init = 1;
183 front->curr_frame = vb;
184 list_del_init(&vb->queue);
185 }
186 spin_unlock(&front->queue_lock);
187
188 return !!vb;
189}
190
191/* check if the video's buffer is ready */
192static bool get_video_frame(struct front_face *front, struct video_data *video)
193{
194 int need_init = 0;
195 bool ret = true;
196
197 ret = get_frame(front, &need_init);
198 if (ret && need_init)
199 init_copy(video, 0);
200 return ret;
201}
202
203static void submit_frame(struct front_face *front)
204{
205 struct videobuf_buffer *vb = front->curr_frame;
206
207 if (vb == NULL)
208 return;
209
210 front->curr_frame = NULL;
211 vb->state = VIDEOBUF_DONE;
212 vb->field_count++;
213 do_gettimeofday(&vb->ts);
214
215 wake_up(&vb->done);
216}
217
218/*
219 * A frame is composed of two fields. If we receive all the two fields,
220 * call the submit_frame() to submit the whole frame to applications.
221 */
222static void end_field(struct video_data *video)
223{
224 /* logs(video->front); */
225 if (1 == video->field_count)
226 submit_frame(video->front);
227 else
228 init_copy(video, 1);
229}
230
231static void copy_video_data(struct video_data *video, char *src,
232 unsigned int count)
233{
234#define copy_data(len) \
235 do { \
236 if (++video->lines_copied > video->lines_per_field) \
237 goto overflow; \
238 memcpy(video->dst, src, len);\
239 video->dst += len + video->lines_size; \
240 src += len; \
241 count -= len; \
242 } while (0)
243
244 while (count && count >= video->lines_size) {
245 if (video->prev_left) {
246 copy_data(video->prev_left);
247 video->prev_left = 0;
248 continue;
249 }
250 copy_data(video->lines_size);
251 }
252 if (count && count < video->lines_size) {
253 memcpy(video->dst, src, count);
254
255 video->prev_left = video->lines_size - count;
256 video->dst += count;
257 }
258 return;
259
260overflow:
261 end_field(video);
262}
263
264static void check_trailer(struct video_data *video, char *src, int count)
265{
266 struct vbi_data *vbi = video->vbi;
267 int offset; /* trailer's offset */
268 char *buf;
269
270 offset = (video->context.pix.sizeimage / 2 + vbi->vbi_size / 2)
271 - (vbi->copied + video->lines_size * video->lines_copied);
272 if (video->prev_left)
273 offset -= (video->lines_size - video->prev_left);
274
275 if (offset > count || offset <= 0)
276 goto short_package;
277
278 buf = src + offset;
279
280 /* trailer : (VFHS) + U32 + U32 + field_num */
281 if (!strncmp(buf, "VFHS", 4)) {
282 int field_num = *((u32 *)(buf + 12));
283
284 if ((field_num & 1) ^ video->field_count) {
285 init_copy(video, video->field_count);
286 return;
287 }
288 copy_video_data(video, src, offset);
289 }
290short_package:
291 end_field(video);
292}
293
294/* ========== Check this more carefully! =========== */
295static inline void copy_vbi_data(struct vbi_data *vbi,
296 char *src, unsigned int count)
297{
298 struct front_face *front = vbi->front;
299
300 if (front && get_frame(front, NULL)) {
301 char *buf = videobuf_to_vmalloc(front->curr_frame);
302
303 if (vbi->video->field_count)
304 buf += (vbi->vbi_size / 2);
305 memcpy(buf + vbi->copied, src, count);
306 }
307 vbi->copied += count;
308}
309
310/*
311 * Copy the normal data (VBI or VIDEO) without the trailer.
312 * VBI is not interlaced, while VIDEO is interlaced.
313 */
314static inline void copy_vbi_video_data(struct video_data *video,
315 char *src, unsigned int count)
316{
317 struct vbi_data *vbi = video->vbi;
318 unsigned int vbi_delta = (vbi->vbi_size / 2) - vbi->copied;
319
320 if (vbi_delta >= count) {
321 copy_vbi_data(vbi, src, count);
322 } else {
323 if (vbi_delta) {
324 copy_vbi_data(vbi, src, vbi_delta);
325
326 /* we receive the two fields of the VBI*/
327 if (vbi->front && video->field_count)
328 submit_frame(vbi->front);
329 }
330 copy_video_data(video, src + vbi_delta, count - vbi_delta);
331 }
332}
333
334static void urb_complete_bulk(struct urb *urb)
335{
336 struct front_face *front = urb->context;
337 struct video_data *video = &front->pd->video_data;
338 char *src = (char *)urb->transfer_buffer;
339 int count = urb->actual_length;
340 int ret = 0;
341
342 if (!video->is_streaming || urb->status) {
343 if (urb->status == -EPROTO)
344 goto resend_it;
345 return;
346 }
347 if (!get_video_frame(front, video))
348 goto resend_it;
349
350 if (count == urb->transfer_buffer_length)
351 copy_vbi_video_data(video, src, count);
352 else
353 check_trailer(video, src, count);
354
355resend_it:
356 ret = usb_submit_urb(urb, GFP_ATOMIC);
357 if (ret)
358 log(" submit failed: error %d", ret);
359}
360
361/************************* for ISO *********************/
362#define GET_SUCCESS (0)
363#define GET_TRAILER (1)
364#define GET_TOO_MUCH_BUBBLE (2)
365#define GET_NONE (3)
366static int get_chunk(int start, struct urb *urb,
367 int *head, int *tail, int *bubble_err)
368{
369 struct usb_iso_packet_descriptor *pkt = NULL;
370 int ret = GET_SUCCESS;
371
372 for (*head = *tail = -1; start < urb->number_of_packets; start++) {
373 pkt = &urb->iso_frame_desc[start];
374
375 /* handle the bubble of the Hub */
376 if (-EOVERFLOW == pkt->status) {
377 if (++*bubble_err > urb->number_of_packets / 3)
378 return GET_TOO_MUCH_BUBBLE;
379 continue;
380 }
381
382 /* This is the gap */
383 if (pkt->status || pkt->actual_length <= 0
384 || pkt->actual_length > ISO_PKT_SIZE) {
385 if (*head != -1)
386 break;
387 continue;
388 }
389
390 /* a good isochronous packet */
391 if (pkt->actual_length == ISO_PKT_SIZE) {
392 if (*head == -1)
393 *head = start;
394 *tail = start;
395 continue;
396 }
397
398 /* trailer is here */
399 if (pkt->actual_length < ISO_PKT_SIZE) {
400 if (*head == -1) {
401 *head = start;
402 *tail = start;
403 return GET_TRAILER;
404 }
405 break;
406 }
407 }
408
409 if (*head == -1 && *tail == -1)
410 ret = GET_NONE;
411 return ret;
412}
413
414/*
415 * |__|------|___|-----|_______|
416 * ^ ^
417 * | |
418 * gap gap
419 */
420static void urb_complete_iso(struct urb *urb)
421{
422 struct front_face *front = urb->context;
423 struct video_data *video = &front->pd->video_data;
424 int bubble_err = 0, head = 0, tail = 0;
425 char *src = (char *)urb->transfer_buffer;
426 int ret = 0;
427
428 if (!video->is_streaming)
429 return;
430
431 do {
432 if (!get_video_frame(front, video))
433 goto out;
434
435 switch (get_chunk(head, urb, &head, &tail, &bubble_err)) {
436 case GET_SUCCESS:
437 copy_vbi_video_data(video, src + (head * ISO_PKT_SIZE),
438 (tail - head + 1) * ISO_PKT_SIZE);
439 break;
440 case GET_TRAILER:
441 check_trailer(video, src + (head * ISO_PKT_SIZE),
442 ISO_PKT_SIZE);
443 break;
444 case GET_NONE:
445 goto out;
446 case GET_TOO_MUCH_BUBBLE:
447 log("\t We got too much bubble");
448 schedule_work(&video->bubble_work);
449 return;
450 }
451 } while (head = tail + 1, head < urb->number_of_packets);
452
453out:
454 ret = usb_submit_urb(urb, GFP_ATOMIC);
455 if (ret)
456 log("usb_submit_urb err : %d", ret);
457}
458/*============================= [ end ] =====================*/
459
460static int prepare_iso_urb(struct video_data *video)
461{
462 struct usb_device *udev = video->pd->udev;
463 int i;
464
465 if (video->urb_array[0])
466 return 0;
467
468 for (i = 0; i < SBUF_NUM; i++) {
469 struct urb *urb;
470 void *mem;
471 int j;
472
473 urb = usb_alloc_urb(PK_PER_URB, GFP_KERNEL);
474 if (urb == NULL)
475 goto out;
476
477 video->urb_array[i] = urb;
478 mem = usb_buffer_alloc(udev,
479 ISO_PKT_SIZE * PK_PER_URB,
480 GFP_KERNEL,
481 &urb->transfer_dma);
482
483 urb->complete = urb_complete_iso; /* handler */
484 urb->dev = udev;
485 urb->context = video->front;
486 urb->pipe = usb_rcvisocpipe(udev,
487 video->endpoint_addr);
488 urb->interval = 1;
489 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
490 urb->number_of_packets = PK_PER_URB;
491 urb->transfer_buffer = mem;
492 urb->transfer_buffer_length = PK_PER_URB * ISO_PKT_SIZE;
493
494 for (j = 0; j < PK_PER_URB; j++) {
495 urb->iso_frame_desc[j].offset = ISO_PKT_SIZE * j;
496 urb->iso_frame_desc[j].length = ISO_PKT_SIZE;
497 }
498 }
499 return 0;
500out:
501 for (; i > 0; i--)
502 ;
503 return -ENOMEM;
504}
505
506/* return the succeeded number of the allocation */
507int alloc_bulk_urbs_generic(struct urb **urb_array, int num,
508 struct usb_device *udev, u8 ep_addr,
509 int buf_size, gfp_t gfp_flags,
510 usb_complete_t complete_fn, void *context)
511{
512 struct urb *urb;
513 void *mem;
514 int i;
515
516 for (i = 0; i < num; i++) {
517 urb = usb_alloc_urb(0, gfp_flags);
518 if (urb == NULL)
519 return i;
520
521 mem = usb_buffer_alloc(udev, buf_size, gfp_flags,
522 &urb->transfer_dma);
523 if (mem == NULL)
524 return i;
525
526 usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, ep_addr),
527 mem, buf_size, complete_fn, context);
528 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
529 urb_array[i] = urb;
530 }
531 return i;
532}
533
534void free_all_urb_generic(struct urb **urb_array, int num)
535{
536 int i;
537 struct urb *urb;
538
539 for (i = 0; i < num; i++) {
540 urb = urb_array[i];
541 if (urb) {
542 usb_buffer_free(urb->dev,
543 urb->transfer_buffer_length,
544 urb->transfer_buffer,
545 urb->transfer_dma);
546 usb_free_urb(urb);
547 urb_array[i] = NULL;
548 }
549 }
550}
551
552static int prepare_bulk_urb(struct video_data *video)
553{
554 if (video->urb_array[0])
555 return 0;
556
557 alloc_bulk_urbs_generic(video->urb_array, SBUF_NUM,
558 video->pd->udev, video->endpoint_addr,
559 0x2000, GFP_KERNEL,
560 urb_complete_bulk, video->front);
561 return 0;
562}
563
564/* free the URBs */
565static void free_all_urb(struct video_data *video)
566{
567 free_all_urb_generic(video->urb_array, SBUF_NUM);
568}
569
570static void pd_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
571{
572 videobuf_vmalloc_free(vb);
573 vb->state = VIDEOBUF_NEEDS_INIT;
574}
575
576static void pd_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
577{
578 struct front_face *front = q->priv_data;
579 vb->state = VIDEOBUF_QUEUED;
580 list_add_tail(&vb->queue, &front->active);
581}
582
583static int pd_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
584 enum v4l2_field field)
585{
586 struct front_face *front = q->priv_data;
587 int rc;
588
589 switch (front->type) {
590 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
591 if (VIDEOBUF_NEEDS_INIT == vb->state) {
592 struct v4l2_pix_format *pix;
593
594 pix = &front->pd->video_data.context.pix;
595 vb->size = pix->sizeimage; /* real frame size */
596 vb->width = pix->width;
597 vb->height = pix->height;
598 rc = videobuf_iolock(q, vb, NULL);
599 if (rc < 0)
600 return rc;
601 }
602 break;
603 case V4L2_BUF_TYPE_VBI_CAPTURE:
604 if (VIDEOBUF_NEEDS_INIT == vb->state) {
605 vb->size = front->pd->vbi_data.vbi_size;
606 rc = videobuf_iolock(q, vb, NULL);
607 if (rc < 0)
608 return rc;
609 }
610 break;
611 default:
612 return -EINVAL;
613 }
614 vb->field = field;
615 vb->state = VIDEOBUF_PREPARED;
616 return 0;
617}
618
619int fire_all_urb(struct video_data *video)
620{
621 int i, ret;
622
623 video->is_streaming = 1;
624
625 for (i = 0; i < SBUF_NUM; i++) {
626 ret = usb_submit_urb(video->urb_array[i], GFP_KERNEL);
627 if (ret)
628 log("(%d) failed: error %d", i, ret);
629 }
630 return ret;
631}
632
633static int start_video_stream(struct poseidon *pd)
634{
635 struct video_data *video = &pd->video_data;
636 s32 cmd_status;
637
638 send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
639 send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_START, &cmd_status);
640
641 if (pd->cur_transfer_mode) {
642 prepare_iso_urb(video);
643 INIT_WORK(&video->bubble_work, iso_bubble_handler);
644 } else {
645 /* The bulk mode does not need a bubble handler */
646 prepare_bulk_urb(video);
647 }
648 fire_all_urb(video);
649 return 0;
650}
651
652static int pd_buf_setup(struct videobuf_queue *q, unsigned int *count,
653 unsigned int *size)
654{
655 struct front_face *front = q->priv_data;
656 struct poseidon *pd = front->pd;
657
658 switch (front->type) {
659 default:
660 return -EINVAL;
661 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
662 struct video_data *video = &pd->video_data;
663 struct v4l2_pix_format *pix = &video->context.pix;
664
665 *size = PAGE_ALIGN(pix->sizeimage);/* page aligned frame size */
666 if (*count < 4)
667 *count = 4;
668 if (1) {
669 /* same in different altersetting */
670 video->endpoint_addr = 0x82;
671 video->vbi = &pd->vbi_data;
672 video->vbi->video = video;
673 video->pd = pd;
674 video->lines_per_field = pix->height / 2;
675 video->lines_size = pix->width * 2;
676 video->front = front;
677 }
678 return start_video_stream(pd);
679 }
680
681 case V4L2_BUF_TYPE_VBI_CAPTURE: {
682 struct vbi_data *vbi = &pd->vbi_data;
683
684 *size = PAGE_ALIGN(vbi->vbi_size);
685 log("size : %d", *size);
686 if (*count == 0)
687 *count = 4;
688 }
689 break;
690 }
691 return 0;
692}
693
694static struct videobuf_queue_ops pd_video_qops = {
695 .buf_setup = pd_buf_setup,
696 .buf_prepare = pd_buf_prepare,
697 .buf_queue = pd_buf_queue,
698 .buf_release = pd_buf_release,
699};
700
701static int vidioc_enum_fmt(struct file *file, void *fh,
702 struct v4l2_fmtdesc *f)
703{
704 if (ARRAY_SIZE(poseidon_formats) <= f->index)
705 return -EINVAL;
706 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
707 f->flags = 0;
708 f->pixelformat = poseidon_formats[f->index].fourcc;
709 strcpy(f->description, poseidon_formats[f->index].name);
710 return 0;
711}
712
713static int vidioc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
714{
715 struct front_face *front = fh;
716 struct poseidon *pd = front->pd;
717
718 logs(front);
719 f->fmt.pix = pd->video_data.context.pix;
720 return 0;
721}
722
723static int vidioc_try_fmt(struct file *file, void *fh,
724 struct v4l2_format *f)
725{
726 return 0;
727}
728
729/*
730 * VLC calls VIDIOC_S_STD before VIDIOC_S_FMT, while
731 * Mplayer calls them in the reverse order.
732 */
733static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix)
734{
735 struct video_data *video = &pd->video_data;
736 struct running_context *context = &video->context;
737 struct v4l2_pix_format *pix_def = &context->pix;
738 s32 ret = 0, cmd_status = 0, vid_resol;
739
740 /* set the pixel format to firmware */
741 if (pix->pixelformat == V4L2_PIX_FMT_RGB565) {
742 vid_resol = TLG_TUNER_VID_FORMAT_RGB_565;
743 } else {
744 pix->pixelformat = V4L2_PIX_FMT_YUYV;
745 vid_resol = TLG_TUNER_VID_FORMAT_YUV;
746 }
747 ret = send_set_req(pd, VIDEO_STREAM_FMT_SEL,
748 vid_resol, &cmd_status);
749
750 /* set the resolution to firmware */
751 vid_resol = TLG_TUNE_VID_RES_720;
752 switch (pix->width) {
753 case 704:
754 vid_resol = TLG_TUNE_VID_RES_704;
755 break;
756 default:
757 pix->width = 720;
758 case 720:
759 break;
760 }
761 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
762 vid_resol, &cmd_status);
763 if (ret || cmd_status) {
764 mutex_unlock(&pd->lock);
765 return -EBUSY;
766 }
767
768 pix_def->pixelformat = pix->pixelformat; /* save it */
769 pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576;
770
771 /* Compare with the default setting */
772 if ((pix_def->width != pix->width)
773 || (pix_def->height != pix->height)) {
774 pix_def->width = pix->width;
775 pix_def->height = pix->height;
776 pix_def->bytesperline = pix->width * 2;
777 pix_def->sizeimage = pix->width * pix->height * 2;
778 }
779 *pix = *pix_def;
780
781 return 0;
782}
783
784static int vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
785{
786 struct front_face *front = fh;
787 struct poseidon *pd = front->pd;
788
789 logs(front);
790 /* stop VBI here */
791 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != f->type)
792 return -EINVAL;
793
794 mutex_lock(&pd->lock);
795 if (pd->file_for_stream == NULL)
796 pd->file_for_stream = file;
797 else if (file != pd->file_for_stream) {
798 mutex_unlock(&pd->lock);
799 return -EINVAL;
800 }
801
802 pd_vidioc_s_fmt(pd, &f->fmt.pix);
803 mutex_unlock(&pd->lock);
804 return 0;
805}
806
807static int vidioc_g_fmt_vbi(struct file *file, void *fh,
808 struct v4l2_format *v4l2_f)
809{
810 struct front_face *front = fh;
811 struct poseidon *pd = front->pd;
812 struct v4l2_vbi_format *vbi_fmt = &v4l2_f->fmt.vbi;
813
814 vbi_fmt->samples_per_line = 720 * 2;
815 vbi_fmt->sampling_rate = 6750000 * 4;
816 vbi_fmt->sample_format = V4L2_PIX_FMT_GREY;
817 vbi_fmt->offset = 64 * 4; /*FIXME: why offset */
818 if (pd->video_data.context.tvnormid & V4L2_STD_525_60) {
819 vbi_fmt->start[0] = 10;
820 vbi_fmt->start[1] = 264;
821 vbi_fmt->count[0] = V4L_NTSC_VBI_LINES;
822 vbi_fmt->count[1] = V4L_NTSC_VBI_LINES;
823 } else {
824 vbi_fmt->start[0] = 6;
825 vbi_fmt->start[1] = 314;
826 vbi_fmt->count[0] = V4L_PAL_VBI_LINES;
827 vbi_fmt->count[1] = V4L_PAL_VBI_LINES;
828 }
829 vbi_fmt->flags = V4L2_VBI_UNSYNC;
830 logs(front);
831 return 0;
832}
833
834static int set_std(struct poseidon *pd, v4l2_std_id *norm)
835{
836 struct video_data *video = &pd->video_data;
837 struct vbi_data *vbi = &pd->vbi_data;
838 struct running_context *context;
839 struct v4l2_pix_format *pix;
840 s32 i, ret = 0, cmd_status, param;
841 int height;
842
843 for (i = 0; i < POSEIDON_TVNORMS; i++) {
844 if (*norm & poseidon_tvnorms[i].v4l2_id) {
845 param = poseidon_tvnorms[i].tlg_tvnorm;
846 log("name : %s", poseidon_tvnorms[i].name);
847 goto found;
848 }
849 }
850 return -EINVAL;
851found:
852 mutex_lock(&pd->lock);
853 ret = send_set_req(pd, VIDEO_STD_SEL, param, &cmd_status);
854 if (ret || cmd_status)
855 goto out;
856
857 /* Set vbi size and check the height of the frame */
858 context = &video->context;
859 context->tvnormid = poseidon_tvnorms[i].v4l2_id;
860 if (context->tvnormid & V4L2_STD_525_60) {
861 vbi->vbi_size = V4L_NTSC_VBI_FRAMESIZE;
862 height = 480;
863 } else {
864 vbi->vbi_size = V4L_PAL_VBI_FRAMESIZE;
865 height = 576;
866 }
867
868 pix = &context->pix;
869 if (pix->height != height) {
870 pix->height = height;
871 pix->sizeimage = pix->width * pix->height * 2;
872 }
873
874out:
875 mutex_unlock(&pd->lock);
876 return ret;
877}
878
879int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm)
880{
881 struct front_face *front = fh;
882 logs(front);
883 return set_std(front->pd, norm);
884}
885
886static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in)
887{
888 struct front_face *front = fh;
889
890 if (in->index < 0 || in->index >= POSEIDON_INPUTS)
891 return -EINVAL;
892 strcpy(in->name, pd_inputs[in->index].name);
893 in->type = V4L2_INPUT_TYPE_TUNER;
894
895 /*
896 * the audio input index mixed with this video input,
897 * Poseidon only have one audio/video, set to "0"
898 */
899 in->audioset = 0;
900 in->tuner = 0;
901 in->std = V4L2_STD_ALL;
902 in->status = 0;
903 logs(front);
904 return 0;
905}
906
907static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
908{
909 struct front_face *front = fh;
910 struct poseidon *pd = front->pd;
911 struct running_context *context = &pd->video_data.context;
912
913 logs(front);
914 *i = context->sig_index;
915 return 0;
916}
917
918/* We can support several inputs */
919static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
920{
921 struct front_face *front = fh;
922 struct poseidon *pd = front->pd;
923 s32 ret, cmd_status;
924
925 if (i < 0 || i >= POSEIDON_INPUTS)
926 return -EINVAL;
927 ret = send_set_req(pd, SGNL_SRC_SEL,
928 pd_inputs[i].tlg_src, &cmd_status);
929 if (ret)
930 return ret;
931
932 pd->video_data.context.sig_index = i;
933 return 0;
934}
935
936static struct poseidon_control *check_control_id(__u32 id)
937{
938 struct poseidon_control *control = &controls[0];
939 int array_size = ARRAY_SIZE(controls);
940
941 for (; control < &controls[array_size]; control++)
942 if (control->v4l2_ctrl.id == id)
943 return control;
944 return NULL;
945}
946
947static int vidioc_queryctrl(struct file *file, void *fh,
948 struct v4l2_queryctrl *a)
949{
950 struct poseidon_control *control = NULL;
951
952 control = check_control_id(a->id);
953 if (!control)
954 return -EINVAL;
955
956 *a = control->v4l2_ctrl;
957 return 0;
958}
959
960static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
961{
962 struct front_face *front = fh;
963 struct poseidon *pd = front->pd;
964 struct poseidon_control *control = NULL;
965 struct tuner_custom_parameter_s tuner_param;
966 s32 ret = 0, cmd_status;
967
968 control = check_control_id(ctrl->id);
969 if (!control)
970 return -EINVAL;
971
972 mutex_lock(&pd->lock);
973 ret = send_get_req(pd, TUNER_CUSTOM_PARAMETER, control->vc_id,
974 &tuner_param, &cmd_status, sizeof(tuner_param));
975 mutex_unlock(&pd->lock);
976
977 if (ret || cmd_status)
978 return -1;
979
980 ctrl->value = tuner_param.param_value;
981 return 0;
982}
983
984static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
985{
986 struct tuner_custom_parameter_s param = {0};
987 struct poseidon_control *control = NULL;
988 struct front_face *front = fh;
989 struct poseidon *pd = front->pd;
990 s32 ret = 0, cmd_status, params;
991
992 control = check_control_id(a->id);
993 if (!control)
994 return -EINVAL;
995
996 param.param_value = a->value;
997 param.param_id = control->vc_id;
998 params = *(s32 *)&param; /* temp code */
999
1000 mutex_lock(&pd->lock);
1001 ret = send_set_req(pd, TUNER_CUSTOM_PARAMETER, params, &cmd_status);
1002 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
1003 mutex_unlock(&pd->lock);
1004
1005 set_current_state(TASK_INTERRUPTIBLE);
1006 schedule_timeout(HZ/4);
1007 return ret;
1008}
1009
1010/* Audio ioctls */
1011static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
1012{
1013 if (0 != a->index)
1014 return -EINVAL;
1015 a->capability = V4L2_AUDCAP_STEREO;
1016 strcpy(a->name, "USB audio in");
1017 /*Poseidon have no AVL function.*/
1018 a->mode = 0;
1019 return 0;
1020}
1021
1022int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
1023{
1024 a->index = 0;
1025 a->capability = V4L2_AUDCAP_STEREO;
1026 strcpy(a->name, "USB audio in");
1027 a->mode = 0;
1028 return 0;
1029}
1030
1031int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
1032{
1033 return (0 == a->index) ? 0 : -EINVAL;
1034}
1035
1036/* Tuner ioctls */
1037static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *tuner)
1038{
1039 struct front_face *front = fh;
1040 struct poseidon *pd = front->pd;
1041 struct tuner_atv_sig_stat_s atv_stat;
1042 s32 count = 5, ret, cmd_status;
1043 int index;
1044
1045 if (0 != tuner->index)
1046 return -EINVAL;
1047
1048 mutex_lock(&pd->lock);
1049 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
1050 &atv_stat, &cmd_status, sizeof(atv_stat));
1051
1052 while (atv_stat.sig_lock_busy && count-- && !ret) {
1053 set_current_state(TASK_INTERRUPTIBLE);
1054 schedule_timeout(HZ);
1055
1056 ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_ANALOG_TV,
1057 &atv_stat, &cmd_status, sizeof(atv_stat));
1058 }
1059 mutex_unlock(&pd->lock);
1060
1061 if (debug_mode)
1062 log("P:%d,S:%d", atv_stat.sig_present, atv_stat.sig_strength);
1063
1064 if (ret || cmd_status)
1065 tuner->signal = 0;
1066 else if (atv_stat.sig_present && !atv_stat.sig_strength)
1067 tuner->signal = 0xFFFF;
1068 else
1069 tuner->signal = (atv_stat.sig_strength * 255 / 10) << 8;
1070
1071 strcpy(tuner->name, "Telegent Systems");
1072 tuner->type = V4L2_TUNER_ANALOG_TV;
1073 tuner->rangelow = TUNER_FREQ_MIN / 62500;
1074 tuner->rangehigh = TUNER_FREQ_MAX / 62500;
1075 tuner->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
1076 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
1077 index = pd->video_data.context.audio_idx;
1078 tuner->rxsubchans = pd_audio_modes[index].v4l2_audio_sub;
1079 tuner->audmode = pd_audio_modes[index].v4l2_audio_mode;
1080 tuner->afc = 0;
1081 logs(front);
1082 return 0;
1083}
1084
1085static int pd_vidioc_s_tuner(struct poseidon *pd, int index)
1086{
1087 s32 ret = 0, cmd_status, param, audiomode;
1088
1089 mutex_lock(&pd->lock);
1090 param = pd_audio_modes[index].tlg_audio_mode;
1091 ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status);
1092 audiomode = get_audio_std(pd->video_data.context.tvnormid);
1093 ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode,
1094 &cmd_status);
1095 if (!ret)
1096 pd->video_data.context.audio_idx = index;
1097 mutex_unlock(&pd->lock);
1098 return ret;
1099}
1100
1101static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *a)
1102{
1103 struct front_face *front = fh;
1104 struct poseidon *pd = front->pd;
1105 int index;
1106
1107 if (0 != a->index)
1108 return -EINVAL;
1109 logs(front);
1110 for (index = 0; index < POSEIDON_AUDIOMODS; index++)
1111 if (a->audmode == pd_audio_modes[index].v4l2_audio_mode)
1112 return pd_vidioc_s_tuner(pd, index);
1113 return -EINVAL;
1114}
1115
1116static int vidioc_g_frequency(struct file *file, void *fh,
1117 struct v4l2_frequency *freq)
1118{
1119 struct front_face *front = fh;
1120 struct poseidon *pd = front->pd;
1121 struct running_context *context = &pd->video_data.context;
1122
1123 if (0 != freq->tuner)
1124 return -EINVAL;
1125 freq->frequency = context->freq;
1126 freq->type = V4L2_TUNER_ANALOG_TV;
1127 return 0;
1128}
1129
1130static int set_frequency(struct poseidon *pd, __u32 frequency)
1131{
1132 s32 ret = 0, param, cmd_status;
1133 struct running_context *context = &pd->video_data.context;
1134
1135 param = frequency * 62500 / 1000;
1136 if (param < TUNER_FREQ_MIN/1000 || param > TUNER_FREQ_MAX / 1000)
1137 return -EINVAL;
1138
1139 mutex_lock(&pd->lock);
1140 ret = send_set_req(pd, TUNE_FREQ_SELECT, param, &cmd_status);
1141 ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status);
1142
1143 msleep(250); /* wait for a while until the hardware is ready. */
1144 context->freq = frequency;
1145 mutex_unlock(&pd->lock);
1146 return ret;
1147}
1148
1149static int vidioc_s_frequency(struct file *file, void *fh,
1150 struct v4l2_frequency *freq)
1151{
1152 struct front_face *front = fh;
1153 struct poseidon *pd = front->pd;
1154
1155 logs(front);
1156#ifdef CONFIG_PM
1157 pd->pm_suspend = pm_video_suspend;
1158 pd->pm_resume = pm_video_resume;
1159#endif
1160 return set_frequency(pd, freq->frequency);
1161}
1162
1163static int vidioc_reqbufs(struct file *file, void *fh,
1164 struct v4l2_requestbuffers *b)
1165{
1166 struct front_face *front = file->private_data;
1167 logs(front);
1168 return videobuf_reqbufs(&front->q, b);
1169}
1170
1171static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
1172{
1173 struct front_face *front = file->private_data;
1174 logs(front);
1175 return videobuf_querybuf(&front->q, b);
1176}
1177
1178static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1179{
1180 struct front_face *front = file->private_data;
1181 return videobuf_qbuf(&front->q, b);
1182}
1183
1184static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1185{
1186 struct front_face *front = file->private_data;
1187 return videobuf_dqbuf(&front->q, b, file->f_flags & O_NONBLOCK);
1188}
1189
1190/* Just stop the URBs, do not free the URBs */
1191int usb_transfer_stop(struct video_data *video)
1192{
1193 if (video->is_streaming) {
1194 int i;
1195 s32 cmd_status;
1196 struct poseidon *pd = video->pd;
1197
1198 video->is_streaming = 0;
1199 for (i = 0; i < SBUF_NUM; ++i) {
1200 if (video->urb_array[i])
1201 usb_kill_urb(video->urb_array[i]);
1202 }
1203
1204 send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
1205 &cmd_status);
1206 }
1207 return 0;
1208}
1209
1210int stop_all_video_stream(struct poseidon *pd)
1211{
1212 struct video_data *video = &pd->video_data;
1213 struct vbi_data *vbi = &pd->vbi_data;
1214
1215 mutex_lock(&pd->lock);
1216 if (video->is_streaming) {
1217 struct front_face *front = video->front;
1218
1219 /* stop the URBs */
1220 usb_transfer_stop(video);
1221 free_all_urb(video);
1222
1223 /* stop the host side of VIDEO */
1224 videobuf_stop(&front->q);
1225 videobuf_mmap_free(&front->q);
1226
1227 /* stop the host side of VBI */
1228 front = vbi->front;
1229 if (front) {
1230 videobuf_stop(&front->q);
1231 videobuf_mmap_free(&front->q);
1232 }
1233 }
1234 mutex_unlock(&pd->lock);
1235 return 0;
1236}
1237
1238/*
1239 * The bubbles can seriously damage the video's quality,
1240 * though it occurs in very rare situation.
1241 */
1242static void iso_bubble_handler(struct work_struct *w)
1243{
1244 struct video_data *video;
1245 struct poseidon *pd;
1246
1247 video = container_of(w, struct video_data, bubble_work);
1248 pd = video->pd;
1249
1250 mutex_lock(&pd->lock);
1251 usb_transfer_stop(video);
1252 msleep(500);
1253 start_video_stream(pd);
1254 mutex_unlock(&pd->lock);
1255}
1256
1257
1258static int vidioc_streamon(struct file *file, void *fh,
1259 enum v4l2_buf_type type)
1260{
1261 struct front_face *front = fh;
1262
1263 logs(front);
1264 if (unlikely(type != front->type))
1265 return -EINVAL;
1266 return videobuf_streamon(&front->q);
1267}
1268
1269static int vidioc_streamoff(struct file *file, void *fh,
1270 enum v4l2_buf_type type)
1271{
1272 struct front_face *front = file->private_data;
1273
1274 logs(front);
1275 if (unlikely(type != front->type))
1276 return -EINVAL;
1277 return videobuf_streamoff(&front->q);
1278}
1279
1280/* Set the firmware's default values : need altersetting */
1281static int pd_video_checkmode(struct poseidon *pd)
1282{
1283 s32 ret = 0, cmd_status, audiomode;
1284
1285 set_current_state(TASK_INTERRUPTIBLE);
1286 schedule_timeout(HZ/2);
1287
1288 /* choose the altersetting */
1289 ret = usb_set_interface(pd->udev, 0,
1290 (pd->cur_transfer_mode ?
1291 ISO_3K_BULK_ALTERNATE_IFACE :
1292 BULK_ALTERNATE_IFACE));
1293 if (ret < 0)
1294 goto error;
1295
1296 /* set default parameters for PAL-D , with the VBI enabled*/
1297 ret = set_tuner_mode(pd, TLG_MODE_ANALOG_TV);
1298 ret |= send_set_req(pd, SGNL_SRC_SEL,
1299 TLG_SIG_SRC_ANTENNA, &cmd_status);
1300 ret |= send_set_req(pd, VIDEO_STD_SEL,
1301 TLG_TUNE_VSTD_PAL_D, &cmd_status);
1302 ret |= send_set_req(pd, VIDEO_STREAM_FMT_SEL,
1303 TLG_TUNER_VID_FORMAT_YUV, &cmd_status);
1304 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
1305 TLG_TUNE_VID_RES_720, &cmd_status);
1306 ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status);
1307 ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */
1308
1309 /* set the audio */
1310 audiomode = get_audio_std(pd->video_data.context.tvnormid);
1311 ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status);
1312 ret |= send_set_req(pd, TUNER_AUD_MODE,
1313 TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status);
1314 ret |= send_set_req(pd, AUDIO_SAMPLE_RATE_SEL,
1315 ATV_AUDIO_RATE_48K, &cmd_status);
1316error:
1317 return ret;
1318}
1319
1320#ifdef CONFIG_PM
1321static int pm_video_suspend(struct poseidon *pd)
1322{
1323 /* stop audio */
1324 pm_alsa_suspend(pd);
1325
1326 /* stop and free all the URBs */
1327 usb_transfer_stop(&pd->video_data);
1328 free_all_urb(&pd->video_data);
1329
1330 /* reset the interface */
1331 usb_set_interface(pd->udev, 0, 0);
1332 msleep(300);
1333 return 0;
1334}
1335
1336static int restore_v4l2_context(struct poseidon *pd,
1337 struct running_context *context)
1338{
1339 struct front_face *front = pd->video_data.front;
1340
1341 pd_video_checkmode(pd);
1342
1343 set_std(pd, &context->tvnormid);
1344 vidioc_s_input(NULL, front, context->sig_index);
1345 pd_vidioc_s_tuner(pd, context->audio_idx);
1346 pd_vidioc_s_fmt(pd, &context->pix);
1347 set_frequency(pd, context->freq);
1348 return 0;
1349}
1350
1351static int pm_video_resume(struct poseidon *pd)
1352{
1353 struct video_data *video = &pd->video_data;
1354
1355 /* resume the video */
1356 /* [1] restore the origin V4L2 parameters */
1357 restore_v4l2_context(pd, &video->context);
1358
1359 /* [2] initiate video copy variables */
1360 if (video->front->curr_frame)
1361 init_copy(video, 0);
1362
1363 /* [3] fire urbs */
1364 start_video_stream(pd);
1365
1366 /* resume the audio */
1367 pm_alsa_resume(pd);
1368 return 0;
1369}
1370#endif
1371
1372void set_debug_mode(struct video_device *vfd, int debug_mode)
1373{
1374 vfd->debug = 0;
1375 if (debug_mode & 0x1)
1376 vfd->debug = V4L2_DEBUG_IOCTL;
1377 if (debug_mode & 0x2)
1378 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1379}
1380
1381static void init_video_context(struct running_context *context)
1382{
1383 context->sig_index = 0;
1384 context->audio_idx = 1; /* stereo */
1385 context->tvnormid = V4L2_STD_PAL_D;
1386 context->pix = (struct v4l2_pix_format) {
1387 .width = 720,
1388 .height = 576,
1389 .pixelformat = V4L2_PIX_FMT_YUYV,
1390 .field = V4L2_FIELD_INTERLACED,
1391 .bytesperline = 720 * 2,
1392 .sizeimage = 720 * 576 * 2,
1393 .colorspace = V4L2_COLORSPACE_SMPTE170M,
1394 .priv = 0
1395 };
1396}
1397
1398static int pd_video_open(struct file *file)
1399{
1400 struct video_device *vfd = video_devdata(file);
1401 struct poseidon *pd = video_get_drvdata(vfd);
1402 struct front_face *front = NULL;
1403 int ret = -ENOMEM;
1404
1405 mutex_lock(&pd->lock);
1406 usb_autopm_get_interface(pd->interface);
1407
1408 if (vfd->vfl_type == VFL_TYPE_GRABBER
1409 && !(pd->state & POSEIDON_STATE_ANALOG)) {
1410 front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
1411 if (!front)
1412 goto out;
1413
1414 pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */
1415 init_video_context(&pd->video_data.context);
1416
1417 ret = pd_video_checkmode(pd);
1418 if (ret < 0) {
1419 kfree(front);
1420 ret = -1;
1421 goto out;
1422 }
1423
1424 pd->state |= POSEIDON_STATE_ANALOG;
1425 front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1426 pd->video_data.users++;
1427 set_debug_mode(vfd, debug_mode);
1428
1429 videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
1430 NULL, &front->queue_lock,
1431 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1432 V4L2_FIELD_INTERLACED,/* video is interlacd */
1433 sizeof(struct videobuf_buffer),/*it's enough*/
1434 front);
1435 } else if (vfd->vfl_type == VFL_TYPE_VBI
1436 && !(pd->state & POSEIDON_STATE_VBI)) {
1437 front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
1438 if (!front)
1439 goto out;
1440
1441 pd->state |= POSEIDON_STATE_VBI;
1442 front->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1443 pd->vbi_data.front = front;
1444 pd->vbi_data.users++;
1445
1446 videobuf_queue_vmalloc_init(&front->q, &pd_video_qops,
1447 NULL, &front->queue_lock,
1448 V4L2_BUF_TYPE_VBI_CAPTURE,
1449 V4L2_FIELD_NONE, /* vbi is NONE mode */
1450 sizeof(struct videobuf_buffer),
1451 front);
1452 } else {
1453 /* maybe add FM support here */
1454 log("other ");
1455 ret = -EINVAL;
1456 goto out;
1457 }
1458
1459 front->pd = pd;
1460 front->curr_frame = NULL;
1461 INIT_LIST_HEAD(&front->active);
1462 spin_lock_init(&front->queue_lock);
1463
1464 file->private_data = front;
1465 kref_get(&pd->kref);
1466
1467 mutex_unlock(&pd->lock);
1468 return 0;
1469out:
1470 usb_autopm_put_interface(pd->interface);
1471 mutex_unlock(&pd->lock);
1472 return ret;
1473}
1474
1475static int pd_video_release(struct file *file)
1476{
1477 struct front_face *front = file->private_data;
1478 struct poseidon *pd = front->pd;
1479 s32 cmd_status = 0;
1480
1481 logs(front);
1482 mutex_lock(&pd->lock);
1483
1484 if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1485 pd->state &= ~POSEIDON_STATE_ANALOG;
1486
1487 /* stop the device, and free the URBs */
1488 usb_transfer_stop(&pd->video_data);
1489 free_all_urb(&pd->video_data);
1490
1491 /* stop the firmware */
1492 send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP,
1493 &cmd_status);
1494
1495 pd->file_for_stream = NULL;
1496 pd->video_data.users--;
1497 } else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1498 pd->state &= ~POSEIDON_STATE_VBI;
1499 pd->vbi_data.front = NULL;
1500 pd->vbi_data.users--;
1501 }
1502 videobuf_stop(&front->q);
1503 videobuf_mmap_free(&front->q);
1504
1505 usb_autopm_put_interface(pd->interface);
1506 mutex_unlock(&pd->lock);
1507
1508 kfree(front);
1509 file->private_data = NULL;
1510 kref_put(&pd->kref, poseidon_delete);
1511 return 0;
1512}
1513
1514static int pd_video_mmap(struct file *file, struct vm_area_struct *vma)
1515{
1516 struct front_face *front = file->private_data;
1517 return videobuf_mmap_mapper(&front->q, vma);
1518}
1519
1520unsigned int pd_video_poll(struct file *file, poll_table *table)
1521{
1522 struct front_face *front = file->private_data;
1523 return videobuf_poll_stream(file, &front->q, table);
1524}
1525
1526ssize_t pd_video_read(struct file *file, char __user *buffer,
1527 size_t count, loff_t *ppos)
1528{
1529 struct front_face *front = file->private_data;
1530 return videobuf_read_stream(&front->q, buffer, count, ppos,
1531 0, file->f_flags & O_NONBLOCK);
1532}
1533
1534/* This struct works for both VIDEO and VBI */
1535static const struct v4l2_file_operations pd_video_fops = {
1536 .owner = THIS_MODULE,
1537 .open = pd_video_open,
1538 .release = pd_video_release,
1539 .read = pd_video_read,
1540 .poll = pd_video_poll,
1541 .mmap = pd_video_mmap,
1542 .ioctl = video_ioctl2, /* maybe changed in future */
1543};
1544
1545static const struct v4l2_ioctl_ops pd_video_ioctl_ops = {
1546 .vidioc_querycap = vidioc_querycap,
1547
1548 /* Video format */
1549 .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
1550 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
1551 .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
1552 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi, /* VBI */
1553 .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
1554
1555 /* Input */
1556 .vidioc_g_input = vidioc_g_input,
1557 .vidioc_s_input = vidioc_s_input,
1558 .vidioc_enum_input = vidioc_enum_input,
1559
1560 /* Audio ioctls */
1561 .vidioc_enumaudio = vidioc_enumaudio,
1562 .vidioc_g_audio = vidioc_g_audio,
1563 .vidioc_s_audio = vidioc_s_audio,
1564
1565 /* Tuner ioctls */
1566 .vidioc_g_tuner = vidioc_g_tuner,
1567 .vidioc_s_tuner = vidioc_s_tuner,
1568 .vidioc_s_std = vidioc_s_std,
1569 .vidioc_g_frequency = vidioc_g_frequency,
1570 .vidioc_s_frequency = vidioc_s_frequency,
1571
1572 /* Buffer handlers */
1573 .vidioc_reqbufs = vidioc_reqbufs,
1574 .vidioc_querybuf = vidioc_querybuf,
1575 .vidioc_qbuf = vidioc_qbuf,
1576 .vidioc_dqbuf = vidioc_dqbuf,
1577
1578 /* Stream on/off */
1579 .vidioc_streamon = vidioc_streamon,
1580 .vidioc_streamoff = vidioc_streamoff,
1581
1582 /* Control handling */
1583 .vidioc_queryctrl = vidioc_queryctrl,
1584 .vidioc_g_ctrl = vidioc_g_ctrl,
1585 .vidioc_s_ctrl = vidioc_s_ctrl,
1586};
1587
1588static struct video_device pd_video_template = {
1589 .name = "Telegent-Video",
1590 .fops = &pd_video_fops,
1591 .minor = -1,
1592 .release = video_device_release,
1593 .tvnorms = V4L2_STD_ALL,
1594 .ioctl_ops = &pd_video_ioctl_ops,
1595};
1596
1597struct video_device *vdev_init(struct poseidon *pd, struct video_device *tmp)
1598{
1599 struct video_device *vfd;
1600
1601 vfd = video_device_alloc();
1602 if (vfd == NULL)
1603 return NULL;
1604 *vfd = *tmp;
1605 vfd->minor = -1;
1606 vfd->v4l2_dev = &pd->v4l2_dev;
1607 /*vfd->parent = &(pd->udev->dev); */
1608 vfd->release = video_device_release;
1609 video_set_drvdata(vfd, pd);
1610 return vfd;
1611}
1612
1613void destroy_video_device(struct video_device **v_dev)
1614{
1615 struct video_device *dev = *v_dev;
1616
1617 if (dev == NULL)
1618 return;
1619
1620 if (video_is_registered(dev))
1621 video_unregister_device(dev);
1622 else
1623 video_device_release(dev);
1624 *v_dev = NULL;
1625}
1626
1627void pd_video_exit(struct poseidon *pd)
1628{
1629 struct video_data *video = &pd->video_data;
1630 struct vbi_data *vbi = &pd->vbi_data;
1631
1632 destroy_video_device(&video->v_dev);
1633 destroy_video_device(&vbi->v_dev);
1634 log();
1635}
1636
1637int pd_video_init(struct poseidon *pd)
1638{
1639 struct video_data *video = &pd->video_data;
1640 struct vbi_data *vbi = &pd->vbi_data;
1641 int ret = -ENOMEM;
1642
1643 video->v_dev = vdev_init(pd, &pd_video_template);
1644 if (video->v_dev == NULL)
1645 goto out;
1646
1647 ret = video_register_device(video->v_dev, VFL_TYPE_GRABBER, -1);
1648 if (ret != 0)
1649 goto out;
1650
1651 /* VBI uses the same template as video */
1652 vbi->v_dev = vdev_init(pd, &pd_video_template);
1653 if (vbi->v_dev == NULL) {
1654 ret = -ENOMEM;
1655 goto out;
1656 }
1657 ret = video_register_device(vbi->v_dev, VFL_TYPE_VBI, -1);
1658 if (ret != 0)
1659 goto out;
1660 log("register VIDEO/VBI devices");
1661 return 0;
1662out:
1663 log("VIDEO/VBI devices register failed, : %d", ret);
1664 pd_video_exit(pd);
1665 return ret;
1666}
1667
diff --git a/drivers/media/video/tlg2300/vendorcmds.h b/drivers/media/video/tlg2300/vendorcmds.h
new file mode 100644
index 000000000000..ba6f4ae3b2c2
--- /dev/null
+++ b/drivers/media/video/tlg2300/vendorcmds.h
@@ -0,0 +1,243 @@
1#ifndef VENDOR_CMD_H_
2#define VENDOR_CMD_H_
3
4#define BULK_ALTERNATE_IFACE (2)
5#define ISO_3K_BULK_ALTERNATE_IFACE (1)
6#define REQ_SET_CMD (0X00)
7#define REQ_GET_CMD (0X80)
8
9enum tlg__analog_audio_standard {
10 TLG_TUNE_ASTD_NONE = 0x00000000,
11 TLG_TUNE_ASTD_A2 = 0x00000001,
12 TLG_TUNE_ASTD_NICAM = 0x00000002,
13 TLG_TUNE_ASTD_EIAJ = 0x00000004,
14 TLG_TUNE_ASTD_BTSC = 0x00000008,
15 TLG_TUNE_ASTD_FM_US = 0x00000010,
16 TLG_TUNE_ASTD_FM_EUR = 0x00000020,
17 TLG_TUNE_ASTD_ALL = 0x0000003f
18};
19
20/*
21 * identifiers for Custom Parameter messages.
22 * @typedef cmd_custom_param_id_t
23 */
24enum cmd_custom_param_id {
25 CUST_PARM_ID_NONE = 0x00,
26 CUST_PARM_ID_BRIGHTNESS_CTRL = 0x01,
27 CUST_PARM_ID_CONTRAST_CTRL = 0x02,
28 CUST_PARM_ID_HUE_CTRL = 0x03,
29 CUST_PARM_ID_SATURATION_CTRL = 0x04,
30 CUST_PARM_ID_AUDIO_SNR_THRESHOLD = 0x10,
31 CUST_PARM_ID_AUDIO_AGC_THRESHOLD = 0x11,
32 CUST_PARM_ID_MAX
33};
34
35struct tuner_custom_parameter_s {
36 uint16_t param_id; /* Parameter identifier */
37 uint16_t param_value; /* Parameter value */
38};
39
40struct tuner_ber_rate_s {
41 uint32_t ber_rate; /* BER sample rate in seconds */
42};
43
44struct tuner_atv_sig_stat_s {
45 uint32_t sig_present;
46 uint32_t sig_locked;
47 uint32_t sig_lock_busy;
48 uint32_t sig_strength; /* milliDb */
49 uint32_t tv_audio_chan; /* mono/stereo/sap*/
50 uint32_t mvision_stat; /* macrovision status */
51};
52
53struct tuner_dtv_sig_stat_s {
54 uint32_t sig_present; /* Boolean*/
55 uint32_t sig_locked; /* Boolean */
56 uint32_t sig_lock_busy; /* Boolean (Can this time-out?) */
57 uint32_t sig_strength; /* milliDb*/
58};
59
60struct tuner_fm_sig_stat_s {
61 uint32_t sig_present; /* Boolean*/
62 uint32_t sig_locked; /* Boolean */
63 uint32_t sig_lock_busy; /* Boolean */
64 uint32_t sig_stereo_mono;/* TBD*/
65 uint32_t sig_strength; /* milliDb*/
66};
67
68enum _tag_tlg_tune_srv_cmd {
69 TLG_TUNE_PLAY_SVC_START = 1,
70 TLG_TUNE_PLAY_SVC_STOP
71};
72
73enum _tag_tune_atv_audio_mode_caps {
74 TLG_TUNE_TVAUDIO_MODE_MONO = 0x00000001,
75 TLG_TUNE_TVAUDIO_MODE_STEREO = 0x00000002,
76 TLG_TUNE_TVAUDIO_MODE_LANG_A = 0x00000010,/* Primary language*/
77 TLG_TUNE_TVAUDIO_MODE_LANG_B = 0x00000020,/* 2nd avail language*/
78 TLG_TUNE_TVAUDIO_MODE_LANG_C = 0x00000040
79};
80
81
82enum _tag_tuner_atv_audio_rates {
83 ATV_AUDIO_RATE_NONE = 0x00,/* Audio not supported*/
84 ATV_AUDIO_RATE_32K = 0x01,/* Audio rate = 32 KHz*/
85 ATV_AUDIO_RATE_48K = 0x02, /* Audio rate = 48 KHz*/
86 ATV_AUDIO_RATE_31_25K = 0x04 /* Audio rate = 31.25KHz */
87};
88
89enum _tag_tune_atv_vid_res_caps {
90 TLG_TUNE_VID_RES_NONE = 0x00000000,
91 TLG_TUNE_VID_RES_720 = 0x00000001,
92 TLG_TUNE_VID_RES_704 = 0x00000002,
93 TLG_TUNE_VID_RES_360 = 0x00000004
94};
95
96enum _tag_tuner_analog_video_format {
97 TLG_TUNER_VID_FORMAT_YUV = 0x00000001,
98 TLG_TUNER_VID_FORMAT_YCRCB = 0x00000002,
99 TLG_TUNER_VID_FORMAT_RGB_565 = 0x00000004,
100};
101
102enum tlg_ext_audio_support {
103 TLG_EXT_AUDIO_NONE = 0x00,/* No external audio input supported */
104 TLG_EXT_AUDIO_LR = 0x01/* LR external audio inputs supported*/
105};
106
107enum {
108 TLG_MODE_NONE = 0x00, /* No Mode specified*/
109 TLG_MODE_ANALOG_TV = 0x01, /* Analog Television mode*/
110 TLG_MODE_ANALOG_TV_UNCOMP = 0x01, /* Analog Television mode*/
111 TLG_MODE_ANALOG_TV_COMP = 0x02, /* Analog TV mode (compressed)*/
112 TLG_MODE_FM_RADIO = 0x04, /* FM Radio mode*/
113 TLG_MODE_DVB_T = 0x08, /* Digital TV (DVB-T)*/
114};
115
116enum tlg_signal_sources_t {
117 TLG_SIG_SRC_NONE = 0x00,/* Signal source not specified */
118 TLG_SIG_SRC_ANTENNA = 0x01,/* Signal src is: Antenna */
119 TLG_SIG_SRC_CABLE = 0x02,/* Signal src is: Coax Cable*/
120 TLG_SIG_SRC_SVIDEO = 0x04,/* Signal src is: S_VIDEO */
121 TLG_SIG_SRC_COMPOSITE = 0x08 /* Signal src is: Composite Video */
122};
123
124enum tuner_analog_video_standard {
125 TLG_TUNE_VSTD_NONE = 0x00000000,
126 TLG_TUNE_VSTD_NTSC_M = 0x00000001,
127 TLG_TUNE_VSTD_NTSC_M_J = 0x00000002,/* Japan */
128 TLG_TUNE_VSTD_PAL_B = 0x00000010,
129 TLG_TUNE_VSTD_PAL_D = 0x00000020,
130 TLG_TUNE_VSTD_PAL_G = 0x00000040,
131 TLG_TUNE_VSTD_PAL_H = 0x00000080,
132 TLG_TUNE_VSTD_PAL_I = 0x00000100,
133 TLG_TUNE_VSTD_PAL_M = 0x00000200,
134 TLG_TUNE_VSTD_PAL_N = 0x00000400,
135 TLG_TUNE_VSTD_SECAM_B = 0x00001000,
136 TLG_TUNE_VSTD_SECAM_D = 0x00002000,
137 TLG_TUNE_VSTD_SECAM_G = 0x00004000,
138 TLG_TUNE_VSTD_SECAM_H = 0x00008000,
139 TLG_TUNE_VSTD_SECAM_K = 0x00010000,
140 TLG_TUNE_VSTD_SECAM_K1 = 0x00020000,
141 TLG_TUNE_VSTD_SECAM_L = 0x00040000,
142 TLG_TUNE_VSTD_SECAM_L1 = 0x00080000,
143 TLG_TUNE_VSTD_PAL_N_COMBO = 0x00100000
144};
145
146enum tlg_mode_caps {
147 TLG_MODE_CAPS_NONE = 0x00, /* No Mode specified */
148 TLG_MODE_CAPS_ANALOG_TV_UNCOMP = 0x01, /* Analog TV mode */
149 TLG_MODE_CAPS_ANALOG_TV_COMP = 0x02, /* Analog TV (compressed)*/
150 TLG_MODE_CAPS_FM_RADIO = 0x04, /* FM Radio mode */
151 TLG_MODE_CAPS_DVB_T = 0x08, /* Digital TV (DVB-T) */
152};
153
154enum poseidon_vendor_cmds {
155 LAST_CMD_STAT = 0x00,
156 GET_CHIP_ID = 0x01,
157 GET_FW_ID = 0x02,
158 PRODUCT_CAPS = 0x03,
159
160 TUNE_MODE_CAP_ATV = 0x10,
161 TUNE_MODE_CAP_ATVCOMP = 0X10,
162 TUNE_MODE_CAP_DVBT = 0x10,
163 TUNE_MODE_CAP_FM = 0x10,
164 TUNE_MODE_SELECT = 0x11,
165 TUNE_FREQ_SELECT = 0x12,
166 SGNL_SRC_SEL = 0x13,
167
168 VIDEO_STD_SEL = 0x14,
169 VIDEO_STREAM_FMT_SEL = 0x15,
170 VIDEO_ROSOLU_AVAIL = 0x16,
171 VIDEO_ROSOLU_SEL = 0x17,
172 VIDEO_CONT_PROTECT = 0x20,
173
174 VCR_TIMING_MODSEL = 0x21,
175 EXT_AUDIO_CAP = 0x22,
176 EXT_AUDIO_SEL = 0x23,
177 TEST_PATTERN_SEL = 0x24,
178 VBI_DATA_SEL = 0x25,
179 AUDIO_SAMPLE_RATE_CAP = 0x28,
180 AUDIO_SAMPLE_RATE_SEL = 0x29,
181 TUNER_AUD_MODE = 0x2a,
182 TUNER_AUD_MODE_AVAIL = 0x2b,
183 TUNER_AUD_ANA_STD = 0x2c,
184 TUNER_CUSTOM_PARAMETER = 0x2f,
185
186 DVBT_TUNE_MODE_SEL = 0x30,
187 DVBT_BANDW_CAP = 0x31,
188 DVBT_BANDW_SEL = 0x32,
189 DVBT_GUARD_INTERV_CAP = 0x33,
190 DVBT_GUARD_INTERV_SEL = 0x34,
191 DVBT_MODULATION_CAP = 0x35,
192 DVBT_MODULATION_SEL = 0x36,
193 DVBT_INNER_FEC_RATE_CAP = 0x37,
194 DVBT_INNER_FEC_RATE_SEL = 0x38,
195 DVBT_TRANS_MODE_CAP = 0x39,
196 DVBT_TRANS_MODE_SEL = 0x3a,
197 DVBT_SEARCH_RANG = 0x3c,
198
199 TUNER_SETUP_ANALOG = 0x40,
200 TUNER_SETUP_DIGITAL = 0x41,
201 TUNER_SETUP_FM_RADIO = 0x42,
202 TAKE_REQUEST = 0x43, /* Take effect of the command */
203 PLAY_SERVICE = 0x44, /* Play start or Play stop */
204 TUNER_STATUS = 0x45,
205 TUNE_PROP_DVBT = 0x46,
206 ERR_RATE_STATS = 0x47,
207 TUNER_BER_RATE = 0x48,
208
209 SCAN_CAPS = 0x50,
210 SCAN_SETUP = 0x51,
211 SCAN_SERVICE = 0x52,
212 SCAN_STATS = 0x53,
213
214 PID_SET = 0x58,
215 PID_UNSET = 0x59,
216 PID_LIST = 0x5a,
217
218 IRD_CAP = 0x60,
219 IRD_MODE_SEL = 0x61,
220 IRD_SETUP = 0x62,
221
222 PTM_MODE_CAP = 0x70,
223 PTM_MODE_SEL = 0x71,
224 PTM_SERVICE = 0x72,
225 TUNER_REG_SCRIPT = 0x73,
226 CMD_CHIP_RST = 0x74,
227};
228
229enum tlg_bw {
230 TLG_BW_5 = 5,
231 TLG_BW_6 = 6,
232 TLG_BW_7 = 7,
233 TLG_BW_8 = 8,
234 TLG_BW_12 = 12,
235 TLG_BW_15 = 15
236};
237
238struct cmd_firmware_vers_s {
239 uint8_t fw_rev_major;
240 uint8_t fw_rev_minor;
241 uint16_t fw_patch;
242};
243#endif /* VENDOR_CMD_H_ */
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 5b3eaa16afd2..c4dab6cfd948 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1078,6 +1078,7 @@ static int tuner_probe(struct i2c_client *client,
1078 1078
1079 goto register_client; 1079 goto register_client;
1080 } 1080 }
1081 kfree(t);
1081 return -ENODEV; 1082 return -ENODEV;
1082 case 0x42: 1083 case 0x42:
1083 case 0x43: 1084 case 0x43:
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index d533ea57e7b1..0a877497b93f 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -680,10 +680,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
680 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", 680 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
681 tvee->model, tvee->rev_str, tvee->serial_number); 681 tvee->model, tvee->rev_str, tvee->serial_number);
682 if (tvee->has_MAC_address == 1) 682 if (tvee->has_MAC_address == 1)
683 tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n", 683 tveeprom_info("MAC address is %pM\n", tvee->MAC_address);
684 tvee->MAC_address[0], tvee->MAC_address[1],
685 tvee->MAC_address[2], tvee->MAC_address[3],
686 tvee->MAC_address[4], tvee->MAC_address[5]);
687 tveeprom_info("tuner model is %s (idx %d, type %d)\n", 684 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
688 t_name1, tuner1, tvee->tuner_type); 685 t_name1, tuner1, tvee->tuner_type);
689 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 686 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
new file mode 100644
index 000000000000..5a878bca02d4
--- /dev/null
+++ b/drivers/media/video/tvp7002.c
@@ -0,0 +1,1187 @@
1/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
2 * Digitizer with Horizontal PLL registers
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
6 *
7 * This code is partially based upon the TVP5150 driver
8 * written by Mauro Carvalho Chehab (mchehab@infradead.org),
9 * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
10 * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by
11 * Muralidharan Karicheri and Snehaprabha Narnakaje (TI).
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 as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
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#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/videodev2.h>
30#include <media/tvp7002.h>
31#include <media/v4l2-device.h>
32#include <media/v4l2-chip-ident.h>
33#include <media/v4l2-common.h>
34#include "tvp7002_reg.h"
35
36MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
37MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
38MODULE_LICENSE("GPL");
39
40/* Module Name */
41#define TVP7002_MODULE_NAME "tvp7002"
42
43/* I2C retry attempts */
44#define I2C_RETRY_COUNT (5)
45
46/* End of registers */
47#define TVP7002_EOR 0x5c
48
49/* Read write definition for registers */
50#define TVP7002_READ 0
51#define TVP7002_WRITE 1
52#define TVP7002_RESERVED 2
53
54/* Interlaced vs progressive mask and shift */
55#define TVP7002_IP_SHIFT 5
56#define TVP7002_INPR_MASK (0x01 << TVP7002_IP_SHIFT)
57
58/* Shift for CPL and LPF registers */
59#define TVP7002_CL_SHIFT 8
60#define TVP7002_CL_MASK 0x0f
61
62/* Debug functions */
63static int debug;
64module_param(debug, bool, 0644);
65MODULE_PARM_DESC(debug, "Debug level (0-2)");
66
67/* Structure for register values */
68struct i2c_reg_value {
69 u8 reg;
70 u8 value;
71 u8 type;
72};
73
74/*
75 * Register default values (according to tvp7002 datasheet)
76 * In the case of read-only registers, the value (0xff) is
77 * never written. R/W functionality is controlled by the
78 * writable bit in the register struct definition.
79 */
80static const struct i2c_reg_value tvp7002_init_default[] = {
81 { TVP7002_CHIP_REV, 0xff, TVP7002_READ },
82 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
83 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
84 { TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
85 { TVP7002_HPLL_PHASE_SEL, 0x80, TVP7002_WRITE },
86 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
87 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
88 { TVP7002_HSYNC_OUT_W, 0x60, TVP7002_WRITE },
89 { TVP7002_B_FINE_GAIN, 0x00, TVP7002_WRITE },
90 { TVP7002_G_FINE_GAIN, 0x00, TVP7002_WRITE },
91 { TVP7002_R_FINE_GAIN, 0x00, TVP7002_WRITE },
92 { TVP7002_B_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
93 { TVP7002_G_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
94 { TVP7002_R_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
95 { TVP7002_SYNC_CTL_1, 0x20, TVP7002_WRITE },
96 { TVP7002_HPLL_AND_CLAMP_CTL, 0x2e, TVP7002_WRITE },
97 { TVP7002_SYNC_ON_G_THRS, 0x5d, TVP7002_WRITE },
98 { TVP7002_SYNC_SEPARATOR_THRS, 0x47, TVP7002_WRITE },
99 { TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
100 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
101 { TVP7002_SYNC_DETECT_STAT, 0xff, TVP7002_READ },
102 { TVP7002_OUT_FORMATTER, 0x47, TVP7002_WRITE },
103 { TVP7002_MISC_CTL_1, 0x01, TVP7002_WRITE },
104 { TVP7002_MISC_CTL_2, 0x00, TVP7002_WRITE },
105 { TVP7002_MISC_CTL_3, 0x01, TVP7002_WRITE },
106 { TVP7002_IN_MUX_SEL_1, 0x00, TVP7002_WRITE },
107 { TVP7002_IN_MUX_SEL_2, 0x67, TVP7002_WRITE },
108 { TVP7002_B_AND_G_COARSE_GAIN, 0x77, TVP7002_WRITE },
109 { TVP7002_R_COARSE_GAIN, 0x07, TVP7002_WRITE },
110 { TVP7002_FINE_OFF_LSBS, 0x00, TVP7002_WRITE },
111 { TVP7002_B_COARSE_OFF, 0x10, TVP7002_WRITE },
112 { TVP7002_G_COARSE_OFF, 0x10, TVP7002_WRITE },
113 { TVP7002_R_COARSE_OFF, 0x10, TVP7002_WRITE },
114 { TVP7002_HSOUT_OUT_START, 0x08, TVP7002_WRITE },
115 { TVP7002_MISC_CTL_4, 0x00, TVP7002_WRITE },
116 { TVP7002_B_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
117 { TVP7002_G_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
118 { TVP7002_R_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
119 { TVP7002_AUTO_LVL_CTL_ENABLE, 0x80, TVP7002_WRITE },
120 { TVP7002_DGTL_ALC_OUT_MSBS, 0xff, TVP7002_READ },
121 { TVP7002_AUTO_LVL_CTL_FILTER, 0x53, TVP7002_WRITE },
122 { 0x29, 0x08, TVP7002_RESERVED },
123 { TVP7002_FINE_CLAMP_CTL, 0x07, TVP7002_WRITE },
124 /* PWR_CTL is controlled only by the probe and reset functions */
125 { TVP7002_PWR_CTL, 0x00, TVP7002_RESERVED },
126 { TVP7002_ADC_SETUP, 0x50, TVP7002_WRITE },
127 { TVP7002_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
128 { TVP7002_SOG_CLAMP, 0x80, TVP7002_WRITE },
129 { TVP7002_RGB_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
130 { TVP7002_SOG_COARSE_CLAMP_CTL, 0x04, TVP7002_WRITE },
131 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
132 { 0x32, 0x18, TVP7002_RESERVED },
133 { 0x33, 0x60, TVP7002_RESERVED },
134 { TVP7002_MVIS_STRIPPER_W, 0xff, TVP7002_RESERVED },
135 { TVP7002_VSYNC_ALGN, 0x10, TVP7002_WRITE },
136 { TVP7002_SYNC_BYPASS, 0x00, TVP7002_WRITE },
137 { TVP7002_L_FRAME_STAT_LSBS, 0xff, TVP7002_READ },
138 { TVP7002_L_FRAME_STAT_MSBS, 0xff, TVP7002_READ },
139 { TVP7002_CLK_L_STAT_LSBS, 0xff, TVP7002_READ },
140 { TVP7002_CLK_L_STAT_MSBS, 0xff, TVP7002_READ },
141 { TVP7002_HSYNC_W, 0xff, TVP7002_READ },
142 { TVP7002_VSYNC_W, 0xff, TVP7002_READ },
143 { TVP7002_L_LENGTH_TOL, 0x03, TVP7002_WRITE },
144 { 0x3e, 0x60, TVP7002_RESERVED },
145 { TVP7002_VIDEO_BWTH_CTL, 0x01, TVP7002_WRITE },
146 { TVP7002_AVID_START_PIXEL_LSBS, 0x01, TVP7002_WRITE },
147 { TVP7002_AVID_START_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
148 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x06, TVP7002_WRITE },
149 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
150 { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
151 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
152 { TVP7002_VBLK_F_0_DURATION, 0x1e, TVP7002_WRITE },
153 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
154 { TVP7002_FBIT_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
155 { TVP7002_FBIT_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
156 { TVP7002_YUV_Y_G_COEF_LSBS, 0xe3, TVP7002_WRITE },
157 { TVP7002_YUV_Y_G_COEF_MSBS, 0x16, TVP7002_WRITE },
158 { TVP7002_YUV_Y_B_COEF_LSBS, 0x4f, TVP7002_WRITE },
159 { TVP7002_YUV_Y_B_COEF_MSBS, 0x02, TVP7002_WRITE },
160 { TVP7002_YUV_Y_R_COEF_LSBS, 0xce, TVP7002_WRITE },
161 { TVP7002_YUV_Y_R_COEF_MSBS, 0x06, TVP7002_WRITE },
162 { TVP7002_YUV_U_G_COEF_LSBS, 0xab, TVP7002_WRITE },
163 { TVP7002_YUV_U_G_COEF_MSBS, 0xf3, TVP7002_WRITE },
164 { TVP7002_YUV_U_B_COEF_LSBS, 0x00, TVP7002_WRITE },
165 { TVP7002_YUV_U_B_COEF_MSBS, 0x10, TVP7002_WRITE },
166 { TVP7002_YUV_U_R_COEF_LSBS, 0x55, TVP7002_WRITE },
167 { TVP7002_YUV_U_R_COEF_MSBS, 0xfc, TVP7002_WRITE },
168 { TVP7002_YUV_V_G_COEF_LSBS, 0x78, TVP7002_WRITE },
169 { TVP7002_YUV_V_G_COEF_MSBS, 0xf1, TVP7002_WRITE },
170 { TVP7002_YUV_V_B_COEF_LSBS, 0x88, TVP7002_WRITE },
171 { TVP7002_YUV_V_B_COEF_MSBS, 0xfe, TVP7002_WRITE },
172 { TVP7002_YUV_V_R_COEF_LSBS, 0x00, TVP7002_WRITE },
173 { TVP7002_YUV_V_R_COEF_MSBS, 0x10, TVP7002_WRITE },
174 /* This signals end of register values */
175 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
176};
177
178/* Register parameters for 480P */
179static const struct i2c_reg_value tvp7002_parms_480P[] = {
180 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x35, TVP7002_WRITE },
181 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x0a, TVP7002_WRITE },
182 { TVP7002_HPLL_CRTL, 0x02, TVP7002_WRITE },
183 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
184 { TVP7002_AVID_START_PIXEL_LSBS, 0x91, TVP7002_WRITE },
185 { TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
186 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x0B, TVP7002_WRITE },
187 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
188 { TVP7002_VBLK_F_0_START_L_OFF, 0x03, TVP7002_WRITE },
189 { TVP7002_VBLK_F_1_START_L_OFF, 0x01, TVP7002_WRITE },
190 { TVP7002_VBLK_F_0_DURATION, 0x13, TVP7002_WRITE },
191 { TVP7002_VBLK_F_1_DURATION, 0x13, TVP7002_WRITE },
192 { TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
193 { TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
194 { TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
195 { TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
196 { TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
197 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
198};
199
200/* Register parameters for 576P */
201static const struct i2c_reg_value tvp7002_parms_576P[] = {
202 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x36, TVP7002_WRITE },
203 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
204 { TVP7002_HPLL_CRTL, 0x18, TVP7002_WRITE },
205 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
206 { TVP7002_AVID_START_PIXEL_LSBS, 0x9B, TVP7002_WRITE },
207 { TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
208 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x0F, TVP7002_WRITE },
209 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
210 { TVP7002_VBLK_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
211 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
212 { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
213 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
214 { TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
215 { TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
216 { TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
217 { TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
218 { TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
219 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
220};
221
222/* Register parameters for 1080I60 */
223static const struct i2c_reg_value tvp7002_parms_1080I60[] = {
224 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
225 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x08, TVP7002_WRITE },
226 { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
227 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
228 { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
229 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
230 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
231 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
232 { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
233 { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
234 { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
235 { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
236 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
237 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
238 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
239 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
240 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
241 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
242};
243
244/* Register parameters for 1080P60 */
245static const struct i2c_reg_value tvp7002_parms_1080P60[] = {
246 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
247 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x08, TVP7002_WRITE },
248 { TVP7002_HPLL_CRTL, 0xE0, TVP7002_WRITE },
249 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
250 { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
251 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
252 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
253 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
254 { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
255 { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
256 { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
257 { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
258 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
259 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
260 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
261 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
262 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
263 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
264};
265
266/* Register parameters for 1080I50 */
267static const struct i2c_reg_value tvp7002_parms_1080I50[] = {
268 { TVP7002_HPLL_FDBK_DIV_MSBS, 0xa5, TVP7002_WRITE },
269 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
270 { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
271 { TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
272 { TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
273 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
274 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
275 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
276 { TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
277 { TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
278 { TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
279 { TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
280 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
281 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
282 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
283 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
284 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
285 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
286};
287
288/* Register parameters for 720P60 */
289static const struct i2c_reg_value tvp7002_parms_720P60[] = {
290 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
291 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x02, TVP7002_WRITE },
292 { TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
293 { TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
294 { TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
295 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
296 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
297 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
298 { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
299 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
300 { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
301 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
302 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
303 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
304 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
305 { TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
306 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
307 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
308};
309
310/* Register parameters for 720P50 */
311static const struct i2c_reg_value tvp7002_parms_720P50[] = {
312 { TVP7002_HPLL_FDBK_DIV_MSBS, 0x7b, TVP7002_WRITE },
313 { TVP7002_HPLL_FDBK_DIV_LSBS, 0x0c, TVP7002_WRITE },
314 { TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
315 { TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
316 { TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
317 { TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
318 { TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
319 { TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
320 { TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
321 { TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
322 { TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
323 { TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
324 { TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
325 { TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
326 { TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
327 { TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
328 { TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
329 { TVP7002_EOR, 0xff, TVP7002_RESERVED }
330};
331
332/* Struct list for available formats */
333static const struct v4l2_fmtdesc tvp7002_fmt_list[] = {
334 {
335 .index = 0,
336 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
337 .flags = 0,
338 .description = "8-bit UYVY 4:2:2 Format",
339 .pixelformat = V4L2_PIX_FMT_UYVY,
340 },
341};
342
343#define NUM_FORMATS ARRAY_SIZE(tvp7002_fmt_list)
344
345/* Preset definition for handling device operation */
346struct tvp7002_preset_definition {
347 u32 preset;
348 const struct i2c_reg_value *p_settings;
349 enum v4l2_colorspace color_space;
350 enum v4l2_field scanmode;
351 u16 progressive;
352 u16 lines_per_frame;
353 u16 cpl_min;
354 u16 cpl_max;
355};
356
357/* Struct list for digital video presets */
358static const struct tvp7002_preset_definition tvp7002_presets[] = {
359 {
360 V4L2_DV_720P60,
361 tvp7002_parms_720P60,
362 V4L2_COLORSPACE_REC709,
363 V4L2_FIELD_NONE,
364 1,
365 0x2EE,
366 135,
367 153
368 },
369 {
370 V4L2_DV_1080I60,
371 tvp7002_parms_1080I60,
372 V4L2_COLORSPACE_REC709,
373 V4L2_FIELD_INTERLACED,
374 0,
375 0x465,
376 181,
377 205
378 },
379 {
380 V4L2_DV_1080I50,
381 tvp7002_parms_1080I50,
382 V4L2_COLORSPACE_REC709,
383 V4L2_FIELD_INTERLACED,
384 0,
385 0x465,
386 217,
387 245
388 },
389 {
390 V4L2_DV_720P50,
391 tvp7002_parms_720P50,
392 V4L2_COLORSPACE_REC709,
393 V4L2_FIELD_NONE,
394 1,
395 0x2EE,
396 163,
397 183
398 },
399 {
400 V4L2_DV_1080P60,
401 tvp7002_parms_1080P60,
402 V4L2_COLORSPACE_REC709,
403 V4L2_FIELD_NONE,
404 1,
405 0x465,
406 90,
407 102
408 },
409 {
410 V4L2_DV_480P59_94,
411 tvp7002_parms_480P,
412 V4L2_COLORSPACE_SMPTE170M,
413 V4L2_FIELD_NONE,
414 1,
415 0x20D,
416 0xffff,
417 0xffff
418 },
419 {
420 V4L2_DV_576P50,
421 tvp7002_parms_576P,
422 V4L2_COLORSPACE_SMPTE170M,
423 V4L2_FIELD_NONE,
424 1,
425 0x271,
426 0xffff,
427 0xffff
428 }
429};
430
431#define NUM_PRESETS ARRAY_SIZE(tvp7002_presets)
432
433/* Device definition */
434struct tvp7002 {
435 struct v4l2_subdev sd;
436 const struct tvp7002_config *pdata;
437
438 int ver;
439 int streaming;
440
441 struct v4l2_pix_format pix;
442 const struct tvp7002_preset_definition *current_preset;
443 u8 gain;
444};
445
446/*
447 * to_tvp7002 - Obtain device handler TVP7002
448 * @sd: ptr to v4l2_subdev struct
449 *
450 * Returns device handler tvp7002.
451 */
452static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
453{
454 return container_of(sd, struct tvp7002, sd);
455}
456
457/*
458 * tvp7002_read - Read a value from a register in an TVP7002
459 * @sd: ptr to v4l2_subdev struct
460 * @reg: TVP7002 register address
461 * @dst: pointer to 8-bit destination
462 *
463 * Returns value read if successful, or non-zero (-1) otherwise.
464 */
465static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
466{
467 struct i2c_client *c = v4l2_get_subdevdata(sd);
468 int retry;
469 int error;
470
471 for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
472 error = i2c_smbus_read_byte_data(c, addr);
473
474 if (error >= 0) {
475 *dst = (u8)error;
476 return 0;
477 }
478
479 msleep_interruptible(10);
480 }
481 v4l2_err(sd, "TVP7002 read error %d\n", error);
482 return error;
483}
484
485/*
486 * tvp7002_read_err() - Read a register value with error code
487 * @sd: pointer to standard V4L2 sub-device structure
488 * @reg: destination register
489 * @val: value to be read
490 * @error: pointer to error value
491 *
492 * Read a value in a register and save error value in pointer.
493 * Also update the register table if successful
494 */
495static inline void tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
496 u8 *dst, int *err)
497{
498 if (!*err)
499 *err = tvp7002_read(sd, reg, dst);
500}
501
502/*
503 * tvp7002_write() - Write a value to a register in TVP7002
504 * @sd: ptr to v4l2_subdev struct
505 * @addr: TVP7002 register address
506 * @value: value to be written to the register
507 *
508 * Write a value to a register in an TVP7002 decoder device.
509 * Returns zero if successful, or non-zero otherwise.
510 */
511static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
512{
513 struct i2c_client *c;
514 int retry;
515 int error;
516
517 c = v4l2_get_subdevdata(sd);
518
519 for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
520 error = i2c_smbus_write_byte_data(c, addr, value);
521
522 if (error >= 0)
523 return 0;
524
525 v4l2_warn(sd, "Write: retry ... %d\n", retry);
526 msleep_interruptible(10);
527 }
528 v4l2_err(sd, "TVP7002 write error %d\n", error);
529 return error;
530}
531
532/*
533 * tvp7002_write_err() - Write a register value with error code
534 * @sd: pointer to standard V4L2 sub-device structure
535 * @reg: destination register
536 * @val: value to be written
537 * @error: pointer to error value
538 *
539 * Write a value in a register and save error value in pointer.
540 * Also update the register table if successful
541 */
542static inline void tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
543 u8 val, int *err)
544{
545 if (!*err)
546 *err = tvp7002_write(sd, reg, val);
547}
548
549/*
550 * tvp7002_g_chip_ident() - Get chip identification number
551 * @sd: ptr to v4l2_subdev struct
552 * @chip: ptr to v4l2_dbg_chip_ident struct
553 *
554 * Obtains the chip's identification number.
555 * Returns zero or -EINVAL if read operation fails.
556 */
557static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
558 struct v4l2_dbg_chip_ident *chip)
559{
560 u8 rev;
561 int error;
562 struct i2c_client *client = v4l2_get_subdevdata(sd);
563
564 error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
565
566 if (error < 0)
567 return error;
568
569 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
570}
571
572/*
573 * tvp7002_write_inittab() - Write initialization values
574 * @sd: ptr to v4l2_subdev struct
575 * @regs: ptr to i2c_reg_value struct
576 *
577 * Write initialization values.
578 * Returns zero or -EINVAL if read operation fails.
579 */
580static int tvp7002_write_inittab(struct v4l2_subdev *sd,
581 const struct i2c_reg_value *regs)
582{
583 int error = 0;
584
585 /* Initialize the first (defined) registers */
586 while (TVP7002_EOR != regs->reg) {
587 if (TVP7002_WRITE == regs->type)
588 tvp7002_write_err(sd, regs->reg, regs->value, &error);
589 regs++;
590 }
591
592 return error;
593}
594
595/*
596 * tvp7002_s_dv_preset() - Set digital video preset
597 * @sd: ptr to v4l2_subdev struct
598 * @std: ptr to v4l2_dv_preset struct
599 *
600 * Set the digital video preset for a TVP7002 decoder device.
601 * Returns zero when successful or -EINVAL if register access fails.
602 */
603static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
604 struct v4l2_dv_preset *dv_preset)
605{
606 struct tvp7002 *device = to_tvp7002(sd);
607 u32 preset;
608 int i;
609
610 for (i = 0; i < NUM_PRESETS; i++) {
611 preset = tvp7002_presets[i].preset;
612 if (preset == dv_preset->preset) {
613 device->current_preset = &tvp7002_presets[i];
614 return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
615 }
616 }
617
618 return -EINVAL;
619}
620
621/*
622 * tvp7002_g_ctrl() - Get a control
623 * @sd: ptr to v4l2_subdev struct
624 * @ctrl: ptr to v4l2_control struct
625 *
626 * Get a control for a TVP7002 decoder device.
627 * Returns zero when successful or -EINVAL if register access fails.
628 */
629static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
630{
631 struct tvp7002 *device = to_tvp7002(sd);
632
633 switch (ctrl->id) {
634 case V4L2_CID_GAIN:
635 ctrl->value = device->gain;
636 return 0;
637 default:
638 return -EINVAL;
639 }
640}
641
642/*
643 * tvp7002_s_ctrl() - Set a control
644 * @sd: ptr to v4l2_subdev struct
645 * @ctrl: ptr to v4l2_control struct
646 *
647 * Set a control in TVP7002 decoder device.
648 * Returns zero when successful or -EINVAL if register access fails.
649 */
650static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
651{
652 struct tvp7002 *device = to_tvp7002(sd);
653 int error = 0;
654
655 switch (ctrl->id) {
656 case V4L2_CID_GAIN:
657 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN,
658 ctrl->value & 0xff, &error);
659 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN,
660 ctrl->value & 0xff, &error);
661 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
662 ctrl->value & 0xff, &error);
663
664 if (error < 0)
665 return error;
666
667 /* Set only after knowing there is no error */
668 device->gain = ctrl->value & 0xff;
669 return 0;
670 default:
671 return -EINVAL;
672 }
673}
674
675/*
676 * tvp7002_queryctrl() - Query a control
677 * @sd: ptr to v4l2_subdev struct
678 * @ctrl: ptr to v4l2_queryctrl struct
679 *
680 * Query a control of a TVP7002 decoder device.
681 * Returns zero when successful or -EINVAL if register read fails.
682 */
683static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
684{
685 switch (qc->id) {
686 case V4L2_CID_GAIN:
687 /*
688 * Gain is supported [0-255, default=0, step=1]
689 */
690 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
691 default:
692 return -EINVAL;
693 }
694}
695
696/*
697 * tvp7002_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
698 * @sd: pointer to standard V4L2 sub-device structure
699 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
700 *
701 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
702 * ioctl is used to negotiate the image capture size and pixel format
703 * without actually making it take effect.
704 */
705static int tvp7002_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
706{
707 struct tvp7002 *device = to_tvp7002(sd);
708 struct v4l2_dv_enum_preset e_preset;
709 struct v4l2_pix_format *pix;
710 int error = 0;
711
712 pix = &f->fmt.pix;
713
714 /* Calculate height and width based on current standard */
715 error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
716 if (error)
717 return -EINVAL;
718
719 pix->width = e_preset.width;
720 pix->height = e_preset.height;
721 pix->pixelformat = V4L2_PIX_FMT_UYVY;
722 pix->field = device->current_preset->scanmode;
723 pix->bytesperline = pix->width * 2;
724 pix->sizeimage = pix->bytesperline * pix->height;
725 pix->colorspace = device->current_preset->color_space;
726 pix->priv = 0;
727
728 v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
729 "Width - %d, Height - %d", "8-bit UYVY 4:2:2 Format",
730 pix->bytesperline, pix->width, pix->height);
731 return error;
732}
733
734/*
735 * tvp7002_s_fmt() - V4L2 decoder interface handler for s_fmt
736 * @sd: pointer to standard V4L2 sub-device structure
737 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
738 *
739 * If the requested format is supported, configures the HW to use that
740 * format, returns error code if format not supported or HW can't be
741 * correctly configured.
742 */
743static int tvp7002_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
744{
745 struct tvp7002 *decoder = to_tvp7002(sd);
746 int rval;
747
748 rval = tvp7002_try_fmt_cap(sd, f);
749 if (!rval)
750 decoder->pix = f->fmt.pix;
751 return rval;
752}
753
754/*
755 * tvp7002_g_fmt() - V4L2 decoder interface handler for tvp7002_g_fmt
756 * @sd: pointer to standard V4L2 sub-device structure
757 * @f: pointer to standard V4L2 v4l2_format structure
758 *
759 * Returns the decoder's current pixel format in the v4l2_format
760 * parameter.
761 */
762static int tvp7002_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
763{
764 struct tvp7002 *decoder = to_tvp7002(sd);
765
766 f->fmt.pix = decoder->pix;
767
768 v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
769 "Width - %d, Height - %d",
770 decoder->pix.bytesperline,
771 decoder->pix.width, decoder->pix.height);
772 return 0;
773}
774
775/*
776 * tvp7002_query_dv_preset() - query DV preset
777 * @sd: pointer to standard V4L2 sub-device structure
778 * @std_id: standard V4L2 v4l2_dv_preset
779 *
780 * Returns the current DV preset by TVP7002. If no active input is
781 * detected, returns -EINVAL
782 */
783static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
784 struct v4l2_dv_preset *qpreset)
785{
786 const struct tvp7002_preset_definition *presets = tvp7002_presets;
787 struct v4l2_dv_enum_preset e_preset;
788 struct tvp7002 *device;
789 u8 progressive;
790 u32 lpfr;
791 u32 cpln;
792 int error = 0;
793 u8 lpf_lsb;
794 u8 lpf_msb;
795 u8 cpl_lsb;
796 u8 cpl_msb;
797 int index;
798
799 device = to_tvp7002(sd);
800
801 /* Read standards from device registers */
802 tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error);
803 tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_MSBS, &lpf_msb, &error);
804
805 if (error < 0)
806 return error;
807
808 tvp7002_read_err(sd, TVP7002_CLK_L_STAT_LSBS, &cpl_lsb, &error);
809 tvp7002_read_err(sd, TVP7002_CLK_L_STAT_MSBS, &cpl_msb, &error);
810
811 if (error < 0)
812 return error;
813
814 /* Get lines per frame, clocks per line and interlaced/progresive */
815 lpfr = lpf_lsb | ((TVP7002_CL_MASK & lpf_msb) << TVP7002_CL_SHIFT);
816 cpln = cpl_lsb | ((TVP7002_CL_MASK & cpl_msb) << TVP7002_CL_SHIFT);
817 progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT;
818
819 /* Do checking of video modes */
820 for (index = 0; index < NUM_PRESETS; index++, presets++)
821 if (lpfr == presets->lines_per_frame &&
822 progressive == presets->progressive) {
823 if (presets->cpl_min == 0xffff)
824 break;
825 if (cpln >= presets->cpl_min && cpln <= presets->cpl_max)
826 break;
827 }
828
829 if (index == NUM_PRESETS) {
830 v4l2_err(sd, "querystd error, lpf = %x, cpl = %x\n",
831 lpfr, cpln);
832 return -EINVAL;
833 }
834
835 if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
836 return -EINVAL;
837
838 /* Set values in found preset */
839 qpreset->preset = presets->preset;
840
841 /* Update lines per frame and clocks per line info */
842 v4l2_dbg(1, debug, sd, "Current preset: %d %d",
843 e_preset.width, e_preset.height);
844 return 0;
845}
846
847#ifdef CONFIG_VIDEO_ADV_DEBUG
848/*
849 * tvp7002_g_register() - Get the value of a register
850 * @sd: ptr to v4l2_subdev struct
851 * @vreg: ptr to v4l2_dbg_register struct
852 *
853 * Get the value of a TVP7002 decoder device register.
854 * Returns zero when successful, -EINVAL if register read fails or
855 * access to I2C client fails, -EPERM if the call is not allowed
856 * by diabled CAP_SYS_ADMIN.
857 */
858static int tvp7002_g_register(struct v4l2_subdev *sd,
859 struct v4l2_dbg_register *reg)
860{
861 struct i2c_client *client = v4l2_get_subdevdata(sd);
862 u8 val;
863 int ret;
864
865 if (!v4l2_chip_match_i2c_client(client, &reg->match))
866 return -EINVAL;
867 if (!capable(CAP_SYS_ADMIN))
868 return -EPERM;
869
870 ret = tvp7002_read(sd, reg->reg & 0xff, &val);
871 reg->val = val;
872 return ret;
873}
874
875/*
876 * tvp7002_s_register() - set a control
877 * @sd: ptr to v4l2_subdev struct
878 * @ctrl: ptr to v4l2_control struct
879 *
880 * Get the value of a TVP7002 decoder device register.
881 * Returns zero when successful, -EINVAL if register read fails or
882 * -EPERM if call not allowed.
883 */
884static int tvp7002_s_register(struct v4l2_subdev *sd,
885 struct v4l2_dbg_register *reg)
886{
887 struct i2c_client *client = v4l2_get_subdevdata(sd);
888
889 if (!v4l2_chip_match_i2c_client(client, &reg->match))
890 return -EINVAL;
891 if (!capable(CAP_SYS_ADMIN))
892 return -EPERM;
893
894 return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
895}
896#endif
897
898/*
899 * tvp7002_enum_fmt() - Enum supported formats
900 * @sd: pointer to standard V4L2 sub-device structure
901 * @enable: pointer to format struct
902 *
903 * Enumerate supported formats.
904 */
905
906static int tvp7002_enum_fmt(struct v4l2_subdev *sd,
907 struct v4l2_fmtdesc *fmtdesc)
908{
909 /* Check requested format index is within range */
910 if (fmtdesc->index < 0 || fmtdesc->index >= NUM_FORMATS)
911 return -EINVAL;
912 *fmtdesc = tvp7002_fmt_list[fmtdesc->index];
913
914 return 0;
915}
916
917/*
918 * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream
919 * @sd: pointer to standard V4L2 sub-device structure
920 * @enable: streaming enable or disable
921 *
922 * Sets streaming to enable or disable, if possible.
923 */
924static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
925{
926 struct tvp7002 *device = to_tvp7002(sd);
927 int error = 0;
928
929 if (device->streaming == enable)
930 return 0;
931
932 if (enable) {
933 /* Set output state on (low impedance means stream on) */
934 error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
935 device->streaming = enable;
936 } else {
937 /* Set output state off (high impedance means stream off) */
938 error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
939 if (error)
940 v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
941
942 device->streaming = enable;
943 }
944
945 return error;
946}
947
948/*
949 * tvp7002_log_status() - Print information about register settings
950 * @sd: ptr to v4l2_subdev struct
951 *
952 * Log register values of a TVP7002 decoder device.
953 * Returns zero or -EINVAL if read operation fails.
954 */
955static int tvp7002_log_status(struct v4l2_subdev *sd)
956{
957 const struct tvp7002_preset_definition *presets = tvp7002_presets;
958 struct tvp7002 *device = to_tvp7002(sd);
959 struct v4l2_dv_enum_preset e_preset;
960 struct v4l2_dv_preset detected;
961 int i;
962
963 detected.preset = V4L2_DV_INVALID;
964 /* Find my current standard*/
965 tvp7002_query_dv_preset(sd, &detected);
966
967 /* Print standard related code values */
968 for (i = 0; i < NUM_PRESETS; i++, presets++)
969 if (presets->preset == detected.preset)
970 break;
971
972 if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset))
973 return -EINVAL;
974
975 v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name);
976 v4l2_info(sd, " Pixels per line: %u\n", e_preset.width);
977 v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height);
978 if (i == NUM_PRESETS) {
979 v4l2_info(sd, "Detected DV Preset: None\n");
980 } else {
981 if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
982 return -EINVAL;
983 v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name);
984 v4l2_info(sd, " Pixels per line: %u\n", e_preset.width);
985 v4l2_info(sd, " Lines per frame: %u\n\n", e_preset.height);
986 }
987 v4l2_info(sd, "Streaming enabled: %s\n",
988 device->streaming ? "yes" : "no");
989
990 /* Print the current value of the gain control */
991 v4l2_info(sd, "Gain: %u\n", device->gain);
992
993 return 0;
994}
995
996/* V4L2 core operation handlers */
997static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
998 .g_chip_ident = tvp7002_g_chip_ident,
999 .log_status = tvp7002_log_status,
1000 .g_ctrl = tvp7002_g_ctrl,
1001 .s_ctrl = tvp7002_s_ctrl,
1002 .queryctrl = tvp7002_queryctrl,
1003#ifdef CONFIG_VIDEO_ADV_DEBUG
1004 .g_register = tvp7002_g_register,
1005 .s_register = tvp7002_s_register,
1006#endif
1007};
1008
1009/* Specific video subsystem operation handlers */
1010static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
1011 .s_dv_preset = tvp7002_s_dv_preset,
1012 .query_dv_preset = tvp7002_query_dv_preset,
1013 .s_stream = tvp7002_s_stream,
1014 .g_fmt = tvp7002_g_fmt,
1015 .s_fmt = tvp7002_s_fmt,
1016 .enum_fmt = tvp7002_enum_fmt,
1017};
1018
1019/* V4L2 top level operation handlers */
1020static const struct v4l2_subdev_ops tvp7002_ops = {
1021 .core = &tvp7002_core_ops,
1022 .video = &tvp7002_video_ops,
1023};
1024
1025static struct tvp7002 tvp7002_dev = {
1026 .streaming = 0,
1027
1028 .pix = {
1029 .width = 1280,
1030 .height = 720,
1031 .pixelformat = V4L2_PIX_FMT_UYVY,
1032 .field = V4L2_FIELD_NONE,
1033 .bytesperline = 1280 * 2,
1034 .sizeimage = 1280 * 2 * 720,
1035 .colorspace = V4L2_COLORSPACE_REC709,
1036 },
1037
1038 .current_preset = tvp7002_presets,
1039 .gain = 0,
1040};
1041
1042/*
1043 * tvp7002_probe - Probe a TVP7002 device
1044 * @sd: ptr to v4l2_subdev struct
1045 * @ctrl: ptr to i2c_device_id struct
1046 *
1047 * Initialize the TVP7002 device
1048 * Returns zero when successful, -EINVAL if register read fails or
1049 * -EIO if i2c access is not available.
1050 */
1051static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1052{
1053 struct v4l2_subdev *sd;
1054 struct tvp7002 *device;
1055 struct v4l2_dv_preset preset;
1056 int polarity_a;
1057 int polarity_b;
1058 u8 revision;
1059
1060 int error;
1061
1062 /* Check if the adapter supports the needed features */
1063 if (!i2c_check_functionality(c->adapter,
1064 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
1065 return -EIO;
1066
1067 if (!c->dev.platform_data) {
1068 v4l_err(c, "No platform data!!\n");
1069 return -ENODEV;
1070 }
1071
1072 device = kmalloc(sizeof(struct tvp7002), GFP_KERNEL);
1073
1074 if (!device)
1075 return -ENOMEM;
1076
1077 *device = tvp7002_dev;
1078 sd = &device->sd;
1079 device->pdata = c->dev.platform_data;
1080
1081 /* Tell v4l2 the device is ready */
1082 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
1083 v4l_info(c, "tvp7002 found @ 0x%02x (%s)\n",
1084 c->addr, c->adapter->name);
1085
1086 error = tvp7002_read(sd, TVP7002_CHIP_REV, &revision);
1087 if (error < 0)
1088 goto found_error;
1089
1090 /* Get revision number */
1091 v4l2_info(sd, "Rev. %02x detected.\n", revision);
1092 if (revision != 0x02)
1093 v4l2_info(sd, "Unknown revision detected.\n");
1094
1095 /* Initializes TVP7002 to its default values */
1096 error = tvp7002_write_inittab(sd, tvp7002_init_default);
1097
1098 if (error < 0)
1099 goto found_error;
1100
1101 /* Set polarity information after registers have been set */
1102 polarity_a = 0x20 | device->pdata->hs_polarity << 5
1103 | device->pdata->vs_polarity << 2;
1104 error = tvp7002_write(sd, TVP7002_SYNC_CTL_1, polarity_a);
1105 if (error < 0)
1106 goto found_error;
1107
1108 polarity_b = 0x01 | device->pdata->fid_polarity << 2
1109 | device->pdata->sog_polarity << 1
1110 | device->pdata->clk_polarity;
1111 error = tvp7002_write(sd, TVP7002_MISC_CTL_3, polarity_b);
1112 if (error < 0)
1113 goto found_error;
1114
1115 /* Set registers according to default video mode */
1116 preset.preset = device->current_preset->preset;
1117 error = tvp7002_s_dv_preset(sd, &preset);
1118
1119found_error:
1120 if (error < 0)
1121 kfree(device);
1122
1123 return error;
1124}
1125
1126/*
1127 * tvp7002_remove - Remove TVP7002 device support
1128 * @c: ptr to i2c_client struct
1129 *
1130 * Reset the TVP7002 device
1131 * Returns zero.
1132 */
1133static int tvp7002_remove(struct i2c_client *c)
1134{
1135 struct v4l2_subdev *sd = i2c_get_clientdata(c);
1136 struct tvp7002 *device = to_tvp7002(sd);
1137
1138 v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
1139 "on address 0x%x\n", c->addr);
1140
1141 v4l2_device_unregister_subdev(sd);
1142 kfree(device);
1143 return 0;
1144}
1145
1146/* I2C Device ID table */
1147static const struct i2c_device_id tvp7002_id[] = {
1148 { "tvp7002", 0 },
1149 { }
1150};
1151MODULE_DEVICE_TABLE(i2c, tvp7002_id);
1152
1153/* I2C driver data */
1154static struct i2c_driver tvp7002_driver = {
1155 .driver = {
1156 .owner = THIS_MODULE,
1157 .name = TVP7002_MODULE_NAME,
1158 },
1159 .probe = tvp7002_probe,
1160 .remove = tvp7002_remove,
1161 .id_table = tvp7002_id,
1162};
1163
1164/*
1165 * tvp7002_init - Initialize driver via I2C interface
1166 *
1167 * Register the TVP7002 driver.
1168 * Return 0 on success or error code on failure.
1169 */
1170static int __init tvp7002_init(void)
1171{
1172 return i2c_add_driver(&tvp7002_driver);
1173}
1174
1175/*
1176 * tvp7002_exit - Remove driver via I2C interface
1177 *
1178 * Unregister the TVP7002 driver.
1179 * Returns nothing.
1180 */
1181static void __exit tvp7002_exit(void)
1182{
1183 i2c_del_driver(&tvp7002_driver);
1184}
1185
1186module_init(tvp7002_init);
1187module_exit(tvp7002_exit);
diff --git a/drivers/media/video/tvp7002_reg.h b/drivers/media/video/tvp7002_reg.h
new file mode 100644
index 000000000000..0e34ca9bccf3
--- /dev/null
+++ b/drivers/media/video/tvp7002_reg.h
@@ -0,0 +1,150 @@
1/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
2 * Digitizer with Horizontal PLL registers
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
6 *
7 * This code is partially based upon the TVP5150 driver
8 * written by Mauro Carvalho Chehab (mchehab@infradead.org),
9 * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
10 * and the TVP7002 driver in the TI LSP 2.10.00.14
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27/* Naming conventions
28 * ------------------
29 *
30 * FDBK: Feedback
31 * DIV: Divider
32 * CTL: Control
33 * SEL: Select
34 * IN: Input
35 * OUT: Output
36 * R: Red
37 * G: Green
38 * B: Blue
39 * OFF: Offset
40 * THRS: Threshold
41 * DGTL: Digital
42 * LVL: Level
43 * PWR: Power
44 * MVIS: Macrovision
45 * W: Width
46 * H: Height
47 * ALGN: Alignment
48 * CLK: Clocks
49 * TOL: Tolerance
50 * BWTH: Bandwidth
51 * COEF: Coefficient
52 * STAT: Status
53 * AUTO: Automatic
54 * FLD: Field
55 * L: Line
56 */
57
58#define TVP7002_CHIP_REV 0x00
59#define TVP7002_HPLL_FDBK_DIV_MSBS 0x01
60#define TVP7002_HPLL_FDBK_DIV_LSBS 0x02
61#define TVP7002_HPLL_CRTL 0x03
62#define TVP7002_HPLL_PHASE_SEL 0x04
63#define TVP7002_CLAMP_START 0x05
64#define TVP7002_CLAMP_W 0x06
65#define TVP7002_HSYNC_OUT_W 0x07
66#define TVP7002_B_FINE_GAIN 0x08
67#define TVP7002_G_FINE_GAIN 0x09
68#define TVP7002_R_FINE_GAIN 0x0a
69#define TVP7002_B_FINE_OFF_MSBS 0x0b
70#define TVP7002_G_FINE_OFF_MSBS 0x0c
71#define TVP7002_R_FINE_OFF_MSBS 0x0d
72#define TVP7002_SYNC_CTL_1 0x0e
73#define TVP7002_HPLL_AND_CLAMP_CTL 0x0f
74#define TVP7002_SYNC_ON_G_THRS 0x10
75#define TVP7002_SYNC_SEPARATOR_THRS 0x11
76#define TVP7002_HPLL_PRE_COAST 0x12
77#define TVP7002_HPLL_POST_COAST 0x13
78#define TVP7002_SYNC_DETECT_STAT 0x14
79#define TVP7002_OUT_FORMATTER 0x15
80#define TVP7002_MISC_CTL_1 0x16
81#define TVP7002_MISC_CTL_2 0x17
82#define TVP7002_MISC_CTL_3 0x18
83#define TVP7002_IN_MUX_SEL_1 0x19
84#define TVP7002_IN_MUX_SEL_2 0x1a
85#define TVP7002_B_AND_G_COARSE_GAIN 0x1b
86#define TVP7002_R_COARSE_GAIN 0x1c
87#define TVP7002_FINE_OFF_LSBS 0x1d
88#define TVP7002_B_COARSE_OFF 0x1e
89#define TVP7002_G_COARSE_OFF 0x1f
90#define TVP7002_R_COARSE_OFF 0x20
91#define TVP7002_HSOUT_OUT_START 0x21
92#define TVP7002_MISC_CTL_4 0x22
93#define TVP7002_B_DGTL_ALC_OUT_LSBS 0x23
94#define TVP7002_G_DGTL_ALC_OUT_LSBS 0x24
95#define TVP7002_R_DGTL_ALC_OUT_LSBS 0x25
96#define TVP7002_AUTO_LVL_CTL_ENABLE 0x26
97#define TVP7002_DGTL_ALC_OUT_MSBS 0x27
98#define TVP7002_AUTO_LVL_CTL_FILTER 0x28
99/* Reserved 0x29*/
100#define TVP7002_FINE_CLAMP_CTL 0x2a
101#define TVP7002_PWR_CTL 0x2b
102#define TVP7002_ADC_SETUP 0x2c
103#define TVP7002_COARSE_CLAMP_CTL 0x2d
104#define TVP7002_SOG_CLAMP 0x2e
105#define TVP7002_RGB_COARSE_CLAMP_CTL 0x2f
106#define TVP7002_SOG_COARSE_CLAMP_CTL 0x30
107#define TVP7002_ALC_PLACEMENT 0x31
108/* Reserved 0x32 */
109/* Reserved 0x33 */
110#define TVP7002_MVIS_STRIPPER_W 0x34
111#define TVP7002_VSYNC_ALGN 0x35
112#define TVP7002_SYNC_BYPASS 0x36
113#define TVP7002_L_FRAME_STAT_LSBS 0x37
114#define TVP7002_L_FRAME_STAT_MSBS 0x38
115#define TVP7002_CLK_L_STAT_LSBS 0x39
116#define TVP7002_CLK_L_STAT_MSBS 0x3a
117#define TVP7002_HSYNC_W 0x3b
118#define TVP7002_VSYNC_W 0x3c
119#define TVP7002_L_LENGTH_TOL 0x3d
120/* Reserved 0x3e */
121#define TVP7002_VIDEO_BWTH_CTL 0x3f
122#define TVP7002_AVID_START_PIXEL_LSBS 0x40
123#define TVP7002_AVID_START_PIXEL_MSBS 0x41
124#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42
125#define TVP7002_AVID_STOP_PIXEL_MSBS 0x43
126#define TVP7002_VBLK_F_0_START_L_OFF 0x44
127#define TVP7002_VBLK_F_1_START_L_OFF 0x45
128#define TVP7002_VBLK_F_0_DURATION 0x46
129#define TVP7002_VBLK_F_1_DURATION 0x47
130#define TVP7002_FBIT_F_0_START_L_OFF 0x48
131#define TVP7002_FBIT_F_1_START_L_OFF 0x49
132#define TVP7002_YUV_Y_G_COEF_LSBS 0x4a
133#define TVP7002_YUV_Y_G_COEF_MSBS 0x4b
134#define TVP7002_YUV_Y_B_COEF_LSBS 0x4c
135#define TVP7002_YUV_Y_B_COEF_MSBS 0x4d
136#define TVP7002_YUV_Y_R_COEF_LSBS 0x4e
137#define TVP7002_YUV_Y_R_COEF_MSBS 0x4f
138#define TVP7002_YUV_U_G_COEF_LSBS 0x50
139#define TVP7002_YUV_U_G_COEF_MSBS 0x51
140#define TVP7002_YUV_U_B_COEF_LSBS 0x52
141#define TVP7002_YUV_U_B_COEF_MSBS 0x53
142#define TVP7002_YUV_U_R_COEF_LSBS 0x54
143#define TVP7002_YUV_U_R_COEF_MSBS 0x55
144#define TVP7002_YUV_V_G_COEF_LSBS 0x56
145#define TVP7002_YUV_V_G_COEF_MSBS 0x57
146#define TVP7002_YUV_V_B_COEF_LSBS 0x58
147#define TVP7002_YUV_V_B_COEF_MSBS 0x59
148#define TVP7002_YUV_V_R_COEF_LSBS 0x5a
149#define TVP7002_YUV_V_R_COEF_MSBS 0x5b
150
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 5b801a6e1eea..76be733eabfd 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -233,10 +233,10 @@ struct tw9910_hsync_ctrl {
233}; 233};
234 234
235struct tw9910_priv { 235struct tw9910_priv {
236 struct v4l2_subdev subdev; 236 struct v4l2_subdev subdev;
237 struct tw9910_video_info *info; 237 struct tw9910_video_info *info;
238 const struct tw9910_scale_ctrl *scale; 238 const struct tw9910_scale_ctrl *scale;
239 u32 revision; 239 u32 revision;
240}; 240};
241 241
242static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { 242static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 1054546db908..7c17ec63c5da 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1487,7 +1487,7 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
1487 usbvision->vbi = usbvision_vdev_init(usbvision, 1487 usbvision->vbi = usbvision_vdev_init(usbvision,
1488 &usbvision_vbi_template, 1488 &usbvision_vbi_template,
1489 "USBVision VBI"); 1489 "USBVision VBI");
1490 if (usbvision->vdev == NULL) { 1490 if (usbvision->vbi == NULL) {
1491 goto err_exit; 1491 goto err_exit;
1492 } 1492 }
1493 if (video_register_device(usbvision->vbi, 1493 if (video_register_device(usbvision->vbi,
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index ec8ef8c5560a..3b2e7800d56f 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -23,9 +23,13 @@
23 23
24#include "uvcvideo.h" 24#include "uvcvideo.h"
25 25
26#define UVC_CTRL_NDATA 2
27#define UVC_CTRL_DATA_CURRENT 0 26#define UVC_CTRL_DATA_CURRENT 0
28#define UVC_CTRL_DATA_BACKUP 1 27#define UVC_CTRL_DATA_BACKUP 1
28#define UVC_CTRL_DATA_MIN 2
29#define UVC_CTRL_DATA_MAX 3
30#define UVC_CTRL_DATA_RES 4
31#define UVC_CTRL_DATA_DEF 5
32#define UVC_CTRL_DATA_LAST 6
29 33
30/* ------------------------------------------------------------------------ 34/* ------------------------------------------------------------------------
31 * Controls 35 * Controls
@@ -755,6 +759,49 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
755 return ctrl; 759 return ctrl;
756} 760}
757 761
762static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
763 struct uvc_control *ctrl)
764{
765 int ret;
766
767 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
768 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
769 chain->dev->intfnum, ctrl->info->selector,
770 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
771 ctrl->info->size);
772 if (ret < 0)
773 return ret;
774 }
775
776 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
777 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
778 chain->dev->intfnum, ctrl->info->selector,
779 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
780 ctrl->info->size);
781 if (ret < 0)
782 return ret;
783 }
784 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
785 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
786 chain->dev->intfnum, ctrl->info->selector,
787 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
788 ctrl->info->size);
789 if (ret < 0)
790 return ret;
791 }
792 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
793 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
794 chain->dev->intfnum, ctrl->info->selector,
795 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
796 ctrl->info->size);
797 if (ret < 0)
798 return ret;
799 }
800
801 ctrl->cached = 1;
802 return 0;
803}
804
758int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, 805int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
759 struct v4l2_queryctrl *v4l2_ctrl) 806 struct v4l2_queryctrl *v4l2_ctrl)
760{ 807{
@@ -762,17 +809,12 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
762 struct uvc_control_mapping *mapping; 809 struct uvc_control_mapping *mapping;
763 struct uvc_menu_info *menu; 810 struct uvc_menu_info *menu;
764 unsigned int i; 811 unsigned int i;
765 __u8 *data;
766 int ret; 812 int ret;
767 813
768 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); 814 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
769 if (ctrl == NULL) 815 if (ctrl == NULL)
770 return -EINVAL; 816 return -EINVAL;
771 817
772 data = kmalloc(ctrl->info->size, GFP_KERNEL);
773 if (data == NULL)
774 return -ENOMEM;
775
776 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); 818 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
777 v4l2_ctrl->id = mapping->id; 819 v4l2_ctrl->id = mapping->id;
778 v4l2_ctrl->type = mapping->v4l2_type; 820 v4l2_ctrl->type = mapping->v4l2_type;
@@ -782,14 +824,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
782 if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) 824 if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
783 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 825 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
784 826
785 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 827 if (!ctrl->cached) {
786 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, 828 ret = uvc_ctrl_populate_cache(chain, ctrl);
787 chain->dev->intfnum, ctrl->info->selector,
788 data, ctrl->info->size);
789 if (ret < 0) 829 if (ret < 0)
790 goto out; 830 return ret;
791 v4l2_ctrl->default_value = 831 }
792 mapping->get(mapping, UVC_GET_DEF, data); 832
833 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
834 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
835 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
793 } 836 }
794 837
795 switch (mapping->v4l2_type) { 838 switch (mapping->v4l2_type) {
@@ -806,56 +849,37 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
806 } 849 }
807 } 850 }
808 851
809 ret = 0; 852 return 0;
810 goto out;
811 853
812 case V4L2_CTRL_TYPE_BOOLEAN: 854 case V4L2_CTRL_TYPE_BOOLEAN:
813 v4l2_ctrl->minimum = 0; 855 v4l2_ctrl->minimum = 0;
814 v4l2_ctrl->maximum = 1; 856 v4l2_ctrl->maximum = 1;
815 v4l2_ctrl->step = 1; 857 v4l2_ctrl->step = 1;
816 ret = 0; 858 return 0;
817 goto out;
818 859
819 case V4L2_CTRL_TYPE_BUTTON: 860 case V4L2_CTRL_TYPE_BUTTON:
820 v4l2_ctrl->minimum = 0; 861 v4l2_ctrl->minimum = 0;
821 v4l2_ctrl->maximum = 0; 862 v4l2_ctrl->maximum = 0;
822 v4l2_ctrl->step = 0; 863 v4l2_ctrl->step = 0;
823 ret = 0; 864 return 0;
824 goto out;
825 865
826 default: 866 default:
827 break; 867 break;
828 } 868 }
829 869
830 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 870 if (ctrl->info->flags & UVC_CONTROL_GET_MIN)
831 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, 871 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
832 chain->dev->intfnum, ctrl->info->selector, 872 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
833 data, ctrl->info->size);
834 if (ret < 0)
835 goto out;
836 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
837 }
838 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
839 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
840 chain->dev->intfnum, ctrl->info->selector,
841 data, ctrl->info->size);
842 if (ret < 0)
843 goto out;
844 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
845 }
846 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
847 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
848 chain->dev->intfnum, ctrl->info->selector,
849 data, ctrl->info->size);
850 if (ret < 0)
851 goto out;
852 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
853 }
854 873
855 ret = 0; 874 if (ctrl->info->flags & UVC_CONTROL_GET_MAX)
856out: 875 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
857 kfree(data); 876 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
858 return ret; 877
878 if (ctrl->info->flags & UVC_CONTROL_GET_RES)
879 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
880 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
881
882 return 0;
859} 883}
860 884
861 885
@@ -997,19 +1021,57 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
997{ 1021{
998 struct uvc_control *ctrl; 1022 struct uvc_control *ctrl;
999 struct uvc_control_mapping *mapping; 1023 struct uvc_control_mapping *mapping;
1000 s32 value = xctrl->value; 1024 s32 value;
1025 u32 step;
1026 s32 min;
1027 s32 max;
1001 int ret; 1028 int ret;
1002 1029
1003 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1030 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1004 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) 1031 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
1005 return -EINVAL; 1032 return -EINVAL;
1006 1033
1007 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { 1034 /* Clamp out of range values. */
1008 if (value < 0 || value >= mapping->menu_count) 1035 switch (mapping->v4l2_type) {
1009 return -EINVAL; 1036 case V4L2_CTRL_TYPE_INTEGER:
1010 value = mapping->menu_info[value].value; 1037 if (!ctrl->cached) {
1038 ret = uvc_ctrl_populate_cache(chain, ctrl);
1039 if (ret < 0)
1040 return ret;
1041 }
1042
1043 min = mapping->get(mapping, UVC_GET_MIN,
1044 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
1045 max = mapping->get(mapping, UVC_GET_MAX,
1046 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
1047 step = mapping->get(mapping, UVC_GET_RES,
1048 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1049
1050 xctrl->value = min + (xctrl->value - min + step/2) / step * step;
1051 xctrl->value = clamp(xctrl->value, min, max);
1052 value = xctrl->value;
1053 break;
1054
1055 case V4L2_CTRL_TYPE_BOOLEAN:
1056 xctrl->value = clamp(xctrl->value, 0, 1);
1057 value = xctrl->value;
1058 break;
1059
1060 case V4L2_CTRL_TYPE_MENU:
1061 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
1062 return -ERANGE;
1063 value = mapping->menu_info[xctrl->value].value;
1064 break;
1065
1066 default:
1067 value = xctrl->value;
1068 break;
1011 } 1069 }
1012 1070
1071 /* If the mapping doesn't span the whole UVC control, the current value
1072 * needs to be loaded from the device to perform the read-modify-write
1073 * operation.
1074 */
1013 if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { 1075 if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) {
1014 if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { 1076 if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) {
1015 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1077 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
@@ -1027,6 +1089,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1027 ctrl->loaded = 1; 1089 ctrl->loaded = 1;
1028 } 1090 }
1029 1091
1092 /* Backup the current value in case we need to rollback later. */
1030 if (!ctrl->dirty) { 1093 if (!ctrl->dirty) {
1031 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1094 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1032 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1095 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
@@ -1080,10 +1143,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1080 } 1143 }
1081 1144
1082 if (!found) { 1145 if (!found) {
1083 uvc_trace(UVC_TRACE_CONTROL, 1146 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
1084 "Control " UVC_GUID_FORMAT "/%u not found.\n", 1147 entity->extension.guidExtensionCode, xctrl->selector);
1085 UVC_GUID_ARGS(entity->extension.guidExtensionCode),
1086 xctrl->selector);
1087 return -EINVAL; 1148 return -EINVAL;
1088 } 1149 }
1089 1150
@@ -1159,9 +1220,9 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
1159 (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) 1220 (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0)
1160 continue; 1221 continue;
1161 1222
1162 printk(KERN_INFO "restoring control " UVC_GUID_FORMAT 1223 printk(KERN_INFO "restoring control %pUl/%u/%u\n",
1163 "/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity), 1224 ctrl->info->entity, ctrl->info->index,
1164 ctrl->info->index, ctrl->info->selector); 1225 ctrl->info->selector);
1165 ctrl->dirty = 1; 1226 ctrl->dirty = 1;
1166 } 1227 }
1167 1228
@@ -1215,47 +1276,43 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
1215 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, 1276 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
1216 dev->intfnum, info->selector, (__u8 *)&size, 2); 1277 dev->intfnum, info->selector, (__u8 *)&size, 2);
1217 if (ret < 0) { 1278 if (ret < 0) {
1218 uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on " 1279 uvc_trace(UVC_TRACE_CONTROL,
1219 "control " UVC_GUID_FORMAT "/%u (%d).\n", 1280 "GET_LEN failed on control %pUl/%u (%d).\n",
1220 UVC_GUID_ARGS(info->entity), info->selector, 1281 info->entity, info->selector, ret);
1221 ret);
1222 return; 1282 return;
1223 } 1283 }
1224 1284
1225 if (info->size != le16_to_cpu(size)) { 1285 if (info->size != le16_to_cpu(size)) {
1226 uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT 1286 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size "
1227 "/%u size doesn't match user supplied " 1287 "doesn't match user supplied value.\n",
1228 "value.\n", UVC_GUID_ARGS(info->entity), 1288 info->entity, info->selector);
1229 info->selector);
1230 return; 1289 return;
1231 } 1290 }
1232 1291
1233 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, 1292 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
1234 dev->intfnum, info->selector, &inf, 1); 1293 dev->intfnum, info->selector, &inf, 1);
1235 if (ret < 0) { 1294 if (ret < 0) {
1236 uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on " 1295 uvc_trace(UVC_TRACE_CONTROL,
1237 "control " UVC_GUID_FORMAT "/%u (%d).\n", 1296 "GET_INFO failed on control %pUl/%u (%d).\n",
1238 UVC_GUID_ARGS(info->entity), info->selector, 1297 info->entity, info->selector, ret);
1239 ret);
1240 return; 1298 return;
1241 } 1299 }
1242 1300
1243 flags = info->flags; 1301 flags = info->flags;
1244 if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) || 1302 if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) ||
1245 ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) { 1303 ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) {
1246 uvc_trace(UVC_TRACE_CONTROL, "Control " 1304 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags "
1247 UVC_GUID_FORMAT "/%u flags don't match " 1305 "don't match supported operations.\n",
1248 "supported operations.\n", 1306 info->entity, info->selector);
1249 UVC_GUID_ARGS(info->entity), info->selector);
1250 return; 1307 return;
1251 } 1308 }
1252 } 1309 }
1253 1310
1254 ctrl->info = info; 1311 ctrl->info = info;
1255 ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL); 1312 ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_DATA_LAST, GFP_KERNEL);
1256 uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u " 1313 uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
1257 "to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity), 1314 "entity %u\n", ctrl->info->entity, ctrl->info->selector,
1258 ctrl->info->selector, dev->udev->devpath, entity->id); 1315 dev->udev->devpath, entity->id);
1259} 1316}
1260 1317
1261/* 1318/*
@@ -1281,17 +1338,16 @@ int uvc_ctrl_add_info(struct uvc_control_info *info)
1281 continue; 1338 continue;
1282 1339
1283 if (ctrl->selector == info->selector) { 1340 if (ctrl->selector == info->selector) {
1284 uvc_trace(UVC_TRACE_CONTROL, "Control " 1341 uvc_trace(UVC_TRACE_CONTROL,
1285 UVC_GUID_FORMAT "/%u is already defined.\n", 1342 "Control %pUl/%u is already defined.\n",
1286 UVC_GUID_ARGS(info->entity), info->selector); 1343 info->entity, info->selector);
1287 ret = -EEXIST; 1344 ret = -EEXIST;
1288 goto end; 1345 goto end;
1289 } 1346 }
1290 if (ctrl->index == info->index) { 1347 if (ctrl->index == info->index) {
1291 uvc_trace(UVC_TRACE_CONTROL, "Control " 1348 uvc_trace(UVC_TRACE_CONTROL,
1292 UVC_GUID_FORMAT "/%u would overwrite index " 1349 "Control %pUl/%u would overwrite index %d.\n",
1293 "%d.\n", UVC_GUID_ARGS(info->entity), 1350 info->entity, info->selector, info->index);
1294 info->selector, info->index);
1295 ret = -EEXIST; 1351 ret = -EEXIST;
1296 goto end; 1352 goto end;
1297 } 1353 }
@@ -1332,10 +1388,9 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
1332 continue; 1388 continue;
1333 1389
1334 if (info->size * 8 < mapping->size + mapping->offset) { 1390 if (info->size * 8 < mapping->size + mapping->offset) {
1335 uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would " 1391 uvc_trace(UVC_TRACE_CONTROL,
1336 "overflow control " UVC_GUID_FORMAT "/%u\n", 1392 "Mapping '%s' would overflow control %pUl/%u\n",
1337 mapping->name, UVC_GUID_ARGS(info->entity), 1393 mapping->name, info->entity, info->selector);
1338 info->selector);
1339 ret = -EOVERFLOW; 1394 ret = -EOVERFLOW;
1340 goto end; 1395 goto end;
1341 } 1396 }
@@ -1354,9 +1409,9 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
1354 1409
1355 mapping->ctrl = info; 1410 mapping->ctrl = info;
1356 list_add_tail(&mapping->list, &info->mappings); 1411 list_add_tail(&mapping->list, &info->mappings);
1357 uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control " 1412 uvc_trace(UVC_TRACE_CONTROL,
1358 UVC_GUID_FORMAT "/%u.\n", mapping->name, 1413 "Adding mapping %s to control %pUl/%u.\n",
1359 UVC_GUID_ARGS(info->entity), info->selector); 1414 mapping->name, info->entity, info->selector);
1360 1415
1361 ret = 0; 1416 ret = 0;
1362 break; 1417 break;
@@ -1378,6 +1433,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
1378 struct usb_device_id id; 1433 struct usb_device_id id;
1379 u8 index; 1434 u8 index;
1380 } blacklist[] = { 1435 } blacklist[] = {
1436 { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */
1381 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ 1437 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
1382 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ 1438 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
1383 }; 1439 };
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 391cccca7ffc..a814820a3f6e 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -43,8 +43,9 @@
43#define DRIVER_VERSION "v0.1.0" 43#define DRIVER_VERSION "v0.1.0"
44#endif 44#endif
45 45
46unsigned int uvc_clock_param = CLOCK_MONOTONIC;
46unsigned int uvc_no_drop_param; 47unsigned int uvc_no_drop_param;
47static unsigned int uvc_quirks_param; 48static unsigned int uvc_quirks_param = -1;
48unsigned int uvc_trace_param; 49unsigned int uvc_trace_param;
49unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT; 50unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
50 51
@@ -59,6 +60,11 @@ static struct uvc_format_desc uvc_fmts[] = {
59 .fcc = V4L2_PIX_FMT_YUYV, 60 .fcc = V4L2_PIX_FMT_YUYV,
60 }, 61 },
61 { 62 {
63 .name = "YUV 4:2:2 (YUYV)",
64 .guid = UVC_GUID_FORMAT_YUY2_ISIGHT,
65 .fcc = V4L2_PIX_FMT_YUYV,
66 },
67 {
62 .name = "YUV 4:2:0 (NV12)", 68 .name = "YUV 4:2:0 (NV12)",
63 .guid = UVC_GUID_FORMAT_NV12, 69 .guid = UVC_GUID_FORMAT_NV12,
64 .fcc = V4L2_PIX_FMT_NV12, 70 .fcc = V4L2_PIX_FMT_NV12,
@@ -309,11 +315,10 @@ static int uvc_parse_format(struct uvc_device *dev,
309 sizeof format->name); 315 sizeof format->name);
310 format->fcc = fmtdesc->fcc; 316 format->fcc = fmtdesc->fcc;
311 } else { 317 } else {
312 uvc_printk(KERN_INFO, "Unknown video format " 318 uvc_printk(KERN_INFO, "Unknown video format %pUl\n",
313 UVC_GUID_FORMAT "\n", 319 &buffer[5]);
314 UVC_GUID_ARGS(&buffer[5])); 320 snprintf(format->name, sizeof(format->name), "%pUl\n",
315 snprintf(format->name, sizeof format->name, 321 &buffer[5]);
316 UVC_GUID_FORMAT, UVC_GUID_ARGS(&buffer[5]));
317 format->fcc = 0; 322 format->fcc = 0;
318 } 323 }
319 324
@@ -1750,7 +1755,8 @@ static int uvc_probe(struct usb_interface *intf,
1750 dev->udev = usb_get_dev(udev); 1755 dev->udev = usb_get_dev(udev);
1751 dev->intf = usb_get_intf(intf); 1756 dev->intf = usb_get_intf(intf);
1752 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; 1757 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
1753 dev->quirks = id->driver_info | uvc_quirks_param; 1758 dev->quirks = (uvc_quirks_param == -1)
1759 ? id->driver_info : uvc_quirks_param;
1754 1760
1755 if (udev->product != NULL) 1761 if (udev->product != NULL)
1756 strlcpy(dev->name, udev->product, sizeof dev->name); 1762 strlcpy(dev->name, udev->product, sizeof dev->name);
@@ -1773,9 +1779,9 @@ static int uvc_probe(struct usb_interface *intf,
1773 le16_to_cpu(udev->descriptor.idVendor), 1779 le16_to_cpu(udev->descriptor.idVendor),
1774 le16_to_cpu(udev->descriptor.idProduct)); 1780 le16_to_cpu(udev->descriptor.idProduct));
1775 1781
1776 if (uvc_quirks_param != 0) { 1782 if (dev->quirks != id->driver_info) {
1777 uvc_printk(KERN_INFO, "Forcing device quirks 0x%x by module " 1783 uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
1778 "parameter for testing purpose.\n", uvc_quirks_param); 1784 "parameter for testing purpose.\n", dev->quirks);
1779 uvc_printk(KERN_INFO, "Please report required quirks to the " 1785 uvc_printk(KERN_INFO, "Please report required quirks to the "
1780 "linux-uvc-devel mailing list.\n"); 1786 "linux-uvc-devel mailing list.\n");
1781 } 1787 }
@@ -1892,6 +1898,45 @@ static int uvc_reset_resume(struct usb_interface *intf)
1892} 1898}
1893 1899
1894/* ------------------------------------------------------------------------ 1900/* ------------------------------------------------------------------------
1901 * Module parameters
1902 */
1903
1904static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
1905{
1906 if (uvc_clock_param == CLOCK_MONOTONIC)
1907 return sprintf(buffer, "CLOCK_MONOTONIC");
1908 else
1909 return sprintf(buffer, "CLOCK_REALTIME");
1910}
1911
1912static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
1913{
1914 if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
1915 val += strlen("clock_");
1916
1917 if (strcasecmp(val, "monotonic") == 0)
1918 uvc_clock_param = CLOCK_MONOTONIC;
1919 else if (strcasecmp(val, "realtime") == 0)
1920 uvc_clock_param = CLOCK_REALTIME;
1921 else
1922 return -EINVAL;
1923
1924 return 0;
1925}
1926
1927module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
1928 &uvc_clock_param, S_IRUGO|S_IWUSR);
1929MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
1930module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
1931MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
1932module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
1933MODULE_PARM_DESC(quirks, "Forced device quirks");
1934module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
1935MODULE_PARM_DESC(trace, "Trace level bitmask");
1936module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
1937MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
1938
1939/* ------------------------------------------------------------------------
1895 * Driver initialization and cleanup 1940 * Driver initialization and cleanup
1896 */ 1941 */
1897 1942
@@ -2197,15 +2242,6 @@ static void __exit uvc_cleanup(void)
2197module_init(uvc_init); 2242module_init(uvc_init);
2198module_exit(uvc_cleanup); 2243module_exit(uvc_cleanup);
2199 2244
2200module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
2201MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
2202module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2203MODULE_PARM_DESC(quirks, "Forced device quirks");
2204module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
2205MODULE_PARM_DESC(trace, "Trace level bitmask");
2206module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
2207MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
2208
2209MODULE_AUTHOR(DRIVER_AUTHOR); 2245MODULE_AUTHOR(DRIVER_AUTHOR);
2210MODULE_DESCRIPTION(DRIVER_DESC); 2246MODULE_DESCRIPTION(DRIVER_DESC);
2211MODULE_LICENSE("GPL"); 2247MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index ea11839cba4a..4a925a31b0e0 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -502,7 +502,6 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
502 spin_unlock_irqrestore(&queue->irqlock, flags); 502 spin_unlock_irqrestore(&queue->irqlock, flags);
503 503
504 buf->buf.sequence = queue->sequence++; 504 buf->buf.sequence = queue->sequence++;
505 do_gettimeofday(&buf->buf.timestamp);
506 505
507 wake_up(&buf->wait); 506 wake_up(&buf->wait);
508 return nextbuf; 507 return nextbuf;
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 23239a4adefe..43152aa52227 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -539,7 +539,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
539 xctrl.id = ctrl->id; 539 xctrl.id = ctrl->id;
540 xctrl.value = ctrl->value; 540 xctrl.value = ctrl->value;
541 541
542 uvc_ctrl_begin(chain); 542 ret = uvc_ctrl_begin(chain);
543 if (ret < 0) 543 if (ret < 0)
544 return ret; 544 return ret;
545 545
@@ -549,6 +549,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
549 return ret; 549 return ret;
550 } 550 }
551 ret = uvc_ctrl_commit(chain); 551 ret = uvc_ctrl_commit(chain);
552 if (ret == 0)
553 ctrl->value = xctrl.value;
552 break; 554 break;
553 } 555 }
554 556
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 7dcf534a0cf3..6b0666be370f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -410,6 +410,8 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
410 * when the EOF bit is set to force synchronisation on the next packet. 410 * when the EOF bit is set to force synchronisation on the next packet.
411 */ 411 */
412 if (buf->state != UVC_BUF_STATE_ACTIVE) { 412 if (buf->state != UVC_BUF_STATE_ACTIVE) {
413 struct timespec ts;
414
413 if (fid == stream->last_fid) { 415 if (fid == stream->last_fid) {
414 uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " 416 uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
415 "sync).\n"); 417 "sync).\n");
@@ -419,6 +421,14 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
419 return -ENODATA; 421 return -ENODATA;
420 } 422 }
421 423
424 if (uvc_clock_param == CLOCK_MONOTONIC)
425 ktime_get_ts(&ts);
426 else
427 ktime_get_real_ts(&ts);
428
429 buf->buf.timestamp.tv_sec = ts.tv_sec;
430 buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
431
422 /* TODO: Handle PTS and SCR. */ 432 /* TODO: Handle PTS and SCR. */
423 buf->state = UVC_BUF_STATE_ACTIVE; 433 buf->state = UVC_BUF_STATE_ACTIVE;
424 } 434 }
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 2337585001ea..2bba059259e6 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -113,6 +113,9 @@ struct uvc_xu_control {
113#define UVC_GUID_FORMAT_YUY2 \ 113#define UVC_GUID_FORMAT_YUY2 \
114 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 114 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
115 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 115 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
116#define UVC_GUID_FORMAT_YUY2_ISIGHT \
117 { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
118 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
116#define UVC_GUID_FORMAT_NV12 \ 119#define UVC_GUID_FORMAT_NV12 \
117 { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 120 { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
118 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 121 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
@@ -149,7 +152,7 @@ struct uvc_xu_control {
149#define UVC_MAX_STATUS_SIZE 16 152#define UVC_MAX_STATUS_SIZE 16
150 153
151#define UVC_CTRL_CONTROL_TIMEOUT 300 154#define UVC_CTRL_CONTROL_TIMEOUT 300
152#define UVC_CTRL_STREAMING_TIMEOUT 3000 155#define UVC_CTRL_STREAMING_TIMEOUT 5000
153 156
154/* Devices quirks */ 157/* Devices quirks */
155#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 158#define UVC_QUIRK_STATUS_INTERVAL 0x00000001
@@ -242,7 +245,8 @@ struct uvc_control {
242 uvc_control_info. */ 245 uvc_control_info. */
243 __u8 dirty : 1, 246 __u8 dirty : 1,
244 loaded : 1, 247 loaded : 1,
245 modified : 1; 248 modified : 1,
249 cached : 1;
246 250
247 __u8 *data; 251 __u8 *data;
248}; 252};
@@ -533,6 +537,7 @@ struct uvc_driver {
533#define UVC_WARN_MINMAX 0 537#define UVC_WARN_MINMAX 0
534#define UVC_WARN_PROBE_DEF 1 538#define UVC_WARN_PROBE_DEF 1
535 539
540extern unsigned int uvc_clock_param;
536extern unsigned int uvc_no_drop_param; 541extern unsigned int uvc_no_drop_param;
537extern unsigned int uvc_trace_param; 542extern unsigned int uvc_trace_param;
538extern unsigned int uvc_timeout_param; 543extern unsigned int uvc_timeout_param;
@@ -552,16 +557,6 @@ extern unsigned int uvc_timeout_param;
552#define uvc_printk(level, msg...) \ 557#define uvc_printk(level, msg...) \
553 printk(level "uvcvideo: " msg) 558 printk(level "uvcvideo: " msg)
554 559
555#define UVC_GUID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
556 "%02x%02x%02x%02x%02x%02x"
557#define UVC_GUID_ARGS(guid) \
558 (guid)[3], (guid)[2], (guid)[1], (guid)[0], \
559 (guid)[5], (guid)[4], \
560 (guid)[7], (guid)[6], \
561 (guid)[8], (guid)[9], \
562 (guid)[10], (guid)[11], (guid)[12], \
563 (guid)[13], (guid)[14], (guid)[15]
564
565/* -------------------------------------------------------------------------- 560/* --------------------------------------------------------------------------
566 * Internal functions. 561 * Internal functions.
567 */ 562 */
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index c4150bd26337..f77f84bfe714 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -288,7 +288,7 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
288 288
289static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) 289static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
290{ 290{
291 if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || 291 if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
292 put_user(kp->field, &up->field) || 292 put_user(kp->field, &up->field) ||
293 put_user(kp->chromakey, &up->chromakey) || 293 put_user(kp->chromakey, &up->chromakey) ||
294 put_user(kp->clipcount, &up->clipcount)) 294 put_user(kp->clipcount, &up->clipcount))
@@ -475,6 +475,9 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
475 return -EFAULT; 475 return -EFAULT;
476 switch (kp->memory) { 476 switch (kp->memory) {
477 case V4L2_MEMORY_MMAP: 477 case V4L2_MEMORY_MMAP:
478 if (get_user(kp->length, &up->length) ||
479 get_user(kp->m.offset, &up->m.offset))
480 return -EFAULT;
478 break; 481 break;
479 case V4L2_MEMORY_USERPTR: 482 case V4L2_MEMORY_USERPTR:
480 { 483 {
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index fa78555b118b..fcd045e7a1c1 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -418,6 +418,8 @@ static void *__videobuf_alloc(size_t size)
418 struct videobuf_buffer *vb; 418 struct videobuf_buffer *vb;
419 419
420 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); 420 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
421 if (!vb)
422 return vb;
421 423
422 mem = vb->priv = ((char *)vb)+size; 424 mem = vb->priv = ((char *)vb)+size;
423 mem->magic=MAGIC_SG_MEM; 425 mem->magic=MAGIC_SG_MEM;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index d6e6a28fb6b8..136e09383c06 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -138,6 +138,8 @@ static void *__videobuf_alloc(size_t size)
138 struct videobuf_buffer *vb; 138 struct videobuf_buffer *vb;
139 139
140 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); 140 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
141 if (!vb)
142 return vb;
141 143
142 mem = vb->priv = ((char *)vb)+size; 144 mem = vb->priv = ((char *)vb)+size;
143 mem->magic=MAGIC_VMAL_MEM; 145 mem->magic=MAGIC_VMAL_MEM;
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 37632a064966..cdbe70385c12 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1371,7 +1371,7 @@ static int __init vivi_create_instance(int inst)
1371 /* Now that everything is fine, let's add it to device list */ 1371 /* Now that everything is fine, let's add it to device list */
1372 list_add_tail(&dev->vivi_devlist, &vivi_devlist); 1372 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1373 1373
1374 if (video_nr >= 0) 1374 if (video_nr != -1)
1375 video_nr++; 1375 video_nr++;
1376 1376
1377 dev->vfd = vfd; 1377 dev->vfd = vfd;
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig
index edb00293cd59..a7e610e0be9e 100644
--- a/drivers/media/video/zc0301/Kconfig
+++ b/drivers/media/video/zc0301/Kconfig
@@ -1,7 +1,11 @@
1config USB_ZC0301 1config USB_ZC0301
2 tristate "USB ZC0301[P] Image Processor and Control Chip support" 2 tristate "USB ZC0301[P] webcam support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2
4 default n
4 ---help--- 5 ---help---
6 This driver is DEPRECATED please use the gspca zc3xx module
7 instead.
8
5 Say Y here if you want support for cameras based on the ZC0301 or 9 Say Y here if you want support for cameras based on the ZC0301 or
6 ZC0301P Image Processors and Control Chips. 10 ZC0301P Image Processors and Control Chips.
7 11
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index f6c2fb4fc3b4..e6ad4b205611 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -1196,7 +1196,8 @@ zoran_reap_stat_com (struct zoran *zr)
1196static void zoran_restart(struct zoran *zr) 1196static void zoran_restart(struct zoran *zr)
1197{ 1197{
1198 /* Now the stat_comm buffer is ready for restart */ 1198 /* Now the stat_comm buffer is ready for restart */
1199 int status = 0, mode; 1199 unsigned int status = 0;
1200 int mode;
1200 1201
1201 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { 1202 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1202 decoder_call(zr, video, g_input_status, &status); 1203 decoder_call(zr, video, g_input_status, &status);
@@ -1228,7 +1229,7 @@ error_handler (struct zoran *zr,
1228 u32 astat, 1229 u32 astat,
1229 u32 stat) 1230 u32 stat)
1230{ 1231{
1231 int i, j; 1232 int i;
1232 1233
1233 /* This is JPEG error handling part */ 1234 /* This is JPEG error handling part */
1234 if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && 1235 if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
@@ -1279,6 +1280,7 @@ error_handler (struct zoran *zr,
1279 /* Report error */ 1280 /* Report error */
1280 if (zr36067_debug > 1 && zr->num_errors <= 8) { 1281 if (zr36067_debug > 1 && zr->num_errors <= 8) {
1281 long frame; 1282 long frame;
1283 int j;
1282 1284
1283 frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; 1285 frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
1284 printk(KERN_ERR 1286 printk(KERN_ERR
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 2ddffed019ee..ec41303544e5 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -324,7 +324,7 @@ static int jpg_fbuffer_alloc(struct zoran_fh *fh)
324 /* Allocate fragment table for this buffer */ 324 /* Allocate fragment table for this buffer */
325 325
326 mem = (void *)get_zeroed_page(GFP_KERNEL); 326 mem = (void *)get_zeroed_page(GFP_KERNEL);
327 if (mem == 0) { 327 if (!mem) {
328 dprintk(1, 328 dprintk(1,
329 KERN_ERR 329 KERN_ERR
330 "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n", 330 "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
@@ -1444,7 +1444,7 @@ zoran_set_norm (struct zoran *zr,
1444 } 1444 }
1445 1445
1446 if (norm == V4L2_STD_ALL) { 1446 if (norm == V4L2_STD_ALL) {
1447 int status = 0; 1447 unsigned int status = 0;
1448 v4l2_std_id std = 0; 1448 v4l2_std_id std = 0;
1449 1449
1450 decoder_call(zr, video, querystd, &std); 1450 decoder_call(zr, video, querystd, &std);
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index f0eae83e3d89..3d4bac252902 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -78,6 +78,7 @@
78#define METHOD0 0 78#define METHOD0 0
79#define METHOD1 1 79#define METHOD1 1
80#define METHOD2 2 80#define METHOD2 2
81#define METHOD3 3
81 82
82 83
83/* Module parameters */ 84/* Module parameters */
@@ -114,7 +115,7 @@ static struct usb_device_id device_table[] = {
114 {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, 115 {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
115 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, 116 {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
116 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, 117 {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
117 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 }, 118 {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD3 },
118 {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 }, 119 {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
119 {} /* Terminating entry */ 120 {} /* Terminating entry */
120}; 121};
@@ -302,7 +303,7 @@ static message m2[] = {
302}; 303};
303 304
304/* init table */ 305/* init table */
305static message *init[3] = { m0, m1, m2 }; 306static message *init[4] = { m0, m1, m2, m2 };
306 307
307 308
308/* JPEG static data in header (Huffman table, etc) */ 309/* JPEG static data in header (Huffman table, etc) */
@@ -967,6 +968,22 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
967 m0d1[0] = mode; 968 m0d1[0] = mode;
968 m1[2].value = 0xf000 + mode; 969 m1[2].value = 0xf000 + mode;
969 m2[1].value = 0xf000 + mode; 970 m2[1].value = 0xf000 + mode;
971
972 /* special case for METHOD3, the modes are different */
973 if (cam->method == METHOD3) {
974 switch (mode) {
975 case 1:
976 m2[1].value = 0xf000 + 4;
977 break;
978 case 2:
979 m2[1].value = 0xf000 + 0;
980 break;
981 default:
982 m2[1].value = 0xf000 + 1;
983 break;
984 }
985 }
986
970 header2[437] = cam->height / 256; 987 header2[437] = cam->height / 256;
971 header2[438] = cam->height % 256; 988 header2[438] = cam->height % 256;
972 header2[439] = cam->width / 256; 989 header2[439] = cam->width / 256;
@@ -1582,6 +1599,22 @@ static int zr364xx_probe(struct usb_interface *intf,
1582 m0d1[0] = mode; 1599 m0d1[0] = mode;
1583 m1[2].value = 0xf000 + mode; 1600 m1[2].value = 0xf000 + mode;
1584 m2[1].value = 0xf000 + mode; 1601 m2[1].value = 0xf000 + mode;
1602
1603 /* special case for METHOD3, the modes are different */
1604 if (cam->method == METHOD3) {
1605 switch (mode) {
1606 case 1:
1607 m2[1].value = 0xf000 + 4;
1608 break;
1609 case 2:
1610 m2[1].value = 0xf000 + 0;
1611 break;
1612 default:
1613 m2[1].value = 0xf000 + 1;
1614 break;
1615 }
1616 }
1617
1585 header2[437] = cam->height / 256; 1618 header2[437] = cam->height / 256;
1586 header2[438] = cam->height % 256; 1619 header2[438] = cam->height % 256;
1587 header2[439] = cam->width / 256; 1620 header2[439] = cam->width / 256;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 87829789243e..413576a2f313 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -348,6 +348,16 @@ config AB4500_CORE
348 read/write functions for the devices to get access to this chip. 348 read/write functions for the devices to get access to this chip.
349 This chip embeds various other multimedia funtionalities as well. 349 This chip embeds various other multimedia funtionalities as well.
350 350
351config MFD_TIMBERDALE
352 tristate "Support for the Timberdale FPGA"
353 select MFD_CORE
354 depends on PCI && GPIOLIB
355 ---help---
356 This is the core driver for the timberdale FPGA. This device is a
357 multifunction device which exposes numerous platform devices.
358
359 The timberdale FPGA can be found on the Intel Atom development board
360 for in-vehicle infontainment, called Russellville.
351endmenu 361endmenu
352 362
353menu "Multimedia Capabilities Port drivers" 363menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e09eb4870db6..78295d6a75f7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -54,5 +54,6 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
54obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 54obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
55obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 55obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
56obj-$(CONFIG_AB4500_CORE) += ab4500-core.o 56obj-$(CONFIG_AB4500_CORE) += ab4500-core.o
57obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
57obj-$(CONFIG_MFD_88PM8607) += 88pm8607.o 58obj-$(CONFIG_MFD_88PM8607) += 88pm8607.o
58obj-$(CONFIG_PMIC_ADP5520) += adp5520.o \ No newline at end of file 59obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
new file mode 100644
index 000000000000..1ed44d283803
--- /dev/null
+++ b/drivers/mfd/timberdale.c
@@ -0,0 +1,727 @@
1/*
2 * timberdale.c timberdale FPGA MFD driver
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * Timberdale FPGA
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/pci.h>
26#include <linux/msi.h>
27#include <linux/mfd/core.h>
28
29#include <linux/timb_gpio.h>
30
31#include <linux/i2c.h>
32#include <linux/i2c-ocores.h>
33#include <linux/i2c/tsc2007.h>
34
35#include <linux/spi/spi.h>
36#include <linux/spi/xilinx_spi.h>
37#include <linux/spi/max7301.h>
38#include <linux/spi/mc33880.h>
39
40#include <media/timb_radio.h>
41
42#include "timberdale.h"
43
44#define DRIVER_NAME "timberdale"
45
46struct timberdale_device {
47 resource_size_t ctl_mapbase;
48 unsigned char __iomem *ctl_membase;
49 struct {
50 u32 major;
51 u32 minor;
52 u32 config;
53 } fw;
54};
55
56/*--------------------------------------------------------------------------*/
57
58static struct tsc2007_platform_data timberdale_tsc2007_platform_data = {
59 .model = 2003,
60 .x_plate_ohms = 100
61};
62
63static struct i2c_board_info timberdale_i2c_board_info[] = {
64 {
65 I2C_BOARD_INFO("tsc2007", 0x48),
66 .platform_data = &timberdale_tsc2007_platform_data,
67 .irq = IRQ_TIMBERDALE_TSC_INT
68 },
69};
70
71static __devinitdata struct ocores_i2c_platform_data
72timberdale_ocores_platform_data = {
73 .regstep = 4,
74 .clock_khz = 62500,
75 .devices = timberdale_i2c_board_info,
76 .num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
77};
78
79const static __devinitconst struct resource timberdale_ocores_resources[] = {
80 {
81 .start = OCORESOFFSET,
82 .end = OCORESEND,
83 .flags = IORESOURCE_MEM,
84 },
85 {
86 .start = IRQ_TIMBERDALE_I2C,
87 .end = IRQ_TIMBERDALE_I2C,
88 .flags = IORESOURCE_IRQ,
89 },
90};
91
92const struct max7301_platform_data timberdale_max7301_platform_data = {
93 .base = 200
94};
95
96const struct mc33880_platform_data timberdale_mc33880_platform_data = {
97 .base = 100
98};
99
100static struct spi_board_info timberdale_spi_16bit_board_info[] = {
101 {
102 .modalias = "max7301",
103 .max_speed_hz = 26000,
104 .chip_select = 2,
105 .mode = SPI_MODE_0,
106 .platform_data = &timberdale_max7301_platform_data
107 },
108};
109
110static struct spi_board_info timberdale_spi_8bit_board_info[] = {
111 {
112 .modalias = "mc33880",
113 .max_speed_hz = 4000,
114 .chip_select = 1,
115 .mode = SPI_MODE_1,
116 .platform_data = &timberdale_mc33880_platform_data
117 },
118};
119
120static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
121 .num_chipselect = 3,
122 .little_endian = true,
123 /* bits per word and devices will be filled in runtime depending
124 * on the HW config
125 */
126};
127
128const static __devinitconst struct resource timberdale_spi_resources[] = {
129 {
130 .start = SPIOFFSET,
131 .end = SPIEND,
132 .flags = IORESOURCE_MEM,
133 },
134 {
135 .start = IRQ_TIMBERDALE_SPI,
136 .end = IRQ_TIMBERDALE_SPI,
137 .flags = IORESOURCE_IRQ,
138 },
139};
140
141const static __devinitconst struct resource timberdale_eth_resources[] = {
142 {
143 .start = ETHOFFSET,
144 .end = ETHEND,
145 .flags = IORESOURCE_MEM,
146 },
147 {
148 .start = IRQ_TIMBERDALE_ETHSW_IF,
149 .end = IRQ_TIMBERDALE_ETHSW_IF,
150 .flags = IORESOURCE_IRQ,
151 },
152};
153
154static __devinitdata struct timbgpio_platform_data
155 timberdale_gpio_platform_data = {
156 .gpio_base = 0,
157 .nr_pins = GPIO_NR_PINS,
158 .irq_base = 200,
159};
160
161const static __devinitconst struct resource timberdale_gpio_resources[] = {
162 {
163 .start = GPIOOFFSET,
164 .end = GPIOEND,
165 .flags = IORESOURCE_MEM,
166 },
167 {
168 .start = IRQ_TIMBERDALE_GPIO,
169 .end = IRQ_TIMBERDALE_GPIO,
170 .flags = IORESOURCE_IRQ,
171 },
172};
173
174const static __devinitconst struct resource timberdale_mlogicore_resources[] = {
175 {
176 .start = MLCOREOFFSET,
177 .end = MLCOREEND,
178 .flags = IORESOURCE_MEM,
179 },
180 {
181 .start = IRQ_TIMBERDALE_MLCORE,
182 .end = IRQ_TIMBERDALE_MLCORE,
183 .flags = IORESOURCE_IRQ,
184 },
185 {
186 .start = IRQ_TIMBERDALE_MLCORE_BUF,
187 .end = IRQ_TIMBERDALE_MLCORE_BUF,
188 .flags = IORESOURCE_IRQ,
189 },
190};
191
192const static __devinitconst struct resource timberdale_uart_resources[] = {
193 {
194 .start = UARTOFFSET,
195 .end = UARTEND,
196 .flags = IORESOURCE_MEM,
197 },
198 {
199 .start = IRQ_TIMBERDALE_UART,
200 .end = IRQ_TIMBERDALE_UART,
201 .flags = IORESOURCE_IRQ,
202 },
203};
204
205const static __devinitconst struct resource timberdale_uartlite_resources[] = {
206 {
207 .start = UARTLITEOFFSET,
208 .end = UARTLITEEND,
209 .flags = IORESOURCE_MEM,
210 },
211 {
212 .start = IRQ_TIMBERDALE_UARTLITE,
213 .end = IRQ_TIMBERDALE_UARTLITE,
214 .flags = IORESOURCE_IRQ,
215 },
216};
217
218const static __devinitconst struct resource timberdale_radio_resources[] = {
219 {
220 .start = RDSOFFSET,
221 .end = RDSEND,
222 .flags = IORESOURCE_MEM,
223 },
224 {
225 .start = IRQ_TIMBERDALE_RDS,
226 .end = IRQ_TIMBERDALE_RDS,
227 .flags = IORESOURCE_IRQ,
228 },
229};
230
231static __devinitdata struct i2c_board_info timberdale_tef6868_i2c_board_info = {
232 I2C_BOARD_INFO("tef6862", 0x60)
233};
234
235static __devinitdata struct i2c_board_info timberdale_saa7706_i2c_board_info = {
236 I2C_BOARD_INFO("saa7706h", 0x1C)
237};
238
239static __devinitdata struct timb_radio_platform_data
240 timberdale_radio_platform_data = {
241 .i2c_adapter = 0,
242 .tuner = {
243 .module_name = "tef6862",
244 .info = &timberdale_tef6868_i2c_board_info
245 },
246 .dsp = {
247 .module_name = "saa7706h",
248 .info = &timberdale_saa7706_i2c_board_info
249 }
250};
251
252const static __devinitconst struct resource timberdale_dma_resources[] = {
253 {
254 .start = DMAOFFSET,
255 .end = DMAEND,
256 .flags = IORESOURCE_MEM,
257 },
258 {
259 .start = IRQ_TIMBERDALE_DMA,
260 .end = IRQ_TIMBERDALE_DMA,
261 .flags = IORESOURCE_IRQ,
262 },
263};
264
265static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
266 {
267 .name = "timb-uart",
268 .num_resources = ARRAY_SIZE(timberdale_uart_resources),
269 .resources = timberdale_uart_resources,
270 },
271 {
272 .name = "timb-gpio",
273 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
274 .resources = timberdale_gpio_resources,
275 .platform_data = &timberdale_gpio_platform_data,
276 .data_size = sizeof(timberdale_gpio_platform_data),
277 },
278 {
279 .name = "timb-radio",
280 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
281 .resources = timberdale_radio_resources,
282 .platform_data = &timberdale_radio_platform_data,
283 .data_size = sizeof(timberdale_radio_platform_data),
284 },
285 {
286 .name = "xilinx_spi",
287 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
288 .resources = timberdale_spi_resources,
289 .platform_data = &timberdale_xspi_platform_data,
290 .data_size = sizeof(timberdale_xspi_platform_data),
291 },
292 {
293 .name = "ks8842",
294 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
295 .resources = timberdale_eth_resources,
296 },
297 {
298 .name = "timb-dma",
299 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
300 .resources = timberdale_dma_resources,
301 },
302};
303
304static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
305 {
306 .name = "timb-uart",
307 .num_resources = ARRAY_SIZE(timberdale_uart_resources),
308 .resources = timberdale_uart_resources,
309 },
310 {
311 .name = "uartlite",
312 .num_resources = ARRAY_SIZE(timberdale_uartlite_resources),
313 .resources = timberdale_uartlite_resources,
314 },
315 {
316 .name = "timb-gpio",
317 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
318 .resources = timberdale_gpio_resources,
319 .platform_data = &timberdale_gpio_platform_data,
320 .data_size = sizeof(timberdale_gpio_platform_data),
321 },
322 {
323 .name = "timb-mlogicore",
324 .num_resources = ARRAY_SIZE(timberdale_mlogicore_resources),
325 .resources = timberdale_mlogicore_resources,
326 },
327 {
328 .name = "timb-radio",
329 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
330 .resources = timberdale_radio_resources,
331 .platform_data = &timberdale_radio_platform_data,
332 .data_size = sizeof(timberdale_radio_platform_data),
333 },
334 {
335 .name = "xilinx_spi",
336 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
337 .resources = timberdale_spi_resources,
338 .platform_data = &timberdale_xspi_platform_data,
339 .data_size = sizeof(timberdale_xspi_platform_data),
340 },
341 {
342 .name = "ks8842",
343 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
344 .resources = timberdale_eth_resources,
345 },
346 {
347 .name = "timb-dma",
348 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
349 .resources = timberdale_dma_resources,
350 },
351};
352
353static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
354 {
355 .name = "timb-uart",
356 .num_resources = ARRAY_SIZE(timberdale_uart_resources),
357 .resources = timberdale_uart_resources,
358 },
359 {
360 .name = "timb-gpio",
361 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
362 .resources = timberdale_gpio_resources,
363 .platform_data = &timberdale_gpio_platform_data,
364 .data_size = sizeof(timberdale_gpio_platform_data),
365 },
366 {
367 .name = "timb-radio",
368 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
369 .resources = timberdale_radio_resources,
370 .platform_data = &timberdale_radio_platform_data,
371 .data_size = sizeof(timberdale_radio_platform_data),
372 },
373 {
374 .name = "xilinx_spi",
375 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
376 .resources = timberdale_spi_resources,
377 .platform_data = &timberdale_xspi_platform_data,
378 .data_size = sizeof(timberdale_xspi_platform_data),
379 },
380 {
381 .name = "timb-dma",
382 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
383 .resources = timberdale_dma_resources,
384 },
385};
386
387static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
388 {
389 .name = "timb-uart",
390 .num_resources = ARRAY_SIZE(timberdale_uart_resources),
391 .resources = timberdale_uart_resources,
392 },
393 {
394 .name = "ocores-i2c",
395 .num_resources = ARRAY_SIZE(timberdale_ocores_resources),
396 .resources = timberdale_ocores_resources,
397 .platform_data = &timberdale_ocores_platform_data,
398 .data_size = sizeof(timberdale_ocores_platform_data),
399 },
400 {
401 .name = "timb-gpio",
402 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
403 .resources = timberdale_gpio_resources,
404 .platform_data = &timberdale_gpio_platform_data,
405 .data_size = sizeof(timberdale_gpio_platform_data),
406 },
407 {
408 .name = "timb-radio",
409 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
410 .resources = timberdale_radio_resources,
411 .platform_data = &timberdale_radio_platform_data,
412 .data_size = sizeof(timberdale_radio_platform_data),
413 },
414 {
415 .name = "xilinx_spi",
416 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
417 .resources = timberdale_spi_resources,
418 .platform_data = &timberdale_xspi_platform_data,
419 .data_size = sizeof(timberdale_xspi_platform_data),
420 },
421 {
422 .name = "ks8842",
423 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
424 .resources = timberdale_eth_resources,
425 },
426 {
427 .name = "timb-dma",
428 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
429 .resources = timberdale_dma_resources,
430 },
431};
432
433static const __devinitconst struct resource timberdale_sdhc_resources[] = {
434 /* located in bar 1 and bar 2 */
435 {
436 .start = SDHC0OFFSET,
437 .end = SDHC0END,
438 .flags = IORESOURCE_MEM,
439 },
440 {
441 .start = IRQ_TIMBERDALE_SDHC,
442 .end = IRQ_TIMBERDALE_SDHC,
443 .flags = IORESOURCE_IRQ,
444 },
445};
446
447static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
448 {
449 .name = "sdhci",
450 .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
451 .resources = timberdale_sdhc_resources,
452 },
453};
454
455static __devinitdata struct mfd_cell timberdale_cells_bar2[] = {
456 {
457 .name = "sdhci",
458 .num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
459 .resources = timberdale_sdhc_resources,
460 },
461};
462
463static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
464 char *buf)
465{
466 struct pci_dev *pdev = to_pci_dev(dev);
467 struct timberdale_device *priv = pci_get_drvdata(pdev);
468
469 return sprintf(buf, "%d.%d.%d\n", priv->fw.major, priv->fw.minor,
470 priv->fw.config);
471}
472
473static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
474
475/*--------------------------------------------------------------------------*/
476
477static int __devinit timb_probe(struct pci_dev *dev,
478 const struct pci_device_id *id)
479{
480 struct timberdale_device *priv;
481 int err, i;
482 resource_size_t mapbase;
483 struct msix_entry *msix_entries = NULL;
484 u8 ip_setup;
485
486 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
487 if (!priv)
488 return -ENOMEM;
489
490 pci_set_drvdata(dev, priv);
491
492 err = pci_enable_device(dev);
493 if (err)
494 goto err_enable;
495
496 mapbase = pci_resource_start(dev, 0);
497 if (!mapbase) {
498 dev_err(&dev->dev, "No resource\n");
499 goto err_start;
500 }
501
502 /* create a resource for the PCI master register */
503 priv->ctl_mapbase = mapbase + CHIPCTLOFFSET;
504 if (!request_mem_region(priv->ctl_mapbase, CHIPCTLSIZE, "timb-ctl")) {
505 dev_err(&dev->dev, "Failed to request ctl mem\n");
506 goto err_request;
507 }
508
509 priv->ctl_membase = ioremap(priv->ctl_mapbase, CHIPCTLSIZE);
510 if (!priv->ctl_membase) {
511 dev_err(&dev->dev, "ioremap failed for ctl mem\n");
512 goto err_ioremap;
513 }
514
515 /* read the HW config */
516 priv->fw.major = ioread32(priv->ctl_membase + TIMB_REV_MAJOR);
517 priv->fw.minor = ioread32(priv->ctl_membase + TIMB_REV_MINOR);
518 priv->fw.config = ioread32(priv->ctl_membase + TIMB_HW_CONFIG);
519
520 if (priv->fw.major > TIMB_SUPPORTED_MAJOR) {
521 dev_err(&dev->dev, "The driver supports an older "
522 "version of the FPGA, please update the driver to "
523 "support %d.%d\n", priv->fw.major, priv->fw.minor);
524 goto err_ioremap;
525 }
526 if (priv->fw.major < TIMB_SUPPORTED_MAJOR ||
527 priv->fw.minor < TIMB_REQUIRED_MINOR) {
528 dev_err(&dev->dev, "The FPGA image is too old (%d.%d), "
529 "please upgrade the FPGA to at least: %d.%d\n",
530 priv->fw.major, priv->fw.minor,
531 TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR);
532 goto err_ioremap;
533 }
534
535 msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries),
536 GFP_KERNEL);
537 if (!msix_entries)
538 goto err_ioremap;
539
540 for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
541 msix_entries[i].entry = i;
542
543 err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS);
544 if (err) {
545 dev_err(&dev->dev,
546 "MSI-X init failed: %d, expected entries: %d\n",
547 err, TIMBERDALE_NR_IRQS);
548 goto err_msix;
549 }
550
551 err = device_create_file(&dev->dev, &dev_attr_fw_ver);
552 if (err)
553 goto err_create_file;
554
555 /* Reset all FPGA PLB peripherals */
556 iowrite32(0x1, priv->ctl_membase + TIMB_SW_RST);
557
558 /* update IRQ offsets in I2C board info */
559 for (i = 0; i < ARRAY_SIZE(timberdale_i2c_board_info); i++)
560 timberdale_i2c_board_info[i].irq =
561 msix_entries[timberdale_i2c_board_info[i].irq].vector;
562
563 /* Update the SPI configuration depending on the HW (8 or 16 bit) */
564 if (priv->fw.config & TIMB_HW_CONFIG_SPI_8BIT) {
565 timberdale_xspi_platform_data.bits_per_word = 8;
566 timberdale_xspi_platform_data.devices =
567 timberdale_spi_8bit_board_info;
568 timberdale_xspi_platform_data.num_devices =
569 ARRAY_SIZE(timberdale_spi_8bit_board_info);
570 } else {
571 timberdale_xspi_platform_data.bits_per_word = 16;
572 timberdale_xspi_platform_data.devices =
573 timberdale_spi_16bit_board_info;
574 timberdale_xspi_platform_data.num_devices =
575 ARRAY_SIZE(timberdale_spi_16bit_board_info);
576 }
577
578 ip_setup = priv->fw.config & TIMB_HW_VER_MASK;
579 switch (ip_setup) {
580 case TIMB_HW_VER0:
581 err = mfd_add_devices(&dev->dev, -1,
582 timberdale_cells_bar0_cfg0,
583 ARRAY_SIZE(timberdale_cells_bar0_cfg0),
584 &dev->resource[0], msix_entries[0].vector);
585 break;
586 case TIMB_HW_VER1:
587 err = mfd_add_devices(&dev->dev, -1,
588 timberdale_cells_bar0_cfg1,
589 ARRAY_SIZE(timberdale_cells_bar0_cfg1),
590 &dev->resource[0], msix_entries[0].vector);
591 break;
592 case TIMB_HW_VER2:
593 err = mfd_add_devices(&dev->dev, -1,
594 timberdale_cells_bar0_cfg2,
595 ARRAY_SIZE(timberdale_cells_bar0_cfg2),
596 &dev->resource[0], msix_entries[0].vector);
597 break;
598 case TIMB_HW_VER3:
599 err = mfd_add_devices(&dev->dev, -1,
600 timberdale_cells_bar0_cfg3,
601 ARRAY_SIZE(timberdale_cells_bar0_cfg3),
602 &dev->resource[0], msix_entries[0].vector);
603 break;
604 default:
605 dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n",
606 priv->fw.major, priv->fw.minor, ip_setup);
607 err = -ENODEV;
608 goto err_mfd;
609 break;
610 }
611
612 if (err) {
613 dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
614 goto err_mfd;
615 }
616
617 err = mfd_add_devices(&dev->dev, 0,
618 timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1),
619 &dev->resource[1], msix_entries[0].vector);
620 if (err) {
621 dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
622 goto err_mfd2;
623 }
624
625 /* only version 0 and 3 have the iNand routed to SDHCI */
626 if (((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER0) ||
627 ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) {
628 err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2,
629 ARRAY_SIZE(timberdale_cells_bar2),
630 &dev->resource[2], msix_entries[0].vector);
631 if (err) {
632 dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
633 goto err_mfd2;
634 }
635 }
636
637 kfree(msix_entries);
638
639 dev_info(&dev->dev,
640 "Found Timberdale Card. Rev: %d.%d, HW config: 0x%02x\n",
641 priv->fw.major, priv->fw.minor, priv->fw.config);
642
643 return 0;
644
645err_mfd2:
646 mfd_remove_devices(&dev->dev);
647err_mfd:
648 device_remove_file(&dev->dev, &dev_attr_fw_ver);
649err_create_file:
650 pci_disable_msix(dev);
651err_msix:
652 iounmap(priv->ctl_membase);
653err_ioremap:
654 release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
655err_request:
656 pci_set_drvdata(dev, NULL);
657err_start:
658 pci_disable_device(dev);
659err_enable:
660 kfree(msix_entries);
661 kfree(priv);
662 pci_set_drvdata(dev, NULL);
663 return -ENODEV;
664}
665
666static void __devexit timb_remove(struct pci_dev *dev)
667{
668 struct timberdale_device *priv = pci_get_drvdata(dev);
669
670 mfd_remove_devices(&dev->dev);
671
672 device_remove_file(&dev->dev, &dev_attr_fw_ver);
673
674 iounmap(priv->ctl_membase);
675 release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
676
677 pci_disable_msix(dev);
678 pci_disable_device(dev);
679 pci_set_drvdata(dev, NULL);
680 kfree(priv);
681}
682
683static struct pci_device_id timberdale_pci_tbl[] = {
684 { PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) },
685 { 0 }
686};
687MODULE_DEVICE_TABLE(pci, timberdale_pci_tbl);
688
689static struct pci_driver timberdale_pci_driver = {
690 .name = DRIVER_NAME,
691 .id_table = timberdale_pci_tbl,
692 .probe = timb_probe,
693 .remove = __devexit_p(timb_remove),
694};
695
696static int __init timberdale_init(void)
697{
698 int err;
699
700 err = pci_register_driver(&timberdale_pci_driver);
701 if (err < 0) {
702 printk(KERN_ERR
703 "Failed to register PCI driver for %s device.\n",
704 timberdale_pci_driver.name);
705 return -ENODEV;
706 }
707
708 printk(KERN_INFO "Driver for %s has been successfully registered.\n",
709 timberdale_pci_driver.name);
710
711 return 0;
712}
713
714static void __exit timberdale_exit(void)
715{
716 pci_unregister_driver(&timberdale_pci_driver);
717
718 printk(KERN_INFO "Driver for %s has been successfully unregistered.\n",
719 timberdale_pci_driver.name);
720}
721
722module_init(timberdale_init);
723module_exit(timberdale_exit);
724
725MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
726MODULE_VERSION(DRV_VERSION);
727MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/timberdale.h b/drivers/mfd/timberdale.h
new file mode 100644
index 000000000000..8d27ffabc25d
--- /dev/null
+++ b/drivers/mfd/timberdale.h
@@ -0,0 +1,130 @@
1/*
2 * timberdale.h timberdale FPGA MFD driver defines
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * Timberdale FPGA
21 */
22
23#ifndef MFD_TIMBERDALE_H
24#define MFD_TIMBERDALE_H
25
26#define DRV_VERSION "0.1"
27
28/* This driver only support versions >= 3.8 and < 4.0 */
29#define TIMB_SUPPORTED_MAJOR 3
30
31/* This driver only support minor >= 8 */
32#define TIMB_REQUIRED_MINOR 8
33
34/* Registers of the control area */
35#define TIMB_REV_MAJOR 0x00
36#define TIMB_REV_MINOR 0x04
37#define TIMB_HW_CONFIG 0x08
38#define TIMB_SW_RST 0x40
39
40/* bits in the TIMB_HW_CONFIG register */
41#define TIMB_HW_CONFIG_SPI_8BIT 0x80
42
43#define TIMB_HW_VER_MASK 0x0f
44#define TIMB_HW_VER0 0x00
45#define TIMB_HW_VER1 0x01
46#define TIMB_HW_VER2 0x02
47#define TIMB_HW_VER3 0x03
48
49#define OCORESOFFSET 0x0
50#define OCORESEND 0x1f
51
52#define SPIOFFSET 0x80
53#define SPIEND 0xff
54
55#define UARTLITEOFFSET 0x100
56#define UARTLITEEND 0x10f
57
58#define RDSOFFSET 0x180
59#define RDSEND 0x183
60
61#define ETHOFFSET 0x300
62#define ETHEND 0x3ff
63
64#define GPIOOFFSET 0x400
65#define GPIOEND 0x7ff
66
67#define CHIPCTLOFFSET 0x800
68#define CHIPCTLEND 0x8ff
69#define CHIPCTLSIZE (CHIPCTLEND - CHIPCTLOFFSET)
70
71#define INTCOFFSET 0xc00
72#define INTCEND 0xfff
73#define INTCSIZE (INTCEND - INTCOFFSET)
74
75#define MOSTOFFSET 0x1000
76#define MOSTEND 0x13ff
77
78#define UARTOFFSET 0x1400
79#define UARTEND 0x17ff
80
81#define XIICOFFSET 0x1800
82#define XIICEND 0x19ff
83
84#define I2SOFFSET 0x1C00
85#define I2SEND 0x1fff
86
87#define LOGIWOFFSET 0x30000
88#define LOGIWEND 0x37fff
89
90#define MLCOREOFFSET 0x40000
91#define MLCOREEND 0x43fff
92
93#define DMAOFFSET 0x01000000
94#define DMAEND 0x013fffff
95
96/* SDHC0 is placed in PCI bar 1 */
97#define SDHC0OFFSET 0x00
98#define SDHC0END 0xff
99
100/* SDHC1 is placed in PCI bar 2 */
101#define SDHC1OFFSET 0x00
102#define SDHC1END 0xff
103
104#define PCI_VENDOR_ID_TIMB 0x10ee
105#define PCI_DEVICE_ID_TIMB 0xa123
106
107#define IRQ_TIMBERDALE_INIC 0
108#define IRQ_TIMBERDALE_MLB 1
109#define IRQ_TIMBERDALE_GPIO 2
110#define IRQ_TIMBERDALE_I2C 3
111#define IRQ_TIMBERDALE_UART 4
112#define IRQ_TIMBERDALE_DMA 5
113#define IRQ_TIMBERDALE_I2S 6
114#define IRQ_TIMBERDALE_TSC_INT 7
115#define IRQ_TIMBERDALE_SDHC 8
116#define IRQ_TIMBERDALE_ADV7180 9
117#define IRQ_TIMBERDALE_ETHSW_IF 10
118#define IRQ_TIMBERDALE_SPI 11
119#define IRQ_TIMBERDALE_UARTLITE 12
120#define IRQ_TIMBERDALE_MLCORE 13
121#define IRQ_TIMBERDALE_MLCORE_BUF 14
122#define IRQ_TIMBERDALE_RDS 15
123#define TIMBERDALE_NR_IRQS 16
124
125#define GPIO_PIN_ASCB 8
126#define GPIO_PIN_INIC_RST 14
127#define GPIO_PIN_BT_RST 15
128#define GPIO_NR_PINS 16
129
130#endif
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 8cf7f2750b3f..c324f6ea002b 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -159,7 +159,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
159 struct go7007 *go = i2c_get_adapdata(client->adapter); 159 struct go7007 *go = i2c_get_adapdata(client->adapter);
160 struct go7007_usb *usb; 160 struct go7007_usb *usb;
161 int rc; 161 int rc;
162 int dev_addr = client->addr; 162 int dev_addr = client->addr << 1; /* firmware wants 8-bit address */
163 u8 *buf; 163 u8 *buf;
164 164
165 if (go == NULL) 165 if (go == NULL)