aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-17 00:15:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-17 00:15:42 -0400
commit0dd5198672dd2bbeb933862e1fc82162e0b636be (patch)
treec9efed20d90603c4d1626c21bd7aab1e7fc74a58 /drivers/media
parentc868d550115b9ccc0027c67265b9520790f05601 (diff)
parent11c635a25b9f3a5d87409ce46cf2e05c500251ec (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits) V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added. V4L/DVB (12004): poll method lose race condition V4L/DVB (11894): flexcop-pci: dmesg visible names broken V4L/DVB (11892): Siano: smsendian - declare function as extern V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol V4L/DVB (11890): Siano: smscore - remove redundant code V4L/DVB (11889): Siano: smsdvb - add DVB v3 events V4L/DVB (11888): Siano: smsusb - remove redundant ifdef V4L/DVB (11887): Siano: smscards - add board (target) events V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names V4L/DVB (11885): Siano: Add new GPIO management interface V4L/DVB (11884): Siano: smssdio - revert to stand alone module V4L/DVB (11883): Siano: cards - add two additional (USB) devices V4L/DVB (11824): Siano: smsusb - change exit func debug msg V4L/DVB (11823): Siano: smsusb - fix typo in module description V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name V4L/DVB (11820): Siano: smscore - fix byte ordering bug V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets ...
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Kconfig10
-rw-r--r--drivers/media/common/tuners/tuner-simple.c44
-rw-r--r--drivers/media/common/tuners/tuner-types.c59
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c56
-rw-r--r--drivers/media/common/tuners/xc5000.c264
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h8
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c790
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c20
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c8
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c121
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c14
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c42
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h4
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig1
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c94
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c31
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h8
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c325
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.h1
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c8
-rw-r--r--drivers/media/dvb/firewire/firedtv-rc.c4
-rw-r--r--drivers/media/dvb/frontends/Kconfig22
-rw-r--r--drivers/media/dvb/frontends/Makefile4
-rw-r--r--drivers/media/dvb/frontends/af9013.c2
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c98
-rw-r--r--drivers/media/dvb/frontends/cx24116.c2
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c4
-rw-r--r--drivers/media/dvb/frontends/isl6423.c308
-rw-r--r--drivers/media/dvb/frontends/isl6423.h63
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c17
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c10
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c2
-rw-r--r--drivers/media/dvb/frontends/mt312.c2
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c6
-rw-r--r--drivers/media/dvb/frontends/or51132.c2
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h2
-rw-r--r--drivers/media/dvb/frontends/stv090x.c4299
-rw-r--r--drivers/media/dvb/frontends/stv090x.h106
-rw-r--r--drivers/media/dvb/frontends/stv090x_priv.h269
-rw-r--r--drivers/media/dvb/frontends/stv090x_reg.h2373
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c373
-rw-r--r--drivers/media/dvb/frontends/stv6110x.h71
-rw-r--r--drivers/media/dvb/frontends/stv6110x_priv.h75
-rw-r--r--drivers/media/dvb/frontends/stv6110x_reg.h82
-rw-r--r--drivers/media/dvb/frontends/tda10048.c312
-rw-r--r--drivers/media/dvb/frontends/tda10048.h21
-rw-r--r--drivers/media/dvb/siano/Makefile2
-rw-r--r--drivers/media/dvb/siano/sms-cards.c188
-rw-r--r--drivers/media/dvb/siano/sms-cards.h64
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c468
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h488
-rw-r--r--drivers/media/dvb/siano/smsdvb.c372
-rw-r--r--drivers/media/dvb/siano/smsendian.c102
-rw-r--r--drivers/media/dvb/siano/smsendian.h32
-rw-r--r--drivers/media/dvb/siano/smsir.c301
-rw-r--r--drivers/media/dvb/siano/smsir.h93
-rw-r--r--drivers/media/dvb/siano/smssdio.c357
-rw-r--r--drivers/media/dvb/siano/smsusb.c75
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c124
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c2
-rw-r--r--drivers/media/dvb/ttpci/budget.c85
-rw-r--r--drivers/media/radio/dsbr100.c109
-rw-r--r--drivers/media/radio/radio-mr800.c1
-rw-r--r--drivers/media/radio/radio-sf16fmi.c16
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c22
-rw-r--r--drivers/media/radio/radio-si470x.c1
-rw-r--r--drivers/media/video/Kconfig20
-rw-r--r--drivers/media/video/Makefile79
-rw-r--r--drivers/media/video/adv7343.c534
-rw-r--r--drivers/media/video/adv7343_regs.h185
-rw-r--r--drivers/media/video/au0828/au0828-cards.c4
-rw-r--r--drivers/media/video/au0828/au0828-core.c17
-rw-r--r--drivers/media/video/au0828/au0828-video.c8
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c14
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c21
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c6
-rw-r--r--drivers/media/video/cx18/cx18-audio.c44
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c374
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c82
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c4
-rw-r--r--drivers/media/video/cx18/cx18-cards.c63
-rw-r--r--drivers/media/video/cx18/cx18-controls.c6
-rw-r--r--drivers/media/video/cx18/cx18-driver.c100
-rw-r--r--drivers/media/video/cx18/cx18-driver.h22
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c54
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c7
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c114
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h2
-rw-r--r--drivers/media/video/cx18/cx18-queue.c85
-rw-r--r--drivers/media/video/cx18/cx18-streams.c44
-rw-r--r--drivers/media/video/cx18/cx18-streams.h20
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c8
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c32
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/video/cx23885/cimax2.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c121
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c92
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c123
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c12
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c14
-rw-r--r--drivers/media/video/cx23885/cx23885.h21
-rw-r--r--drivers/media/video/cx88/Makefile2
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c7
-rw-r--r--drivers/media/video/cx88/cx88-cards.c108
-rw-r--r--drivers/media/video/cx88/cx88-core.c27
-rw-r--r--drivers/media/video/cx88/cx88-dsp.c312
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c1
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c13
-rw-r--r--drivers/media/video/cx88/cx88-input.c6
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c115
-rw-r--r--drivers/media/video/cx88/cx88-video.c16
-rw-r--r--drivers/media/video/cx88/cx88.h12
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c5
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c222
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c58
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c21
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c25
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h16
-rw-r--r--drivers/media/video/em28xx/em28xx.h9
-rw-r--r--drivers/media/video/gspca/finepix.c1
-rw-r--r--drivers/media/video/gspca/gspca.c199
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/m5602/Makefile3
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h26
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c44
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c400
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h805
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c227
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h279
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c222
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h57
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c494
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h439
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c391
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h93
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c473
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h280
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h9
-rw-r--r--drivers/media/video/gspca/mr97310a.c8
-rw-r--r--drivers/media/video/gspca/ov519.c520
-rw-r--r--drivers/media/video/gspca/ov534.c277
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c66
-rw-r--r--drivers/media/video/gspca/spca500.c33
-rw-r--r--drivers/media/video/gspca/spca505.c14
-rw-r--r--drivers/media/video/gspca/spca508.c1934
-rw-r--r--drivers/media/video/gspca/spca561.c105
-rw-r--r--drivers/media/video/gspca/sq905.c1
-rw-r--r--drivers/media/video/gspca/sq905c.c1
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h10
-rw-r--r--drivers/media/video/gspca/sunplus.c33
-rw-r--r--drivers/media/video/gspca/t613.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c22
-rw-r--r--drivers/media/video/gspca/zc3xx.c22
-rw-r--r--drivers/media/video/hexium_gemini.c2
-rw-r--r--drivers/media/video/hexium_orion.c2
-rw-r--r--drivers/media/video/ir-kbd-i2c.c222
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c36
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c2
-rw-r--r--drivers/media/video/mt9m001.c108
-rw-r--r--drivers/media/video/mt9m111.c73
-rw-r--r--drivers/media/video/mt9t031.c135
-rw-r--r--drivers/media/video/mt9v022.c138
-rw-r--r--drivers/media/video/mx1_camera.c50
-rw-r--r--drivers/media/video/mx3_camera.c46
-rw-r--r--drivers/media/video/mxb.c4
-rw-r--r--drivers/media/video/ov511.c45
-rw-r--r--drivers/media/video/ov511.h3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h23
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c74
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c51
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c6
-rw-r--r--drivers/media/video/pwc/pwc-if.c6
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c2
-rw-r--r--drivers/media/video/pxa_camera.c126
-rw-r--r--drivers/media/video/s2255drv.c110
-rw-r--r--drivers/media/video/saa7134/Kconfig1
-rw-r--r--drivers/media/video/saa7134/Makefile3
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c450
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c18
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c26
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c33
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c118
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c122
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c10
-rw-r--r--drivers/media/video/saa7134/saa7134.h29
-rw-r--r--drivers/media/video/se401.c882
-rw-r--r--drivers/media/video/se401.h7
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c27
-rw-r--r--drivers/media/video/soc_camera.c106
-rw-r--r--drivers/media/video/stk-webcam.c4
-rw-r--r--drivers/media/video/tda7432.c14
-rw-r--r--drivers/media/video/tea6415c.c1
-rw-r--r--drivers/media/video/tea6420.c1
-rw-r--r--drivers/media/video/ths7303.c151
-rw-r--r--drivers/media/video/tuner-core.c33
-rw-r--r--drivers/media/video/tveeprom.c6
-rw-r--r--drivers/media/video/tvp514x.c2
-rw-r--r--drivers/media/video/usbvideo/konicawc.c4
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c4
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c14
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c4
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c35
-rw-r--r--drivers/media/video/uvc/uvc_driver.c68
-rw-r--r--drivers/media/video/uvc/uvc_queue.c14
-rw-r--r--drivers/media/video/uvc/uvc_status.c21
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c39
-rw-r--r--drivers/media/video/uvc/uvc_video.c17
-rw-r--r--drivers/media/video/uvc/uvcvideo.h5
-rw-r--r--drivers/media/video/v4l2-common.c4
-rw-r--r--drivers/media/video/v4l2-device.c31
-rw-r--r--drivers/media/video/videobuf-core.c6
-rw-r--r--drivers/media/video/videobuf-dma-contig.c14
-rw-r--r--drivers/media/video/videobuf-dma-sg.c19
-rw-r--r--drivers/media/video/vino.c6
-rw-r--r--drivers/media/video/zoran/zoran_card.c4
-rw-r--r--drivers/media/video/zr364xx.c6
235 files changed, 21513 insertions, 6400 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 223c36ede5ae..ba69beeb0e21 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -2,8 +2,14 @@
2# Multimedia device configuration 2# Multimedia device configuration
3# 3#
4 4
5menu "Multimedia devices" 5menuconfig MEDIA_SUPPORT
6 tristate "Multimedia support"
6 depends on HAS_IOMEM 7 depends on HAS_IOMEM
8 help
9 If you want to use Video for Linux, DVB for Linux, or DAB adapters,
10 enable this option and other options below.
11
12if MEDIA_SUPPORT
7 13
8comment "Multimedia core support" 14comment "Multimedia core support"
9 15
@@ -136,4 +142,4 @@ config USB_DABUSB
136 module will be called dabusb. 142 module will be called dabusb.
137endif # DAB 143endif # DAB
138 144
139endmenu 145endif # MEDIA_SUPPORT
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 78412c9c424a..149d54cdf7b9 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -416,6 +416,24 @@ static int simple_std_setup(struct dvb_frontend *fe,
416 return 0; 416 return 0;
417} 417}
418 418
419static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux)
420{
421 struct tuner_simple_priv *priv = fe->tuner_priv;
422 int rc;
423 u8 buffer[2];
424
425 buffer[0] = (config & ~0x38) | 0x18;
426 buffer[1] = aux;
427
428 tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]);
429
430 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
431 if (2 != rc)
432 tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc);
433
434 return rc == 2 ? 0 : rc;
435}
436
419static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, 437static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
420 u16 div, u8 config, u8 cb) 438 u16 div, u8 config, u8 cb)
421{ 439{
@@ -424,17 +442,10 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
424 442
425 switch (priv->type) { 443 switch (priv->type) {
426 case TUNER_LG_TDVS_H06XF: 444 case TUNER_LG_TDVS_H06XF:
427 /* Set the Auxiliary Byte. */ 445 simple_set_aux_byte(fe, config, 0x20);
428 buffer[0] = buffer[2]; 446 break;
429 buffer[0] &= ~0x20; 447 case TUNER_PHILIPS_FQ1216LME_MK3:
430 buffer[0] |= 0x18; 448 simple_set_aux_byte(fe, config, 0x60); /* External AGC */
431 buffer[1] = 0x20;
432 tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]);
433
434 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
435 if (2 != rc)
436 tuner_warn("i2c i/o error: rc == %d "
437 "(should be 2)\n", rc);
438 break; 449 break;
439 case TUNER_MICROTUNE_4042FI5: 450 case TUNER_MICROTUNE_4042FI5:
440 { 451 {
@@ -506,6 +517,11 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
506 case TUNER_THOMSON_DTT761X: 517 case TUNER_THOMSON_DTT761X:
507 buffer[3] = 0x39; 518 buffer[3] = 0x39;
508 break; 519 break;
520 case TUNER_PHILIPS_FQ1216LME_MK3:
521 tuner_err("This tuner doesn't have FM\n");
522 /* Set the low band for sanity, since it covers 88-108 MHz */
523 buffer[3] = 0x01;
524 break;
509 case TUNER_MICROTUNE_4049FM5: 525 case TUNER_MICROTUNE_4049FM5:
510 default: 526 default:
511 buffer[3] = 0xa4; 527 buffer[3] = 0xa4;
@@ -678,12 +694,12 @@ static int simple_set_radio_freq(struct dvb_frontend *fe,
678 return 0; 694 return 0;
679 } 695 }
680 696
681 /* Bandswitch byte */
682 simple_radio_bandswitch(fe, &buffer[0]);
683
684 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | 697 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
685 TUNER_RATIO_SELECT_50; /* 50 kHz step */ 698 TUNER_RATIO_SELECT_50; /* 50 kHz step */
686 699
700 /* Bandswitch byte */
701 simple_radio_bandswitch(fe, &buffer[0]);
702
687 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps 703 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
688 freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = 704 freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
689 freq * (1/800) */ 705 freq * (1/800) */
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 7c0bc064c008..6a7f1a417c27 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -578,6 +578,31 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = {
578 }, 578 },
579}; 579};
580 580
581/* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */
582
583static struct tuner_range tuner_fm1216mk5_pal_ranges[] = {
584 { 16 * 158.00 /*MHz*/, 0xce, 0x01, },
585 { 16 * 441.00 /*MHz*/, 0xce, 0x02, },
586 { 16 * 864.00 , 0xce, 0x04, },
587};
588
589static struct tuner_params tuner_fm1216mk5_params[] = {
590 {
591 .type = TUNER_PARAM_TYPE_PAL,
592 .ranges = tuner_fm1216mk5_pal_ranges,
593 .count = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges),
594 .cb_first_if_lower_freq = 1,
595 .has_tda9887 = 1,
596 .port1_active = 1,
597 .port2_active = 1,
598 .port2_invert_for_secam_lc = 1,
599 .port1_fm_high_sensitivity = 1,
600 .default_top_mid = -2,
601 .default_top_secam_mid = -2,
602 .default_top_secam_high = -2,
603 },
604};
605
581/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */ 606/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */
582 607
583static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { 608static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
@@ -1254,6 +1279,28 @@ static struct tuner_params tuner_tcl_mf02gip_5n_params[] = {
1254 }, 1279 },
1255}; 1280};
1256 1281
1282/* 80-89 */
1283/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */
1284
1285static struct tuner_params tuner_fq1216lme_mk3_params[] = {
1286 {
1287 .type = TUNER_PARAM_TYPE_PAL,
1288 .ranges = tuner_fm1216me_mk3_pal_ranges,
1289 .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
1290 .cb_first_if_lower_freq = 1, /* not specified, but safe to do */
1291 .has_tda9887 = 1, /* TDA9886 */
1292 .port1_active = 1,
1293 .port2_active = 1,
1294 .port2_invert_for_secam_lc = 1,
1295 .default_top_low = 4,
1296 .default_top_mid = 4,
1297 .default_top_high = 4,
1298 .default_top_secam_low = 4,
1299 .default_top_secam_mid = 4,
1300 .default_top_secam_high = 4,
1301 },
1302};
1303
1257/* --------------------------------------------------------------------- */ 1304/* --------------------------------------------------------------------- */
1258 1305
1259struct tunertype tuners[] = { 1306struct tunertype tuners[] = {
@@ -1694,6 +1741,18 @@ struct tunertype tuners[] = {
1694 .initdata = tua603x_agc112, 1741 .initdata = tua603x_agc112,
1695 .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, 1742 .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
1696 }, 1743 },
1744 [TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */
1745 .name = "Philips PAL/SECAM multi (FM1216 MK5)",
1746 .params = tuner_fm1216mk5_params,
1747 .count = ARRAY_SIZE(tuner_fm1216mk5_params),
1748 },
1749
1750 /* 80-89 */
1751 [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */
1752 .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough",
1753 .params = tuner_fq1216lme_mk3_params,
1754 .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
1755 },
1697}; 1756};
1698EXPORT_SYMBOL(tuners); 1757EXPORT_SYMBOL(tuners);
1699 1758
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 7636c33bc1e9..b6da9c3873fe 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug, "enable verbose debug messages");
30 30
31static int no_poweroff; 31static int no_poweroff;
32module_param(no_poweroff, int, 0644); 32module_param(no_poweroff, int, 0644);
33MODULE_PARM_DESC(debug, "0 (default) powers device off when not used.\n" 33MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
34 "1 keep device energized and with tuner ready all the times.\n" 34 "1 keep device energized and with tuner ready all the times.\n"
35 " Faster, but consumes more power and keeps the device hotter\n"); 35 " Faster, but consumes more power and keeps the device hotter\n");
36 36
@@ -272,7 +272,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
272 fname = firmware_name; 272 fname = firmware_name;
273 273
274 tuner_dbg("Reading firmware %s\n", fname); 274 tuner_dbg("Reading firmware %s\n", fname);
275 rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev); 275 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
276 if (rc < 0) { 276 if (rc < 0) {
277 if (rc == -ENOENT) 277 if (rc == -ENOENT)
278 tuner_err("Error: firmware %s not found.\n", 278 tuner_err("Error: firmware %s not found.\n",
@@ -917,22 +917,29 @@ 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 } else if (priv->cur_fw.type & ATSC) { 922
923 offset = 1750000; 923 /*
924 } else { 924 * Digital modes require an offset to adjust to the
925 offset = 2750000; 925 * proper frequency.
926 * Analog modes require offset = 0
927 */
928 if (new_mode == T_DIGITAL_TV) {
929 /* Sets the offset according with firmware */
930 if (priv->cur_fw.type & DTV6)
931 offset = 1750000;
932 else if (priv->cur_fw.type & DTV7)
933 offset = 2250000;
934 else /* DTV8 or DTV78 */
935 offset = 2750000;
936
926 /* 937 /*
927 * We must adjust the offset by 500kHz in two cases in order 938 * We must adjust the offset by 500kHz when
928 * to correctly center the IF output: 939 * tuning a 7MHz VHF channel with DTV78 firmware
929 * 1) When the ZARLINK456 or DIBCOM52 tables were explicitly 940 * (used in Australia, Italy and Germany)
930 * selected and a 7MHz channel is tuned;
931 * 2) When tuning a VHF channel with DTV78 firmware.
932 */ 941 */
933 if (((priv->cur_fw.type & DTV7) && 942 if ((priv->cur_fw.type & DTV78) && freq < 470000000)
934 (priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) ||
935 ((priv->cur_fw.type & DTV78) && freq < 470000000))
936 offset -= 500000; 943 offset -= 500000;
937 } 944 }
938 945
@@ -991,7 +998,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
991 if (priv->ctrl.input1) 998 if (priv->ctrl.input1)
992 type |= INPUT1; 999 type |= INPUT1;
993 return generic_set_freq(fe, (625l * p->frequency) / 10, 1000 return generic_set_freq(fe, (625l * p->frequency) / 10,
994 T_ANALOG_TV, type, 0, 0); 1001 T_RADIO, type, 0, 0);
995 } 1002 }
996 1003
997 /* if std is not defined, choose one */ 1004 /* if std is not defined, choose one */
@@ -1022,21 +1029,20 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1022 switch(fe->ops.info.type) { 1029 switch(fe->ops.info.type) {
1023 case FE_OFDM: 1030 case FE_OFDM:
1024 bw = p->u.ofdm.bandwidth; 1031 bw = p->u.ofdm.bandwidth;
1025 break; 1032 /*
1026 case FE_QAM: 1033 * The only countries with 6MHz seem to be Taiwan/Uruguay.
1027 tuner_info("WARN: There are some reports that " 1034 * Both seem to require QAM firmware for OFDM decoding
1028 "QAM 6 MHz doesn't work.\n" 1035 * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com>
1029 "If this works for you, please report by " 1036 */
1030 "e-mail to: v4l-dvb-maintainer@linuxtv.org\n"); 1037 if (bw == BANDWIDTH_6_MHZ)
1031 bw = BANDWIDTH_6_MHZ; 1038 type |= QAM;
1032 type |= QAM;
1033 break; 1039 break;
1034 case FE_ATSC: 1040 case FE_ATSC:
1035 bw = BANDWIDTH_6_MHZ; 1041 bw = BANDWIDTH_6_MHZ;
1036 /* The only ATSC firmware (at least on v2.7) is D2633 */ 1042 /* The only ATSC firmware (at least on v2.7) is D2633 */
1037 type |= ATSC | D2633; 1043 type |= ATSC | D2633;
1038 break; 1044 break;
1039 /* DVB-S is not supported */ 1045 /* DVB-S and pure QAM (FE_QAM) are not supported */
1040 default: 1046 default:
1041 return -EINVAL; 1047 return -EINVAL;
1042 } 1048 }
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index b54598550dc4..f4ffcdc9b848 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2007 Xceive Corporation 4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> 5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -36,14 +37,20 @@ static int debug;
36module_param(debug, int, 0644); 37module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 38MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
38 39
40static int no_poweroff;
41module_param(no_poweroff, int, 0644);
42MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
43 "\t\t1 keep device energized and with tuner ready all the times.\n"
44 "\t\tFaster, but consumes more power and keeps the device hotter");
45
39static DEFINE_MUTEX(xc5000_list_mutex); 46static DEFINE_MUTEX(xc5000_list_mutex);
40static LIST_HEAD(hybrid_tuner_instance_list); 47static LIST_HEAD(hybrid_tuner_instance_list);
41 48
42#define dprintk(level, fmt, arg...) if (debug >= level) \ 49#define dprintk(level, fmt, arg...) if (debug >= level) \
43 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) 50 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
44 51
45#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" 52#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
46#define XC5000_DEFAULT_FIRMWARE_SIZE 12332 53#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
47 54
48struct xc5000_priv { 55struct xc5000_priv {
49 struct tuner_i2c_props i2c_props; 56 struct tuner_i2c_props i2c_props;
@@ -83,11 +90,11 @@ struct xc5000_priv {
83#define XREG_D_CODE 0x04 90#define XREG_D_CODE 0x04
84#define XREG_IF_OUT 0x05 91#define XREG_IF_OUT 0x05
85#define XREG_SEEK_MODE 0x07 92#define XREG_SEEK_MODE 0x07
86#define XREG_POWER_DOWN 0x0A 93#define XREG_POWER_DOWN 0x0A /* Obsolete */
87#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ 94#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
88#define XREG_SMOOTHEDCVBS 0x0E 95#define XREG_SMOOTHEDCVBS 0x0E
89#define XREG_XTALFREQ 0x0F 96#define XREG_XTALFREQ 0x0F
90#define XREG_FINERFFREQ 0x10 97#define XREG_FINERFREQ 0x10
91#define XREG_DDIMODE 0x11 98#define XREG_DDIMODE 0x11
92 99
93#define XREG_ADC_ENV 0x00 100#define XREG_ADC_ENV 0x00
@@ -100,6 +107,7 @@ struct xc5000_priv {
100#define XREG_VERSION 0x07 107#define XREG_VERSION 0x07
101#define XREG_PRODUCT_ID 0x08 108#define XREG_PRODUCT_ID 0x08
102#define XREG_BUSY 0x09 109#define XREG_BUSY 0x09
110#define XREG_BUILD 0x0D
103 111
104/* 112/*
105 Basic firmware description. This will remain with 113 Basic firmware description. This will remain with
@@ -191,27 +199,36 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
191 {"FM Radio-INPUT1", 0x0208, 0x9002} 199 {"FM Radio-INPUT1", 0x0208, 0x9002}
192}; 200};
193 201
194static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); 202static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
195static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); 203static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
196static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); 204static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
197static void xc5000_TunerReset(struct dvb_frontend *fe); 205static int xc5000_TunerReset(struct dvb_frontend *fe);
198 206
199static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) 207static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
200{ 208{
201 return xc5000_writeregs(priv, buf, len) 209 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
202 ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; 210 .flags = 0, .buf = buf, .len = len };
211
212 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
213 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
214 return XC_RESULT_I2C_WRITE_FAILURE;
215 }
216 return XC_RESULT_SUCCESS;
203} 217}
204 218
219/* This routine is never used because the only time we read data from the
220 i2c bus is when we read registers, and we want that to be an atomic i2c
221 transaction in case we are on a multi-master bus */
205static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) 222static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
206{ 223{
207 return xc5000_readregs(priv, buf, len) 224 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
208 ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS; 225 .flags = I2C_M_RD, .buf = buf, .len = len };
209}
210 226
211static int xc_reset(struct dvb_frontend *fe) 227 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
212{ 228 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
213 xc5000_TunerReset(fe); 229 return -EREMOTEIO;
214 return XC_RESULT_SUCCESS; 230 }
231 return 0;
215} 232}
216 233
217static void xc_wait(int wait_ms) 234static void xc_wait(int wait_ms)
@@ -219,7 +236,7 @@ static void xc_wait(int wait_ms)
219 msleep(wait_ms); 236 msleep(wait_ms);
220} 237}
221 238
222static void xc5000_TunerReset(struct dvb_frontend *fe) 239static int xc5000_TunerReset(struct dvb_frontend *fe)
223{ 240{
224 struct xc5000_priv *priv = fe->tuner_priv; 241 struct xc5000_priv *priv = fe->tuner_priv;
225 int ret; 242 int ret;
@@ -232,16 +249,21 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
232 priv->i2c_props.adap->algo_data, 249 priv->i2c_props.adap->algo_data,
233 DVB_FRONTEND_COMPONENT_TUNER, 250 DVB_FRONTEND_COMPONENT_TUNER,
234 XC5000_TUNER_RESET, 0); 251 XC5000_TUNER_RESET, 0);
235 if (ret) 252 if (ret) {
236 printk(KERN_ERR "xc5000: reset failed\n"); 253 printk(KERN_ERR "xc5000: reset failed\n");
237 } else 254 return XC_RESULT_RESET_FAILURE;
255 }
256 } else {
238 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); 257 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
258 return XC_RESULT_RESET_FAILURE;
259 }
260 return XC_RESULT_SUCCESS;
239} 261}
240 262
241static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) 263static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
242{ 264{
243 u8 buf[4]; 265 u8 buf[4];
244 int WatchDogTimer = 5; 266 int WatchDogTimer = 100;
245 int result; 267 int result;
246 268
247 buf[0] = (regAddr >> 8) & 0xFF; 269 buf[0] = (regAddr >> 8) & 0xFF;
@@ -263,7 +285,7 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
263 /* busy flag cleared */ 285 /* busy flag cleared */
264 break; 286 break;
265 } else { 287 } else {
266 xc_wait(100); /* wait 5 ms */ 288 xc_wait(5); /* wait 5 ms */
267 WatchDogTimer--; 289 WatchDogTimer--;
268 } 290 }
269 } 291 }
@@ -276,25 +298,6 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
276 return result; 298 return result;
277} 299}
278 300
279static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData)
280{
281 u8 buf[2];
282 int result;
283
284 buf[0] = (regAddr >> 8) & 0xFF;
285 buf[1] = regAddr & 0xFF;
286 result = xc_send_i2c_data(priv, buf, 2);
287 if (result != XC_RESULT_SUCCESS)
288 return result;
289
290 result = xc_read_i2c_data(priv, buf, 2);
291 if (result != XC_RESULT_SUCCESS)
292 return result;
293
294 *i2cData = buf[0] * 256 + buf[1];
295 return result;
296}
297
298static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) 301static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
299{ 302{
300 struct xc5000_priv *priv = fe->tuner_priv; 303 struct xc5000_priv *priv = fe->tuner_priv;
@@ -309,7 +312,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
309 len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; 312 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
310 if (len == 0x0000) { 313 if (len == 0x0000) {
311 /* RESET command */ 314 /* RESET command */
312 result = xc_reset(fe); 315 result = xc5000_TunerReset(fe);
313 index += 2; 316 index += 2;
314 if (result != XC_RESULT_SUCCESS) 317 if (result != XC_RESULT_SUCCESS)
315 return result; 318 return result;
@@ -371,15 +374,6 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
371 return ret; 374 return ret;
372} 375}
373 376
374static int xc_shutdown(struct xc5000_priv *priv)
375{
376 return XC_RESULT_SUCCESS;
377 /* Fixme: cannot bring tuner back alive once shutdown
378 * without reloading the driver modules.
379 * return xc_write_reg(priv, XREG_POWER_DOWN, 0);
380 */
381}
382
383static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) 377static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
384{ 378{
385 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, 379 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
@@ -408,7 +402,10 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
408 402
409 freq_code = (u16)(freq_hz / 15625); 403 freq_code = (u16)(freq_hz / 15625);
410 404
411 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); 405 /* Starting in firmware version 1.1.44, Xceive recommends using the
406 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
407 only be used for fast scanning for channel lock) */
408 return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
412} 409}
413 410
414 411
@@ -424,7 +421,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
424 421
425static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) 422static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
426{ 423{
427 return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope); 424 return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
428} 425}
429 426
430static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) 427static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
@@ -433,8 +430,8 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
433 u16 regData; 430 u16 regData;
434 u32 tmp; 431 u32 tmp;
435 432
436 result = xc_read_reg(priv, XREG_FREQ_ERROR, &regData); 433 result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
437 if (result) 434 if (result != XC_RESULT_SUCCESS)
438 return result; 435 return result;
439 436
440 tmp = (u32)regData; 437 tmp = (u32)regData;
@@ -444,7 +441,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
444 441
445static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) 442static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
446{ 443{
447 return xc_read_reg(priv, XREG_LOCK, lock_status); 444 return xc5000_readreg(priv, XREG_LOCK, lock_status);
448} 445}
449 446
450static int xc_get_version(struct xc5000_priv *priv, 447static int xc_get_version(struct xc5000_priv *priv,
@@ -454,8 +451,8 @@ static int xc_get_version(struct xc5000_priv *priv,
454 u16 data; 451 u16 data;
455 int result; 452 int result;
456 453
457 result = xc_read_reg(priv, XREG_VERSION, &data); 454 result = xc5000_readreg(priv, XREG_VERSION, &data);
458 if (result) 455 if (result != XC_RESULT_SUCCESS)
459 return result; 456 return result;
460 457
461 (*hw_majorversion) = (data >> 12) & 0x0F; 458 (*hw_majorversion) = (data >> 12) & 0x0F;
@@ -466,13 +463,18 @@ static int xc_get_version(struct xc5000_priv *priv,
466 return 0; 463 return 0;
467} 464}
468 465
466static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
467{
468 return xc5000_readreg(priv, XREG_BUILD, buildrev);
469}
470
469static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) 471static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
470{ 472{
471 u16 regData; 473 u16 regData;
472 int result; 474 int result;
473 475
474 result = xc_read_reg(priv, XREG_HSYNC_FREQ, &regData); 476 result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
475 if (result) 477 if (result != XC_RESULT_SUCCESS)
476 return result; 478 return result;
477 479
478 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; 480 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
@@ -481,12 +483,12 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
481 483
482static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) 484static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
483{ 485{
484 return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines); 486 return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
485} 487}
486 488
487static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) 489static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
488{ 490{
489 return xc_read_reg(priv, XREG_QUALITY, quality); 491 return xc5000_readreg(priv, XREG_QUALITY, quality);
490} 492}
491 493
492static u16 WaitForLock(struct xc5000_priv *priv) 494static u16 WaitForLock(struct xc5000_priv *priv)
@@ -504,7 +506,9 @@ static u16 WaitForLock(struct xc5000_priv *priv)
504 return lockState; 506 return lockState;
505} 507}
506 508
507static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) 509#define XC_TUNE_ANALOG 0
510#define XC_TUNE_DIGITAL 1
511static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
508{ 512{
509 int found = 0; 513 int found = 0;
510 514
@@ -513,8 +517,10 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz)
513 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) 517 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
514 return 0; 518 return 0;
515 519
516 if (WaitForLock(priv) == 1) 520 if (mode == XC_TUNE_ANALOG) {
517 found = 1; 521 if (WaitForLock(priv) == 1)
522 found = 1;
523 }
518 524
519 return found; 525 return found;
520} 526}
@@ -536,32 +542,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
536 } 542 }
537 543
538 *val = (bval[0] << 8) | bval[1]; 544 *val = (bval[0] << 8) | bval[1];
539 return 0; 545 return XC_RESULT_SUCCESS;
540}
541
542static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
543{
544 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
545 .flags = 0, .buf = buf, .len = len };
546
547 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
548 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n",
549 (int)len);
550 return -EREMOTEIO;
551 }
552 return 0;
553}
554
555static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
556{
557 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
558 .flags = I2C_M_RD, .buf = buf, .len = len };
559
560 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
561 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len);
562 return -EREMOTEIO;
563 }
564 return 0;
565} 546}
566 547
567static int xc5000_fwupload(struct dvb_frontend *fe) 548static int xc5000_fwupload(struct dvb_frontend *fe)
@@ -575,13 +556,13 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
575 XC5000_DEFAULT_FIRMWARE); 556 XC5000_DEFAULT_FIRMWARE);
576 557
577 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, 558 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
578 &priv->i2c_props.adap->dev); 559 priv->i2c_props.adap->dev.parent);
579 if (ret) { 560 if (ret) {
580 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); 561 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
581 ret = XC_RESULT_RESET_FAILURE; 562 ret = XC_RESULT_RESET_FAILURE;
582 goto out; 563 goto out;
583 } else { 564 } else {
584 printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n", 565 printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
585 fw->size); 566 fw->size);
586 ret = XC_RESULT_SUCCESS; 567 ret = XC_RESULT_SUCCESS;
587 } 568 }
@@ -590,8 +571,9 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
590 printk(KERN_ERR "xc5000: firmware incorrect size\n"); 571 printk(KERN_ERR "xc5000: firmware incorrect size\n");
591 ret = XC_RESULT_RESET_FAILURE; 572 ret = XC_RESULT_RESET_FAILURE;
592 } else { 573 } else {
593 printk(KERN_INFO "xc5000: firmware upload\n"); 574 printk(KERN_INFO "xc5000: firmware uploading...\n");
594 ret = xc_load_i2c_sequence(fe, fw->data); 575 ret = xc_load_i2c_sequence(fe, fw->data);
576 printk(KERN_INFO "xc5000: firmware upload complete...\n");
595 } 577 }
596 578
597out: 579out:
@@ -609,6 +591,7 @@ static void xc_debug_dump(struct xc5000_priv *priv)
609 u16 quality; 591 u16 quality;
610 u8 hw_majorversion = 0, hw_minorversion = 0; 592 u8 hw_majorversion = 0, hw_minorversion = 0;
611 u8 fw_majorversion = 0, fw_minorversion = 0; 593 u8 fw_majorversion = 0, fw_minorversion = 0;
594 u16 fw_buildversion = 0;
612 595
613 /* Wait for stats to stabilize. 596 /* Wait for stats to stabilize.
614 * Frame Lines needs two frame times after initial lock 597 * Frame Lines needs two frame times after initial lock
@@ -628,9 +611,10 @@ static void xc_debug_dump(struct xc5000_priv *priv)
628 611
629 xc_get_version(priv, &hw_majorversion, &hw_minorversion, 612 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
630 &fw_majorversion, &fw_minorversion); 613 &fw_majorversion, &fw_minorversion);
631 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n", 614 xc_get_buildversion(priv, &fw_buildversion);
615 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
632 hw_majorversion, hw_minorversion, 616 hw_majorversion, hw_minorversion,
633 fw_majorversion, fw_minorversion); 617 fw_majorversion, fw_minorversion, fw_buildversion);
634 618
635 xc_get_hsync_freq(priv, &hsync_freq_hz); 619 xc_get_hsync_freq(priv, &hsync_freq_hz);
636 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz); 620 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
@@ -648,27 +632,57 @@ static int xc5000_set_params(struct dvb_frontend *fe,
648 struct xc5000_priv *priv = fe->tuner_priv; 632 struct xc5000_priv *priv = fe->tuner_priv;
649 int ret; 633 int ret;
650 634
635 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
636 xc_load_fw_and_init_tuner(fe);
637
651 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); 638 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
652 639
653 switch (params->u.vsb.modulation) { 640 if (fe->ops.info.type == FE_ATSC) {
654 case VSB_8: 641 dprintk(1, "%s() ATSC\n", __func__);
655 case VSB_16: 642 switch (params->u.vsb.modulation) {
656 dprintk(1, "%s() VSB modulation\n", __func__); 643 case VSB_8:
644 case VSB_16:
645 dprintk(1, "%s() VSB modulation\n", __func__);
646 priv->rf_mode = XC_RF_MODE_AIR;
647 priv->freq_hz = params->frequency - 1750000;
648 priv->bandwidth = BANDWIDTH_6_MHZ;
649 priv->video_standard = DTV6;
650 break;
651 case QAM_64:
652 case QAM_256:
653 case QAM_AUTO:
654 dprintk(1, "%s() QAM modulation\n", __func__);
655 priv->rf_mode = XC_RF_MODE_CABLE;
656 priv->freq_hz = params->frequency - 1750000;
657 priv->bandwidth = BANDWIDTH_6_MHZ;
658 priv->video_standard = DTV6;
659 break;
660 default:
661 return -EINVAL;
662 }
663 } else if (fe->ops.info.type == FE_OFDM) {
664 dprintk(1, "%s() OFDM\n", __func__);
665 switch (params->u.ofdm.bandwidth) {
666 case BANDWIDTH_6_MHZ:
667 priv->bandwidth = BANDWIDTH_6_MHZ;
668 priv->video_standard = DTV6;
669 priv->freq_hz = params->frequency - 1750000;
670 break;
671 case BANDWIDTH_7_MHZ:
672 printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n");
673 return -EINVAL;
674 case BANDWIDTH_8_MHZ:
675 priv->bandwidth = BANDWIDTH_8_MHZ;
676 priv->video_standard = DTV8;
677 priv->freq_hz = params->frequency - 2750000;
678 break;
679 default:
680 printk(KERN_ERR "xc5000 bandwidth not set!\n");
681 return -EINVAL;
682 }
657 priv->rf_mode = XC_RF_MODE_AIR; 683 priv->rf_mode = XC_RF_MODE_AIR;
658 priv->freq_hz = params->frequency - 1750000; 684 } else {
659 priv->bandwidth = BANDWIDTH_6_MHZ; 685 printk(KERN_ERR "xc5000 modulation type not supported!\n");
660 priv->video_standard = DTV6;
661 break;
662 case QAM_64:
663 case QAM_256:
664 case QAM_AUTO:
665 dprintk(1, "%s() QAM modulation\n", __func__);
666 priv->rf_mode = XC_RF_MODE_CABLE;
667 priv->freq_hz = params->frequency - 1750000;
668 priv->bandwidth = BANDWIDTH_6_MHZ;
669 priv->video_standard = DTV6;
670 break;
671 default:
672 return -EINVAL; 686 return -EINVAL;
673 } 687 }
674 688
@@ -698,7 +712,7 @@ static int xc5000_set_params(struct dvb_frontend *fe,
698 return -EIO; 712 return -EIO;
699 } 713 }
700 714
701 xc_tune_channel(priv, priv->freq_hz); 715 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
702 716
703 if (debug) 717 if (debug)
704 xc_debug_dump(priv); 718 xc_debug_dump(priv);
@@ -725,8 +739,6 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
725 return ret; 739 return ret;
726} 740}
727 741
728static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
729
730static int xc5000_set_analog_params(struct dvb_frontend *fe, 742static int xc5000_set_analog_params(struct dvb_frontend *fe,
731 struct analog_parameters *params) 743 struct analog_parameters *params)
732{ 744{
@@ -807,7 +819,7 @@ tune_channel:
807 return -EREMOTEIO; 819 return -EREMOTEIO;
808 } 820 }
809 821
810 xc_tune_channel(priv, priv->freq_hz); 822 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
811 823
812 if (debug) 824 if (debug)
813 xc_debug_dump(priv); 825 xc_debug_dump(priv);
@@ -875,18 +887,18 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
875 887
876static int xc5000_sleep(struct dvb_frontend *fe) 888static int xc5000_sleep(struct dvb_frontend *fe)
877{ 889{
878 struct xc5000_priv *priv = fe->tuner_priv;
879 int ret; 890 int ret;
880 891
881 dprintk(1, "%s()\n", __func__); 892 dprintk(1, "%s()\n", __func__);
882 893
883 /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized 894 /* Avoid firmware reload on slow devices */
884 * once shutdown without reloading the driver. Maybe I am not 895 if (no_poweroff)
885 * doing something right. 896 return 0;
886 *
887 */
888 897
889 ret = xc_shutdown(priv); 898 /* According to Xceive technical support, the "powerdown" register
899 was removed in newer versions of the firmware. The "supported"
900 way to sleep the tuner is to pull the reset pin low for 10ms */
901 ret = xc5000_TunerReset(fe);
890 if (ret != XC_RESULT_SUCCESS) { 902 if (ret != XC_RESULT_SUCCESS) {
891 printk(KERN_ERR 903 printk(KERN_ERR
892 "xc5000: %s() unable to shutdown tuner\n", 904 "xc5000: %s() unable to shutdown tuner\n",
@@ -991,7 +1003,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
991 /* Check if firmware has been loaded. It is possible that another 1003 /* Check if firmware has been loaded. It is possible that another
992 instance of the driver has loaded the firmware. 1004 instance of the driver has loaded the firmware.
993 */ 1005 */
994 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) 1006 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
995 goto fail; 1007 goto fail;
996 1008
997 switch (id) { 1009 switch (id) {
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 3e1c472092ab..9e2148a19967 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -1,9 +1,7 @@
1/* 1/*
2 * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III 2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * 3 * flexcop-common.h - common header file for device-specific source files
4 * flexcop-common.h - common header file for device-specific source files also. 4 * see flexcop.c for copyright information
5 *
6 * see flexcop.c for copyright information.
7 */ 5 */
8#ifndef __FLEXCOP_COMMON_H__ 6#ifndef __FLEXCOP_COMMON_H__
9#define __FLEXCOP_COMMON_H__ 7#define __FLEXCOP_COMMON_H__
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index f7afab5944cf..efb4a6c2b57a 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -1,34 +1,27 @@
1/* 1/*
2 * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III 2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * 3 * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
4 * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC. 4 * see flexcop.c for copyright information
5 *
6 * see flexcop.c for copyright information.
7 */ 5 */
8#include <media/tuner.h> 6#include <media/tuner.h>
9
10#include "flexcop.h" 7#include "flexcop.h"
11
12#include "stv0299.h"
13#include "mt352.h"
14#include "nxt200x.h"
15#include "bcm3510.h"
16#include "stv0297.h"
17#include "mt312.h" 8#include "mt312.h"
18#include "lgdt330x.h" 9#include "stv0299.h"
19#include "dvb-pll.h"
20#include "tuner-simple.h"
21
22#include "s5h1420.h" 10#include "s5h1420.h"
23#include "itd1000.h" 11#include "itd1000.h"
24
25#include "cx24123.h"
26#include "cx24113.h" 12#include "cx24113.h"
27 13#include "cx24123.h"
28#include "isl6421.h" 14#include "isl6421.h"
15#include "mt352.h"
16#include "bcm3510.h"
17#include "nxt200x.h"
18#include "dvb-pll.h"
19#include "lgdt330x.h"
20#include "tuner-simple.h"
21#include "stv0297.h"
29 22
30/* lnb control */ 23/* lnb control */
31 24#if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE)
32static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 25static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
33{ 26{
34 struct flexcop_device *fc = fe->dvb->priv; 27 struct flexcop_device *fc = fe->dvb->priv;
@@ -37,65 +30,62 @@ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage
37 30
38 v = fc->read_ibi_reg(fc, misc_204); 31 v = fc->read_ibi_reg(fc, misc_204);
39 switch (voltage) { 32 switch (voltage) {
40 case SEC_VOLTAGE_OFF: 33 case SEC_VOLTAGE_OFF:
41 v.misc_204.ACPI1_sig = 1; 34 v.misc_204.ACPI1_sig = 1;
42 break; 35 break;
43 case SEC_VOLTAGE_13: 36 case SEC_VOLTAGE_13:
44 v.misc_204.ACPI1_sig = 0; 37 v.misc_204.ACPI1_sig = 0;
45 v.misc_204.LNB_L_H_sig = 0; 38 v.misc_204.LNB_L_H_sig = 0;
46 break; 39 break;
47 case SEC_VOLTAGE_18: 40 case SEC_VOLTAGE_18:
48 v.misc_204.ACPI1_sig = 0; 41 v.misc_204.ACPI1_sig = 0;
49 v.misc_204.LNB_L_H_sig = 1; 42 v.misc_204.LNB_L_H_sig = 1;
50 break; 43 break;
51 default: 44 default:
52 err("unknown SEC_VOLTAGE value"); 45 err("unknown SEC_VOLTAGE value");
53 return -EINVAL; 46 return -EINVAL;
54 } 47 }
55 return fc->write_ibi_reg(fc, misc_204, v); 48 return fc->write_ibi_reg(fc, misc_204, v);
56} 49}
50#endif
57 51
52#if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \
53 || defined(CONFIG_DVB_MT312_MODULE)
58static int flexcop_sleep(struct dvb_frontend* fe) 54static int flexcop_sleep(struct dvb_frontend* fe)
59{ 55{
60 struct flexcop_device *fc = fe->dvb->priv; 56 struct flexcop_device *fc = fe->dvb->priv;
61/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
62
63 if (fc->fe_sleep) 57 if (fc->fe_sleep)
64 return fc->fe_sleep(fe); 58 return fc->fe_sleep(fe);
65
66/* v.misc_204.ACPI3_sig = 1;
67 fc->write_ibi_reg(fc,misc_204,v);*/
68
69 return 0; 59 return 0;
70} 60}
61#endif
71 62
63/* SkyStar2 DVB-S rev 2.3 */
64#if defined(CONFIG_DVB_MT312_MODULE)
72static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 65static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
73{ 66{
74 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ 67/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
75 struct flexcop_device *fc = fe->dvb->priv; 68 struct flexcop_device *fc = fe->dvb->priv;
76 flexcop_ibi_value v; 69 flexcop_ibi_value v;
77 u16 ax; 70 u16 ax;
78 v.raw = 0; 71 v.raw = 0;
79
80 deb_tuner("tone = %u\n",tone); 72 deb_tuner("tone = %u\n",tone);
81 73
82 switch (tone) { 74 switch (tone) {
83 case SEC_TONE_ON: 75 case SEC_TONE_ON:
84 ax = 0x01ff; 76 ax = 0x01ff;
85 break; 77 break;
86 case SEC_TONE_OFF: 78 case SEC_TONE_OFF:
87 ax = 0; 79 ax = 0;
88 break; 80 break;
89 default: 81 default:
90 err("unknown SEC_TONE value"); 82 err("unknown SEC_TONE value");
91 return -EINVAL; 83 return -EINVAL;
92 } 84 }
93 85
94 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */ 86 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
95
96 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax; 87 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
97 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax; 88 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
98
99 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v); 89 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
100} 90}
101 91
@@ -110,17 +100,16 @@ static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
110static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data) 100static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
111{ 101{
112 int i, par = 1, d; 102 int i, par = 1, d;
113
114 for (i = 7; i >= 0; i--) { 103 for (i = 7; i >= 0; i--) {
115 d = (data >> i) & 1; 104 d = (data >> i) & 1;
116 par ^= d; 105 par ^= d;
117 flexcop_diseqc_send_bit(fe, d); 106 flexcop_diseqc_send_bit(fe, d);
118 } 107 }
119
120 flexcop_diseqc_send_bit(fe, par); 108 flexcop_diseqc_send_bit(fe, par);
121} 109}
122 110
123static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst) 111static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
112 int len, u8 *msg, unsigned long burst)
124{ 113{
125 int i; 114 int i;
126 115
@@ -129,7 +118,6 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un
129 118
130 for (i = 0; i < len; i++) 119 for (i = 0; i < len; i++)
131 flexcop_diseqc_send_byte(fe,msg[i]); 120 flexcop_diseqc_send_byte(fe,msg[i]);
132
133 mdelay(16); 121 mdelay(16);
134 122
135 if (burst != -1) { 123 if (burst != -1) {
@@ -146,50 +134,110 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un
146 return 0; 134 return 0;
147} 135}
148 136
149static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) 137static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
138 struct dvb_diseqc_master_cmd *cmd)
150{ 139{
151 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0); 140 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
152} 141}
153 142
154static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) 143static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
144 fe_sec_mini_cmd_t minicmd)
155{ 145{
156 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); 146 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
157} 147}
158 148
159/* dvb-s stv0299 */ 149static struct mt312_config skystar23_samsung_tbdu18132_config = {
160static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) 150 .demod_address = 0x0e,
151};
152
153static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe,
154 struct dvb_frontend_parameters *params)
155{
156 u8 buf[4];
157 u32 div;
158 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf,
159 .len = sizeof(buf) };
160 struct flexcop_device *fc = fe->dvb->priv;
161 div = (params->frequency + (125/2)) / 125;
162
163 buf[0] = (div >> 8) & 0x7f;
164 buf[1] = (div >> 0) & 0xff;
165 buf[2] = 0x84 | ((div >> 10) & 0x60);
166 buf[3] = 0x80;
167
168 if (params->frequency < 1550000)
169 buf[3] |= 0x02;
170
171 if (fe->ops.i2c_gate_ctrl)
172 fe->ops.i2c_gate_ctrl(fe, 1);
173 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
174 return -EIO;
175 return 0;
176}
177
178static int skystar2_rev23_attach(struct flexcop_device *fc,
179 struct i2c_adapter *i2c)
180{
181 fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
182 if (fc->fe != NULL) {
183 struct dvb_frontend_ops *ops = &fc->fe->ops;
184 ops->tuner_ops.set_params =
185 skystar23_samsung_tbdu18132_tuner_set_params;
186 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
187 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
188 ops->set_tone = flexcop_set_tone;
189 ops->set_voltage = flexcop_set_voltage;
190 fc->fe_sleep = ops->sleep;
191 ops->sleep = flexcop_sleep;
192 return 1;
193 }
194 return 0;
195}
196#endif
197
198/* SkyStar2 DVB-S rev 2.6 */
199#if defined(CONFIG_DVB_STV0299_MODULE)
200static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
201 u32 srate, u32 ratio)
161{ 202{
162 u8 aclk = 0; 203 u8 aclk = 0;
163 u8 bclk = 0; 204 u8 bclk = 0;
164 205
165 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } 206 if (srate < 1500000) {
166 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } 207 aclk = 0xb7; bclk = 0x47;
167 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } 208 } else if (srate < 3000000) {
168 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } 209 aclk = 0xb7; bclk = 0x4b;
169 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } 210 } else if (srate < 7000000) {
170 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } 211 aclk = 0xb7; bclk = 0x4f;
171 212 } else if (srate < 14000000) {
172 stv0299_writereg (fe, 0x13, aclk); 213 aclk = 0xb7; bclk = 0x53;
173 stv0299_writereg (fe, 0x14, bclk); 214 } else if (srate < 30000000) {
174 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); 215 aclk = 0xb6; bclk = 0x53;
175 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); 216 } else if (srate < 45000000) {
176 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); 217 aclk = 0xb4; bclk = 0x51;
218 }
177 219
220 stv0299_writereg(fe, 0x13, aclk);
221 stv0299_writereg(fe, 0x14, bclk);
222 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
223 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
224 stv0299_writereg(fe, 0x21, ratio & 0xf0);
178 return 0; 225 return 0;
179} 226}
180 227
181static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) 228static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe,
229 struct dvb_frontend_parameters *params)
182{ 230{
183 u8 buf[4]; 231 u8 buf[4];
184 u32 div; 232 u32 div;
185 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 233 struct i2c_msg msg = {
234 .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
186 struct flexcop_device *fc = fe->dvb->priv; 235 struct flexcop_device *fc = fe->dvb->priv;
187
188 div = params->frequency / 125; 236 div = params->frequency / 125;
189 237
190 buf[0] = (div >> 8) & 0x7f; 238 buf[0] = (div >> 8) & 0x7f;
191 buf[1] = div & 0xff; 239 buf[1] = div & 0xff;
192 buf[2] = 0x84; /* 0xC4 */ 240 buf[2] = 0x84; /* 0xC4 */
193 buf[3] = 0x08; 241 buf[3] = 0x08;
194 242
195 if (params->frequency < 1500000) 243 if (params->frequency < 1500000)
@@ -203,48 +251,48 @@ static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dv
203} 251}
204 252
205static u8 samsung_tbmu24112_inittab[] = { 253static u8 samsung_tbmu24112_inittab[] = {
206 0x01, 0x15, 254 0x01, 0x15,
207 0x02, 0x30, 255 0x02, 0x30,
208 0x03, 0x00, 256 0x03, 0x00,
209 0x04, 0x7D, 257 0x04, 0x7D,
210 0x05, 0x35, 258 0x05, 0x35,
211 0x06, 0x02, 259 0x06, 0x02,
212 0x07, 0x00, 260 0x07, 0x00,
213 0x08, 0xC3, 261 0x08, 0xC3,
214 0x0C, 0x00, 262 0x0C, 0x00,
215 0x0D, 0x81, 263 0x0D, 0x81,
216 0x0E, 0x23, 264 0x0E, 0x23,
217 0x0F, 0x12, 265 0x0F, 0x12,
218 0x10, 0x7E, 266 0x10, 0x7E,
219 0x11, 0x84, 267 0x11, 0x84,
220 0x12, 0xB9, 268 0x12, 0xB9,
221 0x13, 0x88, 269 0x13, 0x88,
222 0x14, 0x89, 270 0x14, 0x89,
223 0x15, 0xC9, 271 0x15, 0xC9,
224 0x16, 0x00, 272 0x16, 0x00,
225 0x17, 0x5C, 273 0x17, 0x5C,
226 0x18, 0x00, 274 0x18, 0x00,
227 0x19, 0x00, 275 0x19, 0x00,
228 0x1A, 0x00, 276 0x1A, 0x00,
229 0x1C, 0x00, 277 0x1C, 0x00,
230 0x1D, 0x00, 278 0x1D, 0x00,
231 0x1E, 0x00, 279 0x1E, 0x00,
232 0x1F, 0x3A, 280 0x1F, 0x3A,
233 0x20, 0x2E, 281 0x20, 0x2E,
234 0x21, 0x80, 282 0x21, 0x80,
235 0x22, 0xFF, 283 0x22, 0xFF,
236 0x23, 0xC1, 284 0x23, 0xC1,
237 0x28, 0x00, 285 0x28, 0x00,
238 0x29, 0x1E, 286 0x29, 0x1E,
239 0x2A, 0x14, 287 0x2A, 0x14,
240 0x2B, 0x0F, 288 0x2B, 0x0F,
241 0x2C, 0x09, 289 0x2C, 0x09,
242 0x2D, 0x05, 290 0x2D, 0x05,
243 0x31, 0x1F, 291 0x31, 0x1F,
244 0x32, 0x19, 292 0x32, 0x19,
245 0x33, 0xFE, 293 0x33, 0xFE,
246 0x34, 0x93, 294 0x34, 0x93,
247 0xff, 0xff, 295 0xff, 0xff,
248}; 296};
249 297
250static struct stv0299_config samsung_tbmu24112_config = { 298static struct stv0299_config samsung_tbmu24112_config = {
@@ -259,27 +307,155 @@ static struct stv0299_config samsung_tbmu24112_config = {
259 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, 307 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
260}; 308};
261 309
262/* dvb-t mt352 */ 310static int skystar2_rev26_attach(struct flexcop_device *fc,
263static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) 311 struct i2c_adapter *i2c)
312{
313 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
314 if (fc->fe != NULL) {
315 struct dvb_frontend_ops *ops = &fc->fe->ops;
316 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
317 ops->set_voltage = flexcop_set_voltage;
318 fc->fe_sleep = ops->sleep;
319 ops->sleep = flexcop_sleep;
320 return 1;
321 }
322 return 0;
323}
324#endif
325
326/* SkyStar2 DVB-S rev 2.7 */
327#if defined(CONFIG_DVB_S5H1420_MODULE)
328static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
329 .demod_address = 0x53,
330 .invert = 1,
331 .repeated_start_workaround = 1,
332 .serial_mpeg = 1,
333};
334
335static struct itd1000_config skystar2_rev2_7_itd1000_config = {
336 .i2c_address = 0x61,
337};
338
339static int skystar2_rev27_attach(struct flexcop_device *fc,
340 struct i2c_adapter *i2c)
341{
342 flexcop_ibi_value r108;
343 struct i2c_adapter *i2c_tuner;
344
345 /* enable no_base_addr - no repeated start when reading */
346 fc->fc_i2c_adap[0].no_base_addr = 1;
347 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
348 i2c);
349 if (!fc->fe)
350 goto fail;
351
352 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
353 if (!i2c_tuner)
354 goto fail;
355
356 fc->fe_sleep = fc->fe->ops.sleep;
357 fc->fe->ops.sleep = flexcop_sleep;
358
359 /* enable no_base_addr - no repeated start when reading */
360 fc->fc_i2c_adap[2].no_base_addr = 1;
361 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
362 0x08, 1, 1)) {
363 err("ISL6421 could NOT be attached");
364 goto fail_isl;
365 }
366 info("ISL6421 successfully attached");
367
368 /* the ITD1000 requires a lower i2c clock - is it a problem ? */
369 r108.raw = 0x00000506;
370 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
371 if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
372 &skystar2_rev2_7_itd1000_config)) {
373 err("ITD1000 could NOT be attached");
374 /* Should i2c clock be restored? */
375 goto fail_isl;
376 }
377 info("ITD1000 successfully attached");
378
379 return 1;
380
381fail_isl:
382 fc->fc_i2c_adap[2].no_base_addr = 0;
383fail:
384 /* for the next devices we need it again */
385 fc->fc_i2c_adap[0].no_base_addr = 0;
386 return 0;
387}
388#endif
389
390/* SkyStar2 rev 2.8 */
391#if defined(CONFIG_DVB_CX24123_MODULE)
392static struct cx24123_config skystar2_rev2_8_cx24123_config = {
393 .demod_address = 0x55,
394 .dont_use_pll = 1,
395 .agc_callback = cx24113_agc_callback,
396};
397
398static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
399 .i2c_addr = 0x54,
400 .xtal_khz = 10111,
401};
402
403static int skystar2_rev28_attach(struct flexcop_device *fc,
404 struct i2c_adapter *i2c)
405{
406 struct i2c_adapter *i2c_tuner;
407
408 fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
409 i2c);
410 if (!fc->fe)
411 return 0;
412
413 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);;
414 if (!i2c_tuner)
415 return 0;
416
417 if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
418 i2c_tuner)) {
419 err("CX24113 could NOT be attached");
420 return 0;
421 }
422 info("CX24113 successfully attached");
423
424 fc->fc_i2c_adap[2].no_base_addr = 1;
425 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
426 0x08, 0, 0)) {
427 err("ISL6421 could NOT be attached");
428 fc->fc_i2c_adap[2].no_base_addr = 0;
429 return 0;
430 }
431 info("ISL6421 successfully attached");
432 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
433 * IR-receiver (PIC16F818) - but the card has no input for that ??? */
434 return 1;
435}
436#endif
437
438/* AirStar DVB-T */
439#if defined(CONFIG_DVB_MT352_MODULE)
440static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
264{ 441{
265 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d }; 442 static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
266 static u8 mt352_reset [] = { 0x50, 0x80 }; 443 static u8 mt352_reset[] = { 0x50, 0x80 };
267 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 444 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
268 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 }; 445 static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
269 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; 446 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
270 447
271 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); 448 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
272 udelay(2000); 449 udelay(2000);
273 mt352_write(fe, mt352_reset, sizeof(mt352_reset)); 450 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
274 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); 451 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
275
276 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); 452 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
277 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); 453 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
278
279 return 0; 454 return 0;
280} 455}
281 456
282static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) 457static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe,
458 struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
283{ 459{
284 u32 div; 460 u32 div;
285 unsigned char bs = 0; 461 unsigned char bs = 0;
@@ -287,19 +463,20 @@ static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_fro
287 if (buf_len < 5) 463 if (buf_len < 5)
288 return -EINVAL; 464 return -EINVAL;
289 465
290 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ 466#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
291 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 467 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
292 468 if (params->frequency >= 48000000 && params->frequency <= 154000000) \
293 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09; 469 bs = 0x09;
294 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; 470 if (params->frequency >= 161000000 && params->frequency <= 439000000) \
295 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; 471 bs = 0x0a;
472 if (params->frequency >= 447000000 && params->frequency <= 863000000) \
473 bs = 0x08;
296 474
297 pllbuf[0] = 0x61; 475 pllbuf[0] = 0x61;
298 pllbuf[1] = div >> 8; 476 pllbuf[1] = div >> 8;
299 pllbuf[2] = div & 0xff; 477 pllbuf[2] = div & 0xff;
300 pllbuf[3] = 0xcc; 478 pllbuf[3] = 0xcc;
301 pllbuf[4] = bs; 479 pllbuf[4] = bs;
302
303 return 5; 480 return 5;
304} 481}
305 482
@@ -308,70 +485,95 @@ static struct mt352_config samsung_tdtc9251dh0_config = {
308 .demod_init = samsung_tdtc9251dh0_demod_init, 485 .demod_init = samsung_tdtc9251dh0_demod_init,
309}; 486};
310 487
311static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) 488static int airstar_dvbt_attach(struct flexcop_device *fc,
489 struct i2c_adapter *i2c)
490{
491 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
492 if (fc->fe != NULL) {
493 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
494 return 1;
495 }
496 return 0;
497}
498#endif
499
500/* AirStar ATSC 1st generation */
501#if defined(CONFIG_DVB_BCM3510_MODULE)
502static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
503 const struct firmware **fw, char* name)
312{ 504{
313 struct flexcop_device *fc = fe->dvb->priv; 505 struct flexcop_device *fc = fe->dvb->priv;
314 return request_firmware(fw, name, fc->dev); 506 return request_firmware(fw, name, fc->dev);
315} 507}
316 508
317static struct lgdt330x_config air2pc_atsc_hd5000_config = {
318 .demod_address = 0x59,
319 .demod_chip = LGDT3303,
320 .serial_mpeg = 0x04,
321 .clock_polarity_flip = 1,
322};
323
324static struct nxt200x_config samsung_tbmv_config = {
325 .demod_address = 0x0a,
326};
327
328static struct bcm3510_config air2pc_atsc_first_gen_config = { 509static struct bcm3510_config air2pc_atsc_first_gen_config = {
329 .demod_address = 0x0f, 510 .demod_address = 0x0f,
330 .request_firmware = flexcop_fe_request_firmware, 511 .request_firmware = flexcop_fe_request_firmware,
331}; 512};
332 513
333static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) 514static int airstar_atsc1_attach(struct flexcop_device *fc,
515 struct i2c_adapter *i2c)
334{ 516{
335 u8 buf[4]; 517 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
336 u32 div; 518 return fc->fe != NULL;
337 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 519}
338 struct flexcop_device *fc = fe->dvb->priv; 520#endif
339
340 div = (params->frequency + (125/2)) / 125;
341 521
342 buf[0] = (div >> 8) & 0x7f; 522/* AirStar ATSC 2nd generation */
343 buf[1] = (div >> 0) & 0xff; 523#if defined(CONFIG_DVB_NXT200X_MODULE)
344 buf[2] = 0x84 | ((div >> 10) & 0x60); 524static struct nxt200x_config samsung_tbmv_config = {
345 buf[3] = 0x80; 525 .demod_address = 0x0a,
526};
346 527
347 if (params->frequency < 1550000) 528static int airstar_atsc2_attach(struct flexcop_device *fc,
348 buf[3] |= 0x02; 529 struct i2c_adapter *i2c)
530{
531 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
532 if (!fc->fe)
533 return 0;
349 534
350 if (fe->ops.i2c_gate_ctrl) 535 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
351 fe->ops.i2c_gate_ctrl(fe, 1); 536 DVB_PLL_SAMSUNG_TBMV);
352 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
353 return -EIO;
354 return 0;
355} 537}
538#endif
356 539
357static struct mt312_config skystar23_samsung_tbdu18132_config = { 540/* AirStar ATSC 3rd generation */
358 541#if defined(CONFIG_DVB_LGDT330X_MODULE)
359 .demod_address = 0x0e, 542static struct lgdt330x_config air2pc_atsc_hd5000_config = {
543 .demod_address = 0x59,
544 .demod_chip = LGDT3303,
545 .serial_mpeg = 0x04,
546 .clock_polarity_flip = 1,
360}; 547};
361 548
549static int airstar_atsc3_attach(struct flexcop_device *fc,
550 struct i2c_adapter *i2c)
551{
552 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
553 if (!fc->fe)
554 return 0;
555
556 return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
557 TUNER_LG_TDVS_H06XF);
558}
559#endif
560
561/* CableStar2 DVB-C */
562#if defined(CONFIG_DVB_STV0297_MODULE)
362static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, 563static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
363 struct dvb_frontend_parameters *fep) 564 struct dvb_frontend_parameters *fep)
364{ 565{
365 struct flexcop_device *fc = fe->dvb->priv; 566 struct flexcop_device *fc = fe->dvb->priv;
366 u8 buf[4]; 567 u8 buf[4];
367 u16 div; 568 u16 div;
368 int ret; 569 int ret;
369 570
370/* 62.5 kHz * 10 */ 571/* 62.5 kHz * 10 */
371#define REF_FREQ 625 572#define REF_FREQ 625
372#define FREQ_OFFSET 36125 573#define FREQ_OFFSET 36125
373 574
374 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz 575 div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ;
576/* 4 MHz = 4000 KHz */
375 577
376 buf[0] = (u8)( div >> 8) & 0x7f; 578 buf[0] = (u8)( div >> 8) & 0x7f;
377 buf[1] = (u8) div & 0xff; 579 buf[1] = (u8) div & 0xff;
@@ -384,11 +586,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
384 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ 586 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
385 buf[2] = 0x95; 587 buf[2] = 0x95;
386 588
387// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 589/* Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
388// 47 - 153 0 * 0 0 0 0 0 1 0x01 590 * 47 - 153 0 * 0 0 0 0 0 1 0x01
389// 153 - 430 0 * 0 0 0 0 1 0 0x02 591 * 153 - 430 0 * 0 0 0 0 1 0 0x02
390// 430 - 822 0 * 0 0 1 0 0 0 0x08 592 * 430 - 822 0 * 0 0 1 0 0 0 0x08
391// 822 - 862 1 * 0 0 1 0 0 0 0x88 593 * 822 - 862 1 * 0 0 1 0 0 0 0x88 */
392 594
393 if (fep->frequency <= 153000000) buf[3] = 0x01; 595 if (fep->frequency <= 153000000) buf[3] = 0x01;
394 else if (fep->frequency <= 430000000) buf[3] = 0x02; 596 else if (fep->frequency <= 430000000) buf[3] = 0x02;
@@ -397,11 +599,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
397 599
398 if (fe->ops.i2c_gate_ctrl) 600 if (fe->ops.i2c_gate_ctrl)
399 fe->ops.i2c_gate_ctrl(fe, 0); 601 fe->ops.i2c_gate_ctrl(fe, 0);
400 deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); 602 deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency,
603 buf[0], buf[1], buf[2], buf[3]);
401 ret = fc->i2c_request(&fc->fc_i2c_adap[2], 604 ret = fc->i2c_request(&fc->fc_i2c_adap[2],
402 FC_WRITE, 0x61, buf[0], &buf[1], 3); 605 FC_WRITE, 0x61, buf[0], &buf[1], 3);
403 deb_tuner("tuner write returned: %d\n",ret); 606 deb_tuner("tuner write returned: %d\n",ret);
404
405 return ret; 607 return ret;
406} 608}
407 609
@@ -481,182 +683,73 @@ static u8 alps_tdee4_stv0297_inittab[] = {
481static struct stv0297_config alps_tdee4_stv0297_config = { 683static struct stv0297_config alps_tdee4_stv0297_config = {
482 .demod_address = 0x1c, 684 .demod_address = 0x1c,
483 .inittab = alps_tdee4_stv0297_inittab, 685 .inittab = alps_tdee4_stv0297_inittab,
484// .invert = 1,
485// .pll_set = alps_tdee4_stv0297_pll_set,
486};
487
488
489/* SkyStar2 rev2.7 (a/u) */
490static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
491 .demod_address = 0x53,
492 .invert = 1,
493 .repeated_start_workaround = 1,
494 .serial_mpeg = 1,
495};
496
497static struct itd1000_config skystar2_rev2_7_itd1000_config = {
498 .i2c_address = 0x61,
499}; 686};
500 687
501/* SkyStar2 rev2.8 */ 688static int cablestar2_attach(struct flexcop_device *fc,
502static struct cx24123_config skystar2_rev2_8_cx24123_config = { 689 struct i2c_adapter *i2c)
503 .demod_address = 0x55,
504 .dont_use_pll = 1,
505 .agc_callback = cx24113_agc_callback,
506};
507
508static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
509 .i2c_addr = 0x54,
510 .xtal_khz = 10111,
511};
512
513/* try to figure out the frontend, each card/box can have on of the following list */
514int flexcop_frontend_init(struct flexcop_device *fc)
515{ 690{
516 struct dvb_frontend_ops *ops;
517 struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap;
518 struct i2c_adapter *i2c_tuner;
519
520 /* enable no_base_addr - no repeated start when reading */
521 fc->fc_i2c_adap[0].no_base_addr = 1;
522 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c);
523 if (fc->fe != NULL) {
524 flexcop_ibi_value r108;
525 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
526 ops = &fc->fe->ops;
527
528 fc->fe_sleep = ops->sleep;
529 ops->sleep = flexcop_sleep;
530
531 fc->dev_type = FC_SKY_REV27;
532
533 /* enable no_base_addr - no repeated start when reading */
534 fc->fc_i2c_adap[2].no_base_addr = 1;
535 if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL)
536 err("ISL6421 could NOT be attached");
537 else
538 info("ISL6421 successfully attached");
539
540 /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */
541 r108.raw = 0x00000506;
542 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
543 if (i2c_tuner) {
544 if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL)
545 err("ITD1000 could NOT be attached");
546 else
547 info("ITD1000 successfully attached");
548 }
549 goto fe_found;
550 }
551 fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */
552
553 /* try the sky v2.8 (cx24123, isl6421) */
554 fc->fe = dvb_attach(cx24123_attach,
555 &skystar2_rev2_8_cx24123_config, i2c);
556 if (fc->fe != NULL) {
557 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
558 if (i2c_tuner != NULL) {
559 if (dvb_attach(cx24113_attach, fc->fe,
560 &skystar2_rev2_8_cx24113_config,
561 i2c_tuner) == NULL)
562 err("CX24113 could NOT be attached");
563 else
564 info("CX24113 successfully attached");
565 }
566
567 fc->dev_type = FC_SKY_REV28;
568
569 fc->fc_i2c_adap[2].no_base_addr = 1;
570 if (dvb_attach(isl6421_attach, fc->fe,
571 &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL)
572 err("ISL6421 could NOT be attached");
573 else
574 info("ISL6421 successfully attached");
575
576 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
577 * IR-receiver (PIC16F818) - but the card has no input for
578 * that ??? */
579
580 goto fe_found;
581 }
582
583 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
584 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
585 if (fc->fe != NULL) {
586 ops = &fc->fe->ops;
587
588 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
589
590 ops->set_voltage = flexcop_set_voltage;
591
592 fc->fe_sleep = ops->sleep;
593 ops->sleep = flexcop_sleep;
594
595 fc->dev_type = FC_SKY_REV26;
596 goto fe_found;
597 }
598
599 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
600 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
601 if (fc->fe != NULL) {
602 fc->dev_type = FC_AIR_DVBT;
603 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
604 goto fe_found;
605 }
606
607 /* try the air atsc 2nd generation (nxt2002) */
608 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
609 if (fc->fe != NULL) {
610 fc->dev_type = FC_AIR_ATSC2;
611 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
612 goto fe_found;
613 }
614
615 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
616 if (fc->fe != NULL) {
617 fc->dev_type = FC_AIR_ATSC3;
618 dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
619 TUNER_LG_TDVS_H06XF);
620 goto fe_found;
621 }
622
623 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
624 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
625 if (fc->fe != NULL) {
626 fc->dev_type = FC_AIR_ATSC1;
627 goto fe_found;
628 }
629
630 /* try the cable dvb (stv0297) */
631 fc->fc_i2c_adap[0].no_base_addr = 1; 691 fc->fc_i2c_adap[0].no_base_addr = 1;
632 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); 692 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
633 if (fc->fe != NULL) { 693 if (!fc->fe) {
634 fc->dev_type = FC_CABLE; 694 /* Reset for next frontend to try */
635 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; 695 fc->fc_i2c_adap[0].no_base_addr = 0;
636 goto fe_found; 696 return 0;
637 } 697 }
638 fc->fc_i2c_adap[0].no_base_addr = 0; 698 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
639 699 return 1;
640 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ 700}
641 fc->fe = dvb_attach(mt312_attach, 701#endif
642 &skystar23_samsung_tbdu18132_config, i2c); 702
643 if (fc->fe != NULL) { 703static struct {
644 ops = &fc->fe->ops; 704 flexcop_device_type_t type;
645 705 int (*attach)(struct flexcop_device *, struct i2c_adapter *);
646 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; 706} flexcop_frontends[] = {
647 707#if defined(CONFIG_DVB_S5H1420_MODULE)
648 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; 708 { FC_SKY_REV27, skystar2_rev27_attach },
649 ops->diseqc_send_burst = flexcop_diseqc_send_burst; 709#endif
650 ops->set_tone = flexcop_set_tone; 710#if defined(CONFIG_DVB_CX24123_MODULE)
651 ops->set_voltage = flexcop_set_voltage; 711 { FC_SKY_REV28, skystar2_rev28_attach },
652 712#endif
653 fc->fe_sleep = ops->sleep; 713#if defined(CONFIG_DVB_STV0299_MODULE)
654 ops->sleep = flexcop_sleep; 714 { FC_SKY_REV26, skystar2_rev26_attach },
715#endif
716#if defined(CONFIG_DVB_MT352_MODULE)
717 { FC_AIR_DVBT, airstar_dvbt_attach },
718#endif
719#if defined(CONFIG_DVB_NXT200X_MODULE)
720 { FC_AIR_ATSC2, airstar_atsc2_attach },
721#endif
722#if defined(CONFIG_DVB_LGDT330X_MODULE)
723 { FC_AIR_ATSC3, airstar_atsc3_attach },
724#endif
725#if defined(CONFIG_DVB_BCM3510_MODULE)
726 { FC_AIR_ATSC1, airstar_atsc1_attach },
727#endif
728#if defined(CONFIG_DVB_STV0297_MODULE)
729 { FC_CABLE, cablestar2_attach },
730#endif
731#if defined(CONFIG_DVB_MT312_MODULE)
732 { FC_SKY_REV23, skystar2_rev23_attach },
733#endif
734};
655 735
656 fc->dev_type = FC_SKY_REV23; 736/* try to figure out the frontend */
657 goto fe_found; 737int flexcop_frontend_init(struct flexcop_device *fc)
738{
739 int i;
740 for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
741 /* type needs to be set before, because of some workarounds
742 * done based on the probed card type */
743 fc->dev_type = flexcop_frontends[i].type;
744 if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
745 goto fe_found;
746 /* Clean up partially attached frontend */
747 if (fc->fe) {
748 dvb_frontend_detach(fc->fe);
749 fc->fe = NULL;
750 }
658 } 751 }
659 752 fc->dev_type = FC_UNK;
660 err("no frontend driver found for this B2C2/FlexCop adapter"); 753 err("no frontend driver found for this B2C2/FlexCop adapter");
661 return -ENODEV; 754 return -ENODEV;
662 755
@@ -664,9 +757,7 @@ fe_found:
664 info("found '%s' .", fc->fe->ops.info.name); 757 info("found '%s' .", fc->fe->ops.info.name);
665 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { 758 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
666 err("frontend registration failed!"); 759 err("frontend registration failed!");
667 ops = &fc->fe->ops; 760 dvb_frontend_detach(fc->fe);
668 if (ops->release != NULL)
669 ops->release(fc->fe);
670 fc->fe = NULL; 761 fc->fe = NULL;
671 return -EINVAL; 762 return -EINVAL;
672 } 763 }
@@ -680,6 +771,5 @@ void flexcop_frontend_exit(struct flexcop_device *fc)
680 dvb_unregister_frontend(fc->fe); 771 dvb_unregister_frontend(fc->fe);
681 dvb_frontend_detach(fc->fe); 772 dvb_frontend_detach(fc->fe);
682 } 773 }
683
684 fc->init_state &= ~FC_STATE_FE_INIT; 774 fc->init_state &= ~FC_STATE_FE_INIT;
685} 775}
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index e2bed5076485..fd1df2352764 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -200,7 +200,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
200 msgs[i].buf[0], &msgs[i].buf[1], 200 msgs[i].buf[0], &msgs[i].buf[1],
201 msgs[i].len - 1); 201 msgs[i].len - 1);
202 if (ret < 0) { 202 if (ret < 0) {
203 err("i2c master_xfer failed"); 203 deb_i2c("i2c master_xfer failed");
204 break; 204 break;
205 } 205 }
206 } 206 }
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index e56627d2f0f4..f06f3a9070f5 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -46,16 +46,16 @@ static const char *flexcop_revision_names[] = {
46}; 46};
47 47
48static const char *flexcop_device_names[] = { 48static const char *flexcop_device_names[] = {
49 "Unknown device", 49 [FC_UNK] = "Unknown device",
50 "Air2PC/AirStar 2 DVB-T", 50 [FC_CABLE] = "Cable2PC/CableStar 2 DVB-C",
51 "Air2PC/AirStar 2 ATSC 1st generation", 51 [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T",
52 "Air2PC/AirStar 2 ATSC 2nd generation", 52 [FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation",
53 "Sky2PC/SkyStar 2 DVB-S", 53 [FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation",
54 "Sky2PC/SkyStar 2 DVB-S (old version)", 54 [FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
55 "Cable2PC/CableStar 2 DVB-C", 55 [FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
56 "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", 56 [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
57 "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", 57 [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
58 "Sky2PC/SkyStar 2 DVB-S rev 2.8", 58 [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
59}; 59};
60 60
61static const char *flexcop_bus_names[] = { 61static const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 56d8fab688bb..a24c125331f0 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -508,12 +508,6 @@ static int __devinit bt878_probe(struct pci_dev *dev,
508 pci_set_master(dev); 508 pci_set_master(dev);
509 pci_set_drvdata(dev, bt); 509 pci_set_drvdata(dev, bt);
510 510
511/* if(init_bt878(btv) < 0) {
512 bt878_remove(dev);
513 return -EIO;
514 }
515*/
516
517 if ((result = bt878_mem_alloc(bt))) { 511 if ((result = bt878_mem_alloc(bt))) {
518 printk(KERN_ERR "bt878: failed to allocate memory!\n"); 512 printk(KERN_ERR "bt878: failed to allocate memory!\n");
519 goto fail2; 513 goto fail2;
@@ -579,7 +573,7 @@ static struct pci_driver bt878_pci_driver = {
579 .name = "bt878", 573 .name = "bt878",
580 .id_table = bt878_pci_tbl, 574 .id_table = bt878_pci_tbl,
581 .probe = bt878_probe, 575 .probe = bt878_probe,
582 .remove = bt878_remove, 576 .remove = __devexit_p(bt878_remove),
583}; 577};
584 578
585static int bt878_pci_driver_registered; 579static int bt878_pci_driver_registered;
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 971a8b18f6dd..4dbd7d4185af 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -51,6 +51,9 @@
51#ifndef PCI_VENDOR_ID_TRIGEM 51#ifndef PCI_VENDOR_ID_TRIGEM
52#define PCI_VENDOR_ID_TRIGEM 0x109f 52#define PCI_VENDOR_ID_TRIGEM 0x109f
53#endif 53#endif
54#ifndef PCI_VENDOR_ID_AXESS
55#define PCI_VENDOR_ID_AXESS 0x195d
56#endif
54#ifndef PCI_DEVICE_ID_DM1105 57#ifndef PCI_DEVICE_ID_DM1105
55#define PCI_DEVICE_ID_DM1105 0x036f 58#define PCI_DEVICE_ID_DM1105 0x036f
56#endif 59#endif
@@ -60,6 +63,9 @@
60#ifndef PCI_DEVICE_ID_DW2004 63#ifndef PCI_DEVICE_ID_DW2004
61#define PCI_DEVICE_ID_DW2004 0x2004 64#define PCI_DEVICE_ID_DW2004 0x2004
62#endif 65#endif
66#ifndef PCI_DEVICE_ID_DM05
67#define PCI_DEVICE_ID_DM05 0x1105
68#endif
63/* ----------------------------------------------- */ 69/* ----------------------------------------------- */
64/* sdmc dm1105 registers */ 70/* sdmc dm1105 registers */
65 71
@@ -150,6 +156,11 @@
150#define DM1105_LNB_13V 0x00010100 156#define DM1105_LNB_13V 0x00010100
151#define DM1105_LNB_18V 0x00000100 157#define DM1105_LNB_18V 0x00000100
152 158
159/* GPIO's for LNB power control for Axess DM05 */
160#define DM05_LNB_MASK 0x00000000
161#define DM05_LNB_13V 0x00020000
162#define DM05_LNB_18V 0x00030000
163
153static int ir_debug; 164static int ir_debug;
154module_param(ir_debug, int, 0644); 165module_param(ir_debug, int, 0644);
155MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); 166MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
@@ -188,6 +199,8 @@ struct dm1105dvb {
188 199
189 /* irq */ 200 /* irq */
190 struct work_struct work; 201 struct work_struct work;
202 struct workqueue_struct *wq;
203 char wqn[16];
191 204
192 /* dma */ 205 /* dma */
193 dma_addr_t dma_addr; 206 dma_addr_t dma_addr;
@@ -313,15 +326,25 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe)
313static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 326static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
314{ 327{
315 struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); 328 struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe);
329 u32 lnb_mask, lnb_13v, lnb_18v;
316 330
317 if (voltage == SEC_VOLTAGE_18) { 331 switch (dm1105dvb->pdev->subsystem_device) {
318 outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); 332 case PCI_DEVICE_ID_DM05:
319 outl(DM1105_LNB_18V, dm_io_mem(DM1105_GPIOVAL)); 333 lnb_mask = DM05_LNB_MASK;
320 } else { 334 lnb_13v = DM05_LNB_13V;
321 /*LNB ON-13V by default!*/ 335 lnb_18v = DM05_LNB_18V;
322 outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); 336 break;
323 outl(DM1105_LNB_13V, dm_io_mem(DM1105_GPIOVAL)); 337 default:
324 } 338 lnb_mask = DM1105_LNB_MASK;
339 lnb_13v = DM1105_LNB_13V;
340 lnb_18v = DM1105_LNB_18V;
341 }
342
343 outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR));
344 if (voltage == SEC_VOLTAGE_18)
345 outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL));
346 else
347 outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL));
325 348
326 return 0; 349 return 0;
327} 350}
@@ -440,7 +463,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
440 case (INTSTS_TSIRQ | INTSTS_IR): 463 case (INTSTS_TSIRQ | INTSTS_IR):
441 dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - 464 dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) -
442 inl(dm_io_mem(DM1105_STADR)); 465 inl(dm_io_mem(DM1105_STADR));
443 schedule_work(&dm1105dvb->work); 466 queue_work(dm1105dvb->wq, &dm1105dvb->work);
444 break; 467 break;
445 case INTSTS_IR: 468 case INTSTS_IR:
446 dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); 469 dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE));
@@ -567,46 +590,44 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
567 int ret; 590 int ret;
568 591
569 switch (dm1105dvb->pdev->subsystem_device) { 592 switch (dm1105dvb->pdev->subsystem_device) {
570 case PCI_DEVICE_ID_DW2002: 593 case PCI_DEVICE_ID_DW2004:
571 dm1105dvb->fe = dvb_attach( 594 dm1105dvb->fe = dvb_attach(
572 stv0299_attach, &sharp_z0194a_config, 595 cx24116_attach, &serit_sp2633_config,
573 &dm1105dvb->i2c_adap); 596 &dm1105dvb->i2c_adap);
597 if (dm1105dvb->fe)
598 dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;
574 599
600 break;
601 default:
602 dm1105dvb->fe = dvb_attach(
603 stv0299_attach, &sharp_z0194a_config,
604 &dm1105dvb->i2c_adap);
575 if (dm1105dvb->fe) { 605 if (dm1105dvb->fe) {
576 dm1105dvb->fe->ops.set_voltage = 606 dm1105dvb->fe->ops.set_voltage =
577 dm1105dvb_set_voltage; 607 dm1105dvb_set_voltage;
578 dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, 608 dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60,
579 &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); 609 &dm1105dvb->i2c_adap, DVB_PLL_OPERA1);
610 break;
580 } 611 }
581 612
582 if (!dm1105dvb->fe) { 613 dm1105dvb->fe = dvb_attach(
583 dm1105dvb->fe = dvb_attach( 614 stv0288_attach, &earda_config,
584 stv0288_attach, &earda_config, 615 &dm1105dvb->i2c_adap);
585 &dm1105dvb->i2c_adap); 616 if (dm1105dvb->fe) {
586 if (dm1105dvb->fe) { 617 dm1105dvb->fe->ops.set_voltage =
587 dm1105dvb->fe->ops.set_voltage = 618 dm1105dvb_set_voltage;
588 dm1105dvb_set_voltage; 619 dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61,
589 dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, 620 &dm1105dvb->i2c_adap);
590 &dm1105dvb->i2c_adap); 621 break;
591 }
592 } 622 }
593 623
594 if (!dm1105dvb->fe) {
595 dm1105dvb->fe = dvb_attach(
596 si21xx_attach, &serit_config,
597 &dm1105dvb->i2c_adap);
598 if (dm1105dvb->fe)
599 dm1105dvb->fe->ops.set_voltage =
600 dm1105dvb_set_voltage;
601 }
602 break;
603 case PCI_DEVICE_ID_DW2004:
604 dm1105dvb->fe = dvb_attach( 624 dm1105dvb->fe = dvb_attach(
605 cx24116_attach, &serit_sp2633_config, 625 si21xx_attach, &serit_config,
606 &dm1105dvb->i2c_adap); 626 &dm1105dvb->i2c_adap);
607 if (dm1105dvb->fe) 627 if (dm1105dvb->fe)
608 dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; 628 dm1105dvb->fe->ops.set_voltage =
609 break; 629 dm1105dvb_set_voltage;
630
610 } 631 }
611 632
612 if (!dm1105dvb->fe) { 633 if (!dm1105dvb->fe) {
@@ -630,10 +651,17 @@ static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac)
630 static u8 command[1] = { 0x28 }; 651 static u8 command[1] = { 0x28 };
631 652
632 struct i2c_msg msg[] = { 653 struct i2c_msg msg[] = {
633 { .addr = IIC_24C01_addr >> 1, .flags = 0, 654 {
634 .buf = command, .len = 1 }, 655 .addr = IIC_24C01_addr >> 1,
635 { .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD, 656 .flags = 0,
636 .buf = mac, .len = 6 }, 657 .buf = command,
658 .len = 1
659 }, {
660 .addr = IIC_24C01_addr >> 1,
661 .flags = I2C_M_RD,
662 .buf = mac,
663 .len = 6
664 },
637 }; 665 };
638 666
639 dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); 667 dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2);
@@ -752,14 +780,22 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
752 dm1105_ir_init(dm1105dvb); 780 dm1105_ir_init(dm1105dvb);
753 781
754 INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); 782 INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer);
783 sprintf(dm1105dvb->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
784 dm1105dvb->wq = create_singlethread_workqueue(dm1105dvb->wqn);
785 if (!dm1105dvb->wq)
786 goto err_dvb_net;
755 787
756 ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, 788 ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED,
757 DRIVER_NAME, dm1105dvb); 789 DRIVER_NAME, dm1105dvb);
758 if (ret < 0) 790 if (ret < 0)
759 goto err_free_irq; 791 goto err_workqueue;
760 792
761 return 0; 793 return 0;
762 794
795err_workqueue:
796 destroy_workqueue(dm1105dvb->wq);
797err_dvb_net:
798 dvb_net_release(&dm1105dvb->dvbnet);
763err_disconnect_frontend: 799err_disconnect_frontend:
764 dmx->disconnect_frontend(dmx); 800 dmx->disconnect_frontend(dmx);
765err_remove_mem_frontend: 801err_remove_mem_frontend:
@@ -776,8 +812,6 @@ err_i2c_del_adapter:
776 i2c_del_adapter(&dm1105dvb->i2c_adap); 812 i2c_del_adapter(&dm1105dvb->i2c_adap);
777err_dm1105dvb_hw_exit: 813err_dm1105dvb_hw_exit:
778 dm1105dvb_hw_exit(dm1105dvb); 814 dm1105dvb_hw_exit(dm1105dvb);
779err_free_irq:
780 free_irq(pdev->irq, dm1105dvb);
781err_pci_iounmap: 815err_pci_iounmap:
782 pci_iounmap(pdev, dm1105dvb->io_mem); 816 pci_iounmap(pdev, dm1105dvb->io_mem);
783err_pci_release_regions: 817err_pci_release_regions:
@@ -834,6 +868,11 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = {
834 .subvendor = PCI_ANY_ID, 868 .subvendor = PCI_ANY_ID,
835 .subdevice = PCI_DEVICE_ID_DW2004, 869 .subdevice = PCI_DEVICE_ID_DW2004,
836 }, { 870 }, {
871 .vendor = PCI_VENDOR_ID_AXESS,
872 .device = PCI_DEVICE_ID_DM05,
873 .subvendor = PCI_VENDOR_ID_AXESS,
874 .subdevice = PCI_DEVICE_ID_DM05,
875 }, {
837 /* empty */ 876 /* empty */
838 }, 877 },
839}; 878};
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index c35fbb8d8f4a..6d6121eb5d59 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -244,19 +244,13 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
244{ 244{
245 struct dvb_device *dvbdev = file->private_data; 245 struct dvb_device *dvbdev = file->private_data;
246 struct dmxdev *dmxdev = dvbdev->priv; 246 struct dmxdev *dmxdev = dvbdev->priv;
247 int ret;
248 247
249 if (dmxdev->exit) { 248 if (dmxdev->exit)
250 mutex_unlock(&dmxdev->mutex);
251 return -ENODEV; 249 return -ENODEV;
252 }
253 250
254 //mutex_lock(&dmxdev->mutex); 251 return dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
255 ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, 252 file->f_flags & O_NONBLOCK,
256 file->f_flags & O_NONBLOCK, 253 buf, count, ppos);
257 buf, count, ppos);
258 //mutex_unlock(&dmxdev->mutex);
259 return ret;
260} 254}
261 255
262static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, 256static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index e2eca0b1fe7c..cfe2768d24af 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -38,6 +38,16 @@
38*/ 38*/
39// #define DVB_DEMUX_SECTION_LOSS_LOG 39// #define DVB_DEMUX_SECTION_LOSS_LOG
40 40
41static int dvb_demux_tscheck;
42module_param(dvb_demux_tscheck, int, 0644);
43MODULE_PARM_DESC(dvb_demux_tscheck,
44 "enable transport stream continuity and TEI check");
45
46#define dprintk_tscheck(x...) do { \
47 if (dvb_demux_tscheck && printk_ratelimit()) \
48 printk(x); \
49 } while (0)
50
41/****************************************************************************** 51/******************************************************************************
42 * static inlined helper functions 52 * static inlined helper functions
43 ******************************************************************************/ 53 ******************************************************************************/
@@ -376,6 +386,36 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
376 u16 pid = ts_pid(buf); 386 u16 pid = ts_pid(buf);
377 int dvr_done = 0; 387 int dvr_done = 0;
378 388
389 if (dvb_demux_tscheck) {
390 if (!demux->cnt_storage)
391 demux->cnt_storage = vmalloc(MAX_PID + 1);
392
393 if (!demux->cnt_storage) {
394 printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
395 dvb_demux_tscheck = 0;
396 goto no_dvb_demux_tscheck;
397 }
398
399 /* check pkt counter */
400 if (pid < MAX_PID) {
401 if (buf[1] & 0x80)
402 dprintk_tscheck("TEI detected. "
403 "PID=0x%x data1=0x%x\n",
404 pid, buf[1]);
405
406 if ((buf[3] & 0xf) != demux->cnt_storage[pid])
407 dprintk_tscheck("TS packet counter mismatch. "
408 "PID=0x%x expected 0x%x "
409 "got 0x%x\n",
410 pid, demux->cnt_storage[pid],
411 buf[3] & 0xf);
412
413 demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf;
414 };
415 /* end check */
416 };
417no_dvb_demux_tscheck:
418
379 list_for_each_entry(feed, &demux->feed_list, list_head) { 419 list_for_each_entry(feed, &demux->feed_list, list_head) {
380 if ((feed->pid != pid) && (feed->pid != 0x2000)) 420 if ((feed->pid != pid) && (feed->pid != 0x2000))
381 continue; 421 continue;
@@ -1160,6 +1200,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
1160 int i; 1200 int i;
1161 struct dmx_demux *dmx = &dvbdemux->dmx; 1201 struct dmx_demux *dmx = &dvbdemux->dmx;
1162 1202
1203 dvbdemux->cnt_storage = NULL;
1163 dvbdemux->users = 0; 1204 dvbdemux->users = 0;
1164 dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); 1205 dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter));
1165 1206
@@ -1226,6 +1267,7 @@ EXPORT_SYMBOL(dvb_dmx_init);
1226 1267
1227void dvb_dmx_release(struct dvb_demux *dvbdemux) 1268void dvb_dmx_release(struct dvb_demux *dvbdemux)
1228{ 1269{
1270 vfree(dvbdemux->cnt_storage);
1229 vfree(dvbdemux->filter); 1271 vfree(dvbdemux->filter);
1230 vfree(dvbdemux->feed); 1272 vfree(dvbdemux->feed);
1231} 1273}
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 2c5f915329ca..2fe05d03240d 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -42,6 +42,8 @@
42 42
43#define DVB_DEMUX_MASK_MAX 18 43#define DVB_DEMUX_MASK_MAX 18
44 44
45#define MAX_PID 0x1fff
46
45struct dvb_demux_filter { 47struct dvb_demux_filter {
46 struct dmx_section_filter filter; 48 struct dmx_section_filter filter;
47 u8 maskandmode[DMX_MAX_FILTER_SIZE]; 49 u8 maskandmode[DMX_MAX_FILTER_SIZE];
@@ -127,6 +129,8 @@ struct dvb_demux {
127 129
128 struct mutex mutex; 130 struct mutex mutex;
129 spinlock_t lock; 131 spinlock_t lock;
132
133 uint8_t *cnt_storage; /* for TS continuity check */
130}; 134};
131 135
132int dvb_dmx_init(struct dvb_demux *dvbdemux); 136int dvb_dmx_init(struct dvb_demux *dvbdemux);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index ebc78157b9b8..f50ca7292a7d 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -543,6 +543,7 @@ restart:
543 543
544 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { 544 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
545 /* got signal or quitting */ 545 /* got signal or quitting */
546 fepriv->exit = 1;
546 break; 547 break;
547 } 548 }
548 549
@@ -656,6 +657,7 @@ restart:
656 } 657 }
657 658
658 fepriv->thread = NULL; 659 fepriv->thread = NULL;
660 fepriv->exit = 0;
659 mb(); 661 mb();
660 662
661 dvb_frontend_wakeup(fe); 663 dvb_frontend_wakeup(fe);
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 1bb66e1ed5a7..496c1a37034c 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -261,6 +261,7 @@ config DVB_USB_DW2102
261 select DVB_STB6000 if !DVB_FE_CUSTOMISE 261 select DVB_STB6000 if !DVB_FE_CUSTOMISE
262 select DVB_CX24116 if !DVB_FE_CUSTOMISE 262 select DVB_CX24116 if !DVB_FE_CUSTOMISE
263 select DVB_SI21XX if !DVB_FE_CUSTOMISE 263 select DVB_SI21XX if !DVB_FE_CUSTOMISE
264 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
264 help 265 help
265 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers 266 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
266 and the TeVii S650. 267 and the TeVii S650.
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 53bfc8e42fb9..4cb31e7c13c2 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -40,7 +40,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
40static DEFINE_MUTEX(af9015_usb_mutex); 40static DEFINE_MUTEX(af9015_usb_mutex);
41 41
42static struct af9015_config af9015_config; 42static struct af9015_config af9015_config;
43static struct dvb_usb_device_properties af9015_properties[2]; 43static struct dvb_usb_device_properties af9015_properties[3];
44static int af9015_properties_count = ARRAY_SIZE(af9015_properties); 44static int af9015_properties_count = ARRAY_SIZE(af9015_properties);
45 45
46static struct af9013_config af9015_af9013_config[] = { 46static struct af9013_config af9015_af9013_config[] = {
@@ -538,7 +538,7 @@ exit:
538/* dump eeprom */ 538/* dump eeprom */
539static int af9015_eeprom_dump(struct dvb_usb_device *d) 539static int af9015_eeprom_dump(struct dvb_usb_device *d)
540{ 540{
541 char buf[52], buf2[4]; 541 char buf[4+3*16+1], buf2[4];
542 u8 reg, val; 542 u8 reg, val;
543 543
544 for (reg = 0; ; reg++) { 544 for (reg = 0; ; reg++) {
@@ -1261,7 +1261,11 @@ static struct usb_device_id af9015_usb_table[] = {
1261 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, 1261 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
1262 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, 1262 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
1263 {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, 1263 {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
1264 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, 1264/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
1265 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
1266 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
1267 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
1268 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
1265 {0}, 1269 {0},
1266}; 1270};
1267MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1271MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1321,7 +1325,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1321 1325
1322 .i2c_algo = &af9015_i2c_algo, 1326 .i2c_algo = &af9015_i2c_algo,
1323 1327
1324 .num_device_descs = 9, 1328 .num_device_descs = 9, /* max 9 */
1325 .devices = { 1329 .devices = {
1326 { 1330 {
1327 .name = "Afatech AF9015 DVB-T USB2.0 stick", 1331 .name = "Afatech AF9015 DVB-T USB2.0 stick",
@@ -1426,7 +1430,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1426 1430
1427 .i2c_algo = &af9015_i2c_algo, 1431 .i2c_algo = &af9015_i2c_algo,
1428 1432
1429 .num_device_descs = 9, 1433 .num_device_descs = 9, /* max 9 */
1430 .devices = { 1434 .devices = {
1431 { 1435 {
1432 .name = "Xtensions XD-380", 1436 .name = "Xtensions XD-380",
@@ -1478,7 +1482,85 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1478 .warm_ids = {NULL}, 1482 .warm_ids = {NULL},
1479 }, 1483 },
1480 } 1484 }
1481 } 1485 }, {
1486 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1487
1488 .usb_ctrl = DEVICE_SPECIFIC,
1489 .download_firmware = af9015_download_firmware,
1490 .firmware = "dvb-usb-af9015.fw",
1491 .no_reconnect = 1,
1492
1493 .size_of_priv = sizeof(struct af9015_state), \
1494
1495 .num_adapters = 2,
1496 .adapter = {
1497 {
1498 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1499 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1500
1501 .pid_filter_count = 32,
1502 .pid_filter = af9015_pid_filter,
1503 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1504
1505 .frontend_attach =
1506 af9015_af9013_frontend_attach,
1507 .tuner_attach = af9015_tuner_attach,
1508 .stream = {
1509 .type = USB_BULK,
1510 .count = 6,
1511 .endpoint = 0x84,
1512 },
1513 },
1514 {
1515 .frontend_attach =
1516 af9015_af9013_frontend_attach,
1517 .tuner_attach = af9015_tuner_attach,
1518 .stream = {
1519 .type = USB_BULK,
1520 .count = 6,
1521 .endpoint = 0x85,
1522 .u = {
1523 .bulk = {
1524 .buffersize =
1525 TS_USB20_MAX_PACKET_SIZE,
1526 }
1527 }
1528 },
1529 }
1530 },
1531
1532 .identify_state = af9015_identify_state,
1533
1534 .rc_query = af9015_rc_query,
1535 .rc_interval = 150,
1536
1537 .i2c_algo = &af9015_i2c_algo,
1538
1539 .num_device_descs = 4, /* max 9 */
1540 .devices = {
1541 {
1542 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
1543 .cold_ids = {&af9015_usb_table[21], NULL},
1544 .warm_ids = {NULL},
1545 },
1546 {
1547 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
1548 "V3.0",
1549 .cold_ids = {&af9015_usb_table[22], NULL},
1550 .warm_ids = {NULL},
1551 },
1552 {
1553 .name = "KWorld Digial MC-810",
1554 .cold_ids = {&af9015_usb_table[23], NULL},
1555 .warm_ids = {NULL},
1556 },
1557 {
1558 .name = "Genius TVGo DVB-T03",
1559 .cold_ids = {&af9015_usb_table[24], NULL},
1560 .warm_ids = {NULL},
1561 },
1562 }
1563 },
1482}; 1564};
1483 1565
1484static int af9015_usb_probe(struct usb_interface *intf, 1566static int af9015_usb_probe(struct usb_interface *intf,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 8ddbadf62194..818b2ab584bf 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1346,9 +1346,9 @@ static int dib0700_xc5000_tuner_callback(void *priv, int component,
1346 if (command == XC5000_TUNER_RESET) { 1346 if (command == XC5000_TUNER_RESET) {
1347 /* Reset the tuner */ 1347 /* Reset the tuner */
1348 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0); 1348 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1349 msleep(330); /* from Windows USB trace */ 1349 msleep(10);
1350 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1); 1350 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1351 msleep(330); /* from Windows USB trace */ 1351 msleep(10);
1352 } else { 1352 } else {
1353 err("xc5000: unknown tuner callback command: %d\n", command); 1353 err("xc5000: unknown tuner callback command: %d\n", command);
1354 return -EINVAL; 1354 return -EINVAL;
@@ -1493,6 +1493,10 @@ struct usb_device_id dib0700_usb_id_table[] = {
1493 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, 1493 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
1494 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, 1494 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
1495 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, 1495 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
1496/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) },
1497 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) },
1498 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
1499 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
1496 { 0 } /* Terminating entry */ 1500 { 0 } /* Terminating entry */
1497}; 1501};
1498MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1502MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1692,7 +1696,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1692 }, 1696 },
1693 }, 1697 },
1694 1698
1695 .num_device_descs = 11, 1699 .num_device_descs = 12,
1696 .devices = { 1700 .devices = {
1697 { "DiBcom STK7070P reference design", 1701 { "DiBcom STK7070P reference design",
1698 { &dib0700_usb_id_table[15], NULL }, 1702 { &dib0700_usb_id_table[15], NULL },
@@ -1726,8 +1730,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1726 { &dib0700_usb_id_table[30], NULL }, 1730 { &dib0700_usb_id_table[30], NULL },
1727 { NULL }, 1731 { NULL },
1728 }, 1732 },
1729 { "Terratec Cinergy T USB XXS", 1733 { "Terratec Cinergy T USB XXS/ T3",
1730 { &dib0700_usb_id_table[33], NULL }, 1734 { &dib0700_usb_id_table[33],
1735 &dib0700_usb_id_table[52], NULL },
1731 { NULL }, 1736 { NULL },
1732 }, 1737 },
1733 { "Elgato EyeTV DTT", 1738 { "Elgato EyeTV DTT",
@@ -1738,6 +1743,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1738 { &dib0700_usb_id_table[45], NULL }, 1743 { &dib0700_usb_id_table[45], NULL },
1739 { NULL }, 1744 { NULL },
1740 }, 1745 },
1746 { "Elgato EyeTV Dtt Dlx PD378S",
1747 { &dib0700_usb_id_table[50], NULL },
1748 { NULL },
1749 },
1741 }, 1750 },
1742 1751
1743 .rc_interval = DEFAULT_RC_INTERVAL, 1752 .rc_interval = DEFAULT_RC_INTERVAL,
@@ -1784,8 +1793,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1784 { &dib0700_usb_id_table[36], NULL }, 1793 { &dib0700_usb_id_table[36], NULL },
1785 { NULL }, 1794 { NULL },
1786 }, 1795 },
1787 { "Terratec Cinergy DT USB XS Diversity", 1796 { "Terratec Cinergy DT USB XS Diversity/ T5",
1788 { &dib0700_usb_id_table[43], NULL }, 1797 { &dib0700_usb_id_table[43],
1798 &dib0700_usb_id_table[53], NULL},
1789 { NULL }, 1799 { NULL },
1790 }, 1800 },
1791 { "Sony PlayTV", 1801 { "Sony PlayTV",
@@ -1812,7 +1822,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1812 }, 1822 },
1813 }, 1823 },
1814 1824
1815 .num_device_descs = 7, 1825 .num_device_descs = 8,
1816 .devices = { 1826 .devices = {
1817 { "Terratec Cinergy HT USB XE", 1827 { "Terratec Cinergy HT USB XE",
1818 { &dib0700_usb_id_table[27], NULL }, 1828 { &dib0700_usb_id_table[27], NULL },
@@ -1842,6 +1852,11 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1842 { &dib0700_usb_id_table[48], NULL }, 1852 { &dib0700_usb_id_table[48], NULL },
1843 { NULL }, 1853 { NULL },
1844 }, 1854 },
1855 { "Leadtek WinFast DTV Dongle H",
1856 { &dib0700_usb_id_table[51], NULL },
1857 { NULL },
1858 },
1859
1845 }, 1860 },
1846 .rc_interval = DEFAULT_RC_INTERVAL, 1861 .rc_interval = DEFAULT_RC_INTERVAL,
1847 .rc_key_map = dib0700_rc_keys, 1862 .rc_key_map = dib0700_rc_keys,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 8ee6cd4da9e7..8dbad1ec53c4 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -133,14 +133,17 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
133 133
134 for (i = 0; i < num; i++) { 134 for (i = 0; i < num; i++) {
135 /* write/read request */ 135 /* write/read request */
136 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { 136 if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
137 && (msg[i+1].flags & I2C_M_RD)) {
137 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, 138 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
138 msg[i+1].buf,msg[i+1].len) < 0) 139 msg[i+1].buf,msg[i+1].len) < 0)
139 break; 140 break;
140 i++; 141 i++;
141 } else 142 } else if ((msg[i].flags & I2C_M_RD) == 0) {
142 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) 143 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
143 break; 144 break;
145 } else
146 break;
144 } 147 }
145 148
146 mutex_unlock(&d->i2c_mutex); 149 mutex_unlock(&d->i2c_mutex);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index f506c74119f3..9593b7289994 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -80,6 +80,7 @@
80#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 80#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
81#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 81#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78
82#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 82#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
83#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397
83#define USB_PID_CONEXANT_D680_DMB 0x86d6 84#define USB_PID_CONEXANT_D680_DMB 0x86d6
84#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 85#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
85#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 86#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
@@ -97,6 +98,7 @@
97#define USB_PID_DPOSH_M9206_COLD 0x9206 98#define USB_PID_DPOSH_M9206_COLD 0x9206
98#define USB_PID_DPOSH_M9206_WARM 0xa090 99#define USB_PID_DPOSH_M9206_WARM 0xa090
99#define USB_PID_UNIWILL_STK7700P 0x6003 100#define USB_PID_UNIWILL_STK7700P 0x6003
101#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012
100#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 102#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
101#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 103#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
102#define USB_PID_INTEL_CE9500 0x9500 104#define USB_PID_INTEL_CE9500 0x9500
@@ -104,6 +106,7 @@
104#define USB_PID_KWORLD_395U 0xe396 106#define USB_PID_KWORLD_395U 0xe396
105#define USB_PID_KWORLD_395U_2 0xe39b 107#define USB_PID_KWORLD_395U_2 0xe39b
106#define USB_PID_KWORLD_395U_3 0xe395 108#define USB_PID_KWORLD_395U_3 0xe395
109#define USB_PID_KWORLD_MC810 0xc810
107#define USB_PID_KWORLD_PC160_2T 0xc160 110#define USB_PID_KWORLD_PC160_2T 0xc160
108#define USB_PID_KWORLD_VSTREAM_COLD 0x17de 111#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
109#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 112#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
@@ -171,6 +174,7 @@
171#define USB_PID_AVERMEDIA_A309 0xa309 174#define USB_PID_AVERMEDIA_A309 0xa309
172#define USB_PID_AVERMEDIA_A310 0xa310 175#define USB_PID_AVERMEDIA_A310 0xa310
173#define USB_PID_AVERMEDIA_A850 0x850a 176#define USB_PID_AVERMEDIA_A850 0x850a
177#define USB_PID_AVERMEDIA_A805 0xa805
174#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 178#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
175#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 179#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
176#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 180#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
@@ -178,6 +182,8 @@
178#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 182#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
179#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 183#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
180#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 184#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
185#define USB_PID_TERRATEC_T3 0x10a0
186#define USB_PID_TERRATEC_T5 0x10a1
181#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e 187#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
182#define USB_PID_PINNACLE_PCTV2000E 0x022c 188#define USB_PID_PINNACLE_PCTV2000E 0x022c
183#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 189#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
@@ -222,6 +228,7 @@
222#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 228#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
223#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 229#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
224#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 230#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
231#define USB_PID_WINFAST_DTV_DONGLE_H 0x60f6
225#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 232#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01
226#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 233#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029
227#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 234#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200
@@ -251,5 +258,6 @@
251#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 258#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
252#define USB_PID_SONY_PLAYTV 0x0003 259#define USB_PID_SONY_PLAYTV 0x0003
253#define USB_PID_ELGATO_EYETV_DTT 0x0021 260#define USB_PID_ELGATO_EYETV_DTT 0x0021
261#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
254 262
255#endif 263#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index b5157518a300..e441d274e6c1 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties {
223 int generic_bulk_ctrl_endpoint; 223 int generic_bulk_ctrl_endpoint;
224 224
225 int num_device_descs; 225 int num_device_descs;
226 struct dvb_usb_device_description devices[11]; 226 struct dvb_usb_device_description devices[12];
227}; 227};
228 228
229/** 229/**
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index c65f273ff313..75de49c0d943 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,7 +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 Card 2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3* 3* TeVii S600, S650 Cards
4* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) 4* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
5* 5*
6* This program is free software; you can redistribute it and/or modify it 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 7* under the terms of the GNU General Public License as published by the
@@ -17,6 +17,7 @@
17#include "stb6000.h" 17#include "stb6000.h"
18#include "eds1547.h" 18#include "eds1547.h"
19#include "cx24116.h" 19#include "cx24116.h"
20#include "tda1002x.h"
20 21
21#ifndef USB_PID_DW2102 22#ifndef USB_PID_DW2102
22#define USB_PID_DW2102 0x2102 23#define USB_PID_DW2102 0x2102
@@ -26,10 +27,18 @@
26#define USB_PID_DW2104 0x2104 27#define USB_PID_DW2104 0x2104
27#endif 28#endif
28 29
30#ifndef USB_PID_DW3101
31#define USB_PID_DW3101 0x3101
32#endif
33
29#ifndef USB_PID_CINERGY_S 34#ifndef USB_PID_CINERGY_S
30#define USB_PID_CINERGY_S 0x0064 35#define USB_PID_CINERGY_S 0x0064
31#endif 36#endif
32 37
38#ifndef USB_PID_TEVII_S650
39#define USB_PID_TEVII_S650 0xd650
40#endif
41
33#define DW210X_READ_MSG 0 42#define DW210X_READ_MSG 0
34#define DW210X_WRITE_MSG 1 43#define DW210X_WRITE_MSG 1
35 44
@@ -40,18 +49,21 @@
40#define DW2102_VOLTAGE_CTRL (0x1800) 49#define DW2102_VOLTAGE_CTRL (0x1800)
41#define DW2102_RC_QUERY (0x1a00) 50#define DW2102_RC_QUERY (0x1a00)
42 51
43struct dw210x_state { 52struct dvb_usb_rc_keys_table {
44 u32 last_key_pressed; 53 struct dvb_usb_rc_key *rc_keys;
45}; 54 int rc_keys_size;
46struct dw210x_rc_keys {
47 u32 keycode;
48 u32 event;
49}; 55};
50 56
51/* debug */ 57/* debug */
52static int dvb_usb_dw2102_debug; 58static int dvb_usb_dw2102_debug;
53module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 59module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
54MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); 60MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
61 DVB_USB_DEBUG_STATUS);
62
63/* keymaps */
64static int ir_keymap;
65module_param_named(keymap, ir_keymap, int, 0644);
66MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ...");
55 67
56DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 68DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
57 69
@@ -79,7 +91,7 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
79static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 91static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
80 int num) 92 int num)
81{ 93{
82struct dvb_usb_device *d = i2c_get_adapdata(adap); 94 struct dvb_usb_device *d = i2c_get_adapdata(adap);
83 int i = 0, ret = 0; 95 int i = 0, ret = 0;
84 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 96 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
85 u16 value; 97 u16 value;
@@ -205,6 +217,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
205 mutex_unlock(&d->i2c_mutex); 217 mutex_unlock(&d->i2c_mutex);
206 return num; 218 return num;
207} 219}
220
208static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 221static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
209{ 222{
210 struct dvb_usb_device *d = i2c_get_adapdata(adap); 223 struct dvb_usb_device *d = i2c_get_adapdata(adap);
@@ -219,7 +232,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
219 case 2: { 232 case 2: {
220 /* read */ 233 /* read */
221 /* first write first register number */ 234 /* first write first register number */
222 u8 ibuf [msg[1].len + 2], obuf[3]; 235 u8 ibuf[msg[1].len + 2], obuf[3];
223 obuf[0] = 0xd0; 236 obuf[0] = 0xd0;
224 obuf[1] = msg[0].len; 237 obuf[1] = msg[0].len;
225 obuf[2] = msg[0].buf[0]; 238 obuf[2] = msg[0].buf[0];
@@ -293,7 +306,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
293 case 2: { 306 case 2: {
294 /* read */ 307 /* read */
295 /* first write first register number */ 308 /* first write first register number */
296 u8 ibuf [msg[1].len + 2], obuf[3]; 309 u8 ibuf[msg[1].len + 2], obuf[3];
297 obuf[0] = 0xaa; 310 obuf[0] = 0xaa;
298 obuf[1] = msg[0].len; 311 obuf[1] = msg[0].len;
299 obuf[2] = msg[0].buf[0]; 312 obuf[2] = msg[0].buf[0];
@@ -360,6 +373,69 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
360 return num; 373 return num;
361} 374}
362 375
376static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
377 int num)
378{
379 struct dvb_usb_device *d = i2c_get_adapdata(adap);
380 int ret = 0, i;
381
382 if (!d)
383 return -ENODEV;
384 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
385 return -EAGAIN;
386
387 switch (num) {
388 case 2: {
389 /* read */
390 /* first write first register number */
391 u8 ibuf[msg[1].len + 2], obuf[3];
392 obuf[0] = msg[0].addr << 1;
393 obuf[1] = msg[0].len;
394 obuf[2] = msg[0].buf[0];
395 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
396 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
397 /* second read registers */
398 ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
399 ibuf, msg[1].len + 2, DW210X_READ_MSG);
400 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
401
402 break;
403 }
404 case 1:
405 switch (msg[0].addr) {
406 case 0x60:
407 case 0x0c: {
408 /* write to register */
409 u8 obuf[msg[0].len + 2];
410 obuf[0] = msg[0].addr << 1;
411 obuf[1] = msg[0].len;
412 memcpy(obuf + 2, msg[0].buf, msg[0].len);
413 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
414 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
415 break;
416 }
417 case(DW2102_RC_QUERY): {
418 u8 ibuf[2];
419 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
420 ibuf, 2, DW210X_READ_MSG);
421 memcpy(msg[0].buf, ibuf , 2);
422 break;
423 }
424 }
425
426 break;
427 }
428
429 for (i = 0; i < num; i++) {
430 deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
431 msg[i].flags == 0 ? ">>>" : "<<<");
432 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
433 }
434
435 mutex_unlock(&d->i2c_mutex);
436 return num;
437}
438
363static u32 dw210x_i2c_func(struct i2c_adapter *adapter) 439static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
364{ 440{
365 return I2C_FUNC_I2C; 441 return I2C_FUNC_I2C;
@@ -385,6 +461,11 @@ static struct i2c_algorithm dw2104_i2c_algo = {
385 .functionality = dw210x_i2c_func, 461 .functionality = dw210x_i2c_func,
386}; 462};
387 463
464static struct i2c_algorithm dw3101_i2c_algo = {
465 .master_xfer = dw3101_i2c_transfer,
466 .functionality = dw210x_i2c_func,
467};
468
388static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 469static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
389{ 470{
390 int i; 471 int i;
@@ -404,6 +485,7 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
404 debug_dump(eepromline, 16, deb_xfer); 485 debug_dump(eepromline, 16, deb_xfer);
405 } 486 }
406 } 487 }
488
407 memcpy(mac, eeprom + 8, 6); 489 memcpy(mac, eeprom + 8, 6);
408 return 0; 490 return 0;
409}; 491};
@@ -448,6 +530,11 @@ static struct si21xx_config serit_sp1511lhb_config = {
448 530
449}; 531};
450 532
533static struct tda10023_config dw3101_tda10023_config = {
534 .demod_address = 0x0c,
535 .invert = 1,
536};
537
451static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 538static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
452{ 539{
453 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, 540 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
@@ -460,6 +547,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
460} 547}
461 548
462static struct dvb_usb_device_properties dw2102_properties; 549static struct dvb_usb_device_properties dw2102_properties;
550static struct dvb_usb_device_properties dw2104_properties;
463 551
464static int dw2102_frontend_attach(struct dvb_usb_adapter *d) 552static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
465{ 553{
@@ -497,6 +585,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
497 return -EIO; 585 return -EIO;
498} 586}
499 587
588static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
589{
590 d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
591 &d->dev->i2c_adap, 0x48);
592 if (d->fe != NULL) {
593 info("Attached tda10023!\n");
594 return 0;
595 }
596 return -EIO;
597}
598
500static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 599static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
501{ 600{
502 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 601 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -512,6 +611,14 @@ static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
512 return 0; 611 return 0;
513} 612}
514 613
614static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
615{
616 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
617 &adap->dev->i2c_adap, DVB_PLL_TUA6034);
618
619 return 0;
620}
621
515static struct dvb_usb_rc_key dw210x_rc_keys[] = { 622static struct dvb_usb_rc_key dw210x_rc_keys[] = {
516 { 0xf8, 0x0a, KEY_Q }, /*power*/ 623 { 0xf8, 0x0a, KEY_Q }, /*power*/
517 { 0xf8, 0x0c, KEY_M }, /*mute*/ 624 { 0xf8, 0x0c, KEY_M }, /*mute*/
@@ -544,44 +651,147 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = {
544 { 0xf8, 0x40, KEY_F }, /*full*/ 651 { 0xf8, 0x40, KEY_F }, /*full*/
545 { 0xf8, 0x1e, KEY_W }, /*tvmode*/ 652 { 0xf8, 0x1e, KEY_W }, /*tvmode*/
546 { 0xf8, 0x1b, KEY_B }, /*recall*/ 653 { 0xf8, 0x1b, KEY_B }, /*recall*/
654};
547 655
656static struct dvb_usb_rc_key tevii_rc_keys[] = {
657 { 0xf8, 0x0a, KEY_POWER },
658 { 0xf8, 0x0c, KEY_MUTE },
659 { 0xf8, 0x11, KEY_1 },
660 { 0xf8, 0x12, KEY_2 },
661 { 0xf8, 0x13, KEY_3 },
662 { 0xf8, 0x14, KEY_4 },
663 { 0xf8, 0x15, KEY_5 },
664 { 0xf8, 0x16, KEY_6 },
665 { 0xf8, 0x17, KEY_7 },
666 { 0xf8, 0x18, KEY_8 },
667 { 0xf8, 0x19, KEY_9 },
668 { 0xf8, 0x10, KEY_0 },
669 { 0xf8, 0x1c, KEY_MENU },
670 { 0xf8, 0x0f, KEY_VOLUMEDOWN },
671 { 0xf8, 0x1a, KEY_LAST },
672 { 0xf8, 0x0e, KEY_OPEN },
673 { 0xf8, 0x04, KEY_RECORD },
674 { 0xf8, 0x09, KEY_VOLUMEUP },
675 { 0xf8, 0x08, KEY_CHANNELUP },
676 { 0xf8, 0x07, KEY_PVR },
677 { 0xf8, 0x0b, KEY_TIME },
678 { 0xf8, 0x02, KEY_RIGHT },
679 { 0xf8, 0x03, KEY_LEFT },
680 { 0xf8, 0x00, KEY_UP },
681 { 0xf8, 0x1f, KEY_OK },
682 { 0xf8, 0x01, KEY_DOWN },
683 { 0xf8, 0x05, KEY_TUNER },
684 { 0xf8, 0x06, KEY_CHANNELDOWN },
685 { 0xf8, 0x40, KEY_PLAYPAUSE },
686 { 0xf8, 0x1e, KEY_REWIND },
687 { 0xf8, 0x1b, KEY_FAVORITES },
688 { 0xf8, 0x1d, KEY_BACK },
689 { 0xf8, 0x4d, KEY_FASTFORWARD },
690 { 0xf8, 0x44, KEY_EPG },
691 { 0xf8, 0x4c, KEY_INFO },
692 { 0xf8, 0x41, KEY_AB },
693 { 0xf8, 0x43, KEY_AUDIO },
694 { 0xf8, 0x45, KEY_SUBTITLE },
695 { 0xf8, 0x4a, KEY_LIST },
696 { 0xf8, 0x46, KEY_F1 },
697 { 0xf8, 0x47, KEY_F2 },
698 { 0xf8, 0x5e, KEY_F3 },
699 { 0xf8, 0x5c, KEY_F4 },
700 { 0xf8, 0x52, KEY_F5 },
701 { 0xf8, 0x5a, KEY_F6 },
702 { 0xf8, 0x56, KEY_MODE },
703 { 0xf8, 0x58, KEY_SWITCHVIDEOMODE },
548}; 704};
549 705
706static struct dvb_usb_rc_key tbs_rc_keys[] = {
707 { 0xf8, 0x84, KEY_POWER },
708 { 0xf8, 0x94, KEY_MUTE },
709 { 0xf8, 0x87, KEY_1 },
710 { 0xf8, 0x86, KEY_2 },
711 { 0xf8, 0x85, KEY_3 },
712 { 0xf8, 0x8b, KEY_4 },
713 { 0xf8, 0x8a, KEY_5 },
714 { 0xf8, 0x89, KEY_6 },
715 { 0xf8, 0x8f, KEY_7 },
716 { 0xf8, 0x8e, KEY_8 },
717 { 0xf8, 0x8d, KEY_9 },
718 { 0xf8, 0x92, KEY_0 },
719 { 0xf8, 0x96, KEY_CHANNELUP },
720 { 0xf8, 0x91, KEY_CHANNELDOWN },
721 { 0xf8, 0x93, KEY_VOLUMEUP },
722 { 0xf8, 0x8c, KEY_VOLUMEDOWN },
723 { 0xf8, 0x83, KEY_RECORD },
724 { 0xf8, 0x98, KEY_PAUSE },
725 { 0xf8, 0x99, KEY_OK },
726 { 0xf8, 0x9a, KEY_SHUFFLE },
727 { 0xf8, 0x81, KEY_UP },
728 { 0xf8, 0x90, KEY_LEFT },
729 { 0xf8, 0x82, KEY_RIGHT },
730 { 0xf8, 0x88, KEY_DOWN },
731 { 0xf8, 0x95, KEY_FAVORITES },
732 { 0xf8, 0x97, KEY_SUBTITLE },
733 { 0xf8, 0x9d, KEY_ZOOM },
734 { 0xf8, 0x9f, KEY_EXIT },
735 { 0xf8, 0x9e, KEY_MENU },
736 { 0xf8, 0x9c, KEY_EPG },
737 { 0xf8, 0x80, KEY_PREVIOUS },
738 { 0xf8, 0x9b, KEY_MODE }
739};
550 740
741static struct dvb_usb_rc_keys_table keys_tables[] = {
742 { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) },
743 { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) },
744 { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) },
745};
551 746
552static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 747static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
553{ 748{
554 struct dw210x_state *st = d->priv; 749 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
750 int keymap_size = d->props.rc_key_map_size;
555 u8 key[2]; 751 u8 key[2];
556 struct i2c_msg msg[] = { 752 struct i2c_msg msg = {
557 {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, 753 .addr = DW2102_RC_QUERY,
558 .len = 2}, 754 .flags = I2C_M_RD,
755 .buf = key,
756 .len = 2
559 }; 757 };
560 int i; 758 int i;
759 /* override keymap */
760 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
761 keymap = keys_tables[ir_keymap - 1].rc_keys ;
762 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
763 }
561 764
562 *state = REMOTE_NO_KEY_PRESSED; 765 *state = REMOTE_NO_KEY_PRESSED;
563 if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { 766 if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) {
564 for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { 767 for (i = 0; i < keymap_size ; i++) {
565 if (dw210x_rc_keys[i].data == msg[0].buf[0]) { 768 if (keymap[i].data == msg.buf[0]) {
566 *state = REMOTE_KEY_PRESSED; 769 *state = REMOTE_KEY_PRESSED;
567 *event = dw210x_rc_keys[i].event; 770 *event = keymap[i].event;
568 st->last_key_pressed =
569 dw210x_rc_keys[i].event;
570 break; 771 break;
571 } 772 }
572 st->last_key_pressed = 0; 773
573 } 774 }
775
776 if ((*state) == REMOTE_KEY_PRESSED)
777 deb_rc("%s: found rc key: %x, %x, event: %x\n",
778 __func__, key[0], key[1], (*event));
779 else if (key[0] != 0xff)
780 deb_rc("%s: unknown rc key: %x, %x\n",
781 __func__, key[0], key[1]);
782
574 } 783 }
575 /* info("key: %x %x\n",key[0],key[1]); */ 784
576 return 0; 785 return 0;
577} 786}
578 787
579static struct usb_device_id dw2102_table[] = { 788static struct usb_device_id dw2102_table[] = {
580 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, 789 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
581 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, 790 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
582 {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, 791 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
583 {USB_DEVICE(0x9022, 0xd650)}, 792 {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
584 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, 793 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
794 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
585 { } 795 { }
586}; 796};
587 797
@@ -642,11 +852,16 @@ static int dw2102_load_firmware(struct usb_device *dev,
642 } 852 }
643 /* init registers */ 853 /* init registers */
644 switch (dev->descriptor.idProduct) { 854 switch (dev->descriptor.idProduct) {
855 case USB_PID_TEVII_S650:
856 dw2104_properties.rc_key_map = tevii_rc_keys;
857 dw2104_properties.rc_key_map_size =
858 ARRAY_SIZE(tevii_rc_keys);
645 case USB_PID_DW2104: 859 case USB_PID_DW2104:
646 case 0xd650:
647 reset = 1; 860 reset = 1;
648 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, 861 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
649 DW210X_WRITE_MSG); 862 DW210X_WRITE_MSG);
863 /* break omitted intentionally */
864 case USB_PID_DW3101:
650 reset = 0; 865 reset = 0;
651 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 866 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
652 DW210X_WRITE_MSG); 867 DW210X_WRITE_MSG);
@@ -690,6 +905,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
690 DW210X_READ_MSG); 905 DW210X_READ_MSG);
691 break; 906 break;
692 } 907 }
908
693 msleep(100); 909 msleep(100);
694 kfree(p); 910 kfree(p);
695 } 911 }
@@ -700,7 +916,6 @@ static struct dvb_usb_device_properties dw2102_properties = {
700 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 916 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
701 .usb_ctrl = DEVICE_SPECIFIC, 917 .usb_ctrl = DEVICE_SPECIFIC,
702 .firmware = "dvb-usb-dw2102.fw", 918 .firmware = "dvb-usb-dw2102.fw",
703 .size_of_priv = sizeof(struct dw210x_state),
704 .no_reconnect = 1, 919 .no_reconnect = 1,
705 920
706 .i2c_algo = &dw2102_serit_i2c_algo, 921 .i2c_algo = &dw2102_serit_i2c_algo,
@@ -714,7 +929,7 @@ static struct dvb_usb_device_properties dw2102_properties = {
714 .num_adapters = 1, 929 .num_adapters = 1,
715 .download_firmware = dw2102_load_firmware, 930 .download_firmware = dw2102_load_firmware,
716 .read_mac_address = dw210x_read_mac_address, 931 .read_mac_address = dw210x_read_mac_address,
717 .adapter = { 932 .adapter = {
718 { 933 {
719 .frontend_attach = dw2102_frontend_attach, 934 .frontend_attach = dw2102_frontend_attach,
720 .streaming_ctrl = NULL, 935 .streaming_ctrl = NULL,
@@ -752,7 +967,6 @@ static struct dvb_usb_device_properties dw2104_properties = {
752 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 967 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
753 .usb_ctrl = DEVICE_SPECIFIC, 968 .usb_ctrl = DEVICE_SPECIFIC,
754 .firmware = "dvb-usb-dw2104.fw", 969 .firmware = "dvb-usb-dw2104.fw",
755 .size_of_priv = sizeof(struct dw210x_state),
756 .no_reconnect = 1, 970 .no_reconnect = 1,
757 971
758 .i2c_algo = &dw2104_i2c_algo, 972 .i2c_algo = &dw2104_i2c_algo,
@@ -796,12 +1010,57 @@ static struct dvb_usb_device_properties dw2104_properties = {
796 } 1010 }
797}; 1011};
798 1012
1013static struct dvb_usb_device_properties dw3101_properties = {
1014 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1015 .usb_ctrl = DEVICE_SPECIFIC,
1016 .firmware = "dvb-usb-dw3101.fw",
1017 .no_reconnect = 1,
1018
1019 .i2c_algo = &dw3101_i2c_algo,
1020 .rc_key_map = dw210x_rc_keys,
1021 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
1022 .rc_interval = 150,
1023 .rc_query = dw2102_rc_query,
1024
1025 .generic_bulk_ctrl_endpoint = 0x81,
1026 /* parameter for the MPEG2-data transfer */
1027 .num_adapters = 1,
1028 .download_firmware = dw2102_load_firmware,
1029 .read_mac_address = dw210x_read_mac_address,
1030 .adapter = {
1031 {
1032 .frontend_attach = dw3101_frontend_attach,
1033 .streaming_ctrl = NULL,
1034 .tuner_attach = dw3101_tuner_attach,
1035 .stream = {
1036 .type = USB_BULK,
1037 .count = 8,
1038 .endpoint = 0x82,
1039 .u = {
1040 .bulk = {
1041 .buffersize = 4096,
1042 }
1043 }
1044 },
1045 }
1046 },
1047 .num_device_descs = 1,
1048 .devices = {
1049 { "DVBWorld DVB-C 3101 USB2.0",
1050 {&dw2102_table[5], NULL},
1051 {NULL},
1052 },
1053 }
1054};
1055
799static int dw2102_probe(struct usb_interface *intf, 1056static int dw2102_probe(struct usb_interface *intf,
800 const struct usb_device_id *id) 1057 const struct usb_device_id *id)
801{ 1058{
802 if (0 == dvb_usb_device_init(intf, &dw2102_properties, 1059 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
803 THIS_MODULE, NULL, adapter_nr) || 1060 THIS_MODULE, NULL, adapter_nr) ||
804 0 == dvb_usb_device_init(intf, &dw2104_properties, 1061 0 == dvb_usb_device_init(intf, &dw2104_properties,
1062 THIS_MODULE, NULL, adapter_nr) ||
1063 0 == dvb_usb_device_init(intf, &dw3101_properties,
805 THIS_MODULE, NULL, adapter_nr)) { 1064 THIS_MODULE, NULL, adapter_nr)) {
806 return 0; 1065 return 0;
807 } 1066 }
@@ -833,6 +1092,8 @@ module_init(dw2102_module_init);
833module_exit(dw2102_module_exit); 1092module_exit(dw2102_module_exit);
834 1093
835MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1094MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
836MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); 1095MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1096 " DVB-C 3101 USB2.0,"
1097 " TeVii S600, S650 USB2.0 devices");
837MODULE_VERSION("0.1"); 1098MODULE_VERSION("0.1");
838MODULE_LICENSE("GPL"); 1099MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
index e3370734e95a..5cd0b0eb6ce1 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.h
+++ b/drivers/media/dvb/dvb-usb/dw2102.h
@@ -5,4 +5,5 @@
5#include "dvb-usb.h" 5#include "dvb-usb.h"
6 6
7#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) 7#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
8#define deb_rc(args...) dprintk(dvb_usb_dw2102_debug, 0x04, args)
8#endif 9#endif
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index 3dd6843864ed..afb444db43ad 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -223,7 +223,7 @@ static struct usb_device_id gp8psk_usb_table [] = {
223 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, 223 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
224 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, 224 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
225 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, 225 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
226 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, 226/* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
227 { 0 }, 227 { 0 },
228}; 228};
229MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); 229MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
@@ -254,7 +254,7 @@ static struct dvb_usb_device_properties gp8psk_properties = {
254 254
255 .generic_bulk_ctrl_endpoint = 0x01, 255 .generic_bulk_ctrl_endpoint = 0x01,
256 256
257 .num_device_descs = 4, 257 .num_device_descs = 3,
258 .devices = { 258 .devices = {
259 { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", 259 { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
260 .cold_ids = { &gp8psk_usb_table[0], NULL }, 260 .cold_ids = { &gp8psk_usb_table[0], NULL },
@@ -268,10 +268,6 @@ static struct dvb_usb_device_properties gp8psk_properties = {
268 .cold_ids = { NULL }, 268 .cold_ids = { NULL },
269 .warm_ids = { &gp8psk_usb_table[3], NULL }, 269 .warm_ids = { &gp8psk_usb_table[3], NULL },
270 }, 270 },
271 { .name = "Genpix SkyWalker-CW3K DVB-S receiver",
272 .cold_ids = { NULL },
273 .warm_ids = { &gp8psk_usb_table[4], NULL },
274 },
275 { NULL }, 271 { NULL },
276 } 272 }
277}; 273};
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
index 46a6324d7b73..27bca2e283df 100644
--- a/drivers/media/dvb/firewire/firedtv-rc.c
+++ b/drivers/media/dvb/firewire/firedtv-rc.c
@@ -18,7 +18,7 @@
18#include "firedtv.h" 18#include "firedtv.h"
19 19
20/* fixed table with older keycodes, geared towards MythTV */ 20/* fixed table with older keycodes, geared towards MythTV */
21const static u16 oldtable[] = { 21static const u16 oldtable[] = {
22 22
23 /* code from device: 0x4501...0x451f */ 23 /* code from device: 0x4501...0x451f */
24 24
@@ -62,7 +62,7 @@ const static u16 oldtable[] = {
62}; 62};
63 63
64/* user-modifiable table for a remote as sold in 2008 */ 64/* user-modifiable table for a remote as sold in 2008 */
65const static u16 keytable[] = { 65static const u16 keytable[] = {
66 66
67 /* code from device: 0x0300...0x031f */ 67 /* code from device: 0x0300...0x031f */
68 68
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 23e4cffeba38..be967ac09a39 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -35,6 +35,21 @@ config DVB_STB6100
35 A Silicon tuner from ST used in conjunction with the STB0899 35 A Silicon tuner from ST used in conjunction with the STB0899
36 demodulator. Say Y when you want to support this tuner. 36 demodulator. Say Y when you want to support this tuner.
37 37
38config DVB_STV090x
39 tristate "STV0900/STV0903(A/B) based"
40 depends on DVB_CORE && I2C
41 default m if DVB_FE_CUSTOMISE
42 help
43 DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
44 Say Y when you want to support these frontends.
45
46config DVB_STV6110x
47 tristate "STV6110/(A) based tuners"
48 depends on DVB_CORE && I2C
49 default m if DVB_FE_CUSTOMISE
50 help
51 A Silicon tuner that supports DVB-S and DVB-S2 modes
52
38comment "DVB-S (satellite) frontends" 53comment "DVB-S (satellite) frontends"
39 depends on DVB_CORE 54 depends on DVB_CORE
40 55
@@ -506,6 +521,13 @@ config DVB_ISL6421
506 help 521 help
507 An SEC control chip. 522 An SEC control chip.
508 523
524config DVB_ISL6423
525 tristate "ISL6423 SEC controller"
526 depends on DVB_CORE && I2C
527 default m if DVB_FE_CUSTOMISE
528 help
529 A SEC controller chip from Intersil
530
509config DVB_LGS8GL5 531config DVB_LGS8GL5
510 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" 532 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
511 depends on DVB_CORE && I2C 533 depends on DVB_CORE && I2C
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index bc2b00abd106..832473c1e512 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -71,4 +71,6 @@ obj-$(CONFIG_DVB_STB6000) += stb6000.o
71obj-$(CONFIG_DVB_S921) += s921.o 71obj-$(CONFIG_DVB_S921) += s921.o
72obj-$(CONFIG_DVB_STV6110) += stv6110.o 72obj-$(CONFIG_DVB_STV6110) += stv6110.o
73obj-$(CONFIG_DVB_STV0900) += stv0900.o 73obj-$(CONFIG_DVB_STV0900) += stv0900.o
74 74obj-$(CONFIG_DVB_STV090x) += stv090x.o
75obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
76obj-$(CONFIG_DVB_ISL6423) += isl6423.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index b2b50fb4cfd3..136c5863d81b 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -1455,7 +1455,7 @@ static int af9013_download_firmware(struct af9013_state *state)
1455 af9013_ops.info.name); 1455 af9013_ops.info.name);
1456 1456
1457 /* request the firmware, this will block and timeout */ 1457 /* request the firmware, this will block and timeout */
1458 ret = request_firmware(&fw, fw_file, &state->i2c->dev); 1458 ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
1459 if (ret) { 1459 if (ret) {
1460 err("did not find the firmware file. (%s) " 1460 err("did not find the firmware file. (%s) "
1461 "Please see linux/Documentation/dvb/ for more details" \ 1461 "Please see linux/Documentation/dvb/ for more details" \
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index 35731258bb0a..956b80f4979c 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -367,11 +367,90 @@ static struct {
367 { 0x8231, 0x13 }, 367 { 0x8231, 0x13 },
368}; 368};
369 369
370/* QAM Modulation table */ 370/* QAM64 Modulation table */
371static struct { 371static struct {
372 u16 reg; 372 u16 reg;
373 u16 data; 373 u16 data;
374} QAM_mod_tab[] = { 374} QAM64_mod_tab[] = {
375 { 0x00a3, 0x09 },
376 { 0x00a4, 0x00 },
377 { 0x0081, 0xc4 },
378 { 0x00a5, 0x40 },
379 { 0x00aa, 0x77 },
380 { 0x00ad, 0x77 },
381 { 0x00a6, 0x67 },
382 { 0x0262, 0x20 },
383 { 0x021c, 0x30 },
384 { 0x00b8, 0x3e },
385 { 0x00b9, 0xf0 },
386 { 0x00ba, 0x01 },
387 { 0x00bb, 0x18 },
388 { 0x00bc, 0x50 },
389 { 0x00bd, 0x00 },
390 { 0x00be, 0xea },
391 { 0x00bf, 0xef },
392 { 0x00c0, 0xfc },
393 { 0x00c1, 0xbd },
394 { 0x00c2, 0x1f },
395 { 0x00c3, 0xfc },
396 { 0x00c4, 0xdd },
397 { 0x00c5, 0xaf },
398 { 0x00c6, 0x00 },
399 { 0x00c7, 0x38 },
400 { 0x00c8, 0x30 },
401 { 0x00c9, 0x05 },
402 { 0x00ca, 0x4a },
403 { 0x00cb, 0xd0 },
404 { 0x00cc, 0x01 },
405 { 0x00cd, 0xd9 },
406 { 0x00ce, 0x6f },
407 { 0x00cf, 0xf9 },
408 { 0x00d0, 0x70 },
409 { 0x00d1, 0xdf },
410 { 0x00d2, 0xf7 },
411 { 0x00d3, 0xc2 },
412 { 0x00d4, 0xdf },
413 { 0x00d5, 0x02 },
414 { 0x00d6, 0x9a },
415 { 0x00d7, 0xd0 },
416 { 0x0250, 0x0d },
417 { 0x0251, 0xcd },
418 { 0x0252, 0xe0 },
419 { 0x0253, 0x05 },
420 { 0x0254, 0xa7 },
421 { 0x0255, 0xff },
422 { 0x0256, 0xed },
423 { 0x0257, 0x5b },
424 { 0x0258, 0xae },
425 { 0x0259, 0xe6 },
426 { 0x025a, 0x3d },
427 { 0x025b, 0x0f },
428 { 0x025c, 0x0d },
429 { 0x025d, 0xea },
430 { 0x025e, 0xf2 },
431 { 0x025f, 0x51 },
432 { 0x0260, 0xf5 },
433 { 0x0261, 0x06 },
434 { 0x021a, 0x00 },
435 { 0x0546, 0x40 },
436 { 0x0210, 0xc7 },
437 { 0x0211, 0xaa },
438 { 0x0212, 0xab },
439 { 0x0213, 0x02 },
440 { 0x0502, 0x00 },
441 { 0x0121, 0x04 },
442 { 0x0122, 0x04 },
443 { 0x052e, 0x10 },
444 { 0x00a4, 0xca },
445 { 0x00a7, 0x40 },
446 { 0x0526, 0x01 },
447};
448
449/* QAM256 Modulation table */
450static struct {
451 u16 reg;
452 u16 data;
453} QAM256_mod_tab[] = {
375 { 0x80a3, 0x09 }, 454 { 0x80a3, 0x09 },
376 { 0x80a4, 0x00 }, 455 { 0x80a4, 0x00 },
377 { 0x8081, 0xc4 }, 456 { 0x8081, 0xc4 },
@@ -464,12 +543,19 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
464 au8522_set_if(fe, state->config->vsb_if); 543 au8522_set_if(fe, state->config->vsb_if);
465 break; 544 break;
466 case QAM_64: 545 case QAM_64:
546 dprintk("%s() QAM 64\n", __func__);
547 for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++)
548 au8522_writereg(state,
549 QAM64_mod_tab[i].reg,
550 QAM64_mod_tab[i].data);
551 au8522_set_if(fe, state->config->qam_if);
552 break;
467 case QAM_256: 553 case QAM_256:
468 dprintk("%s() QAM 64/256\n", __func__); 554 dprintk("%s() QAM 256\n", __func__);
469 for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) 555 for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++)
470 au8522_writereg(state, 556 au8522_writereg(state,
471 QAM_mod_tab[i].reg, 557 QAM256_mod_tab[i].reg,
472 QAM_mod_tab[i].data); 558 QAM256_mod_tab[i].data);
473 au8522_set_if(fe, state->config->qam_if); 559 au8522_set_if(fe, state->config->qam_if);
474 break; 560 break;
475 default: 561 default:
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 9b9f57264cef..2410d8b59b6b 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -492,7 +492,7 @@ static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
492 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", 492 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
493 __func__, CX24116_DEFAULT_FIRMWARE); 493 __func__, CX24116_DEFAULT_FIRMWARE);
494 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, 494 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
495 &state->i2c->dev); 495 state->i2c->dev.parent);
496 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", 496 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
497 __func__); 497 __func__);
498 if (ret) { 498 if (ret) {
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 172f1f928f02..010075535221 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -123,10 +123,10 @@ static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix)
123 } 123 }
124 memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); 124 memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
125 125
126 if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) { 126 rc = request_firmware(&fw[ix].file, fw[ix].name, s->i2c->dev.parent);
127 if (rc != 0) {
127 printk(KERN_ERR "%s: Firmware \"%s\" not available\n", 128 printk(KERN_ERR "%s: Firmware \"%s\" not available\n",
128 mod_name, fw[ix].name); 129 mod_name, fw[ix].name);
129 rc = -ENOENT;
130 goto exit_err; 130 goto exit_err;
131 } 131 }
132 132
diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c
new file mode 100644
index 000000000000..dca5bebfeeb5
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6423.c
@@ -0,0 +1,308 @@
1/*
2 Intersil ISL6423 SEC and LNB Power supply controller
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28
29#include "dvb_frontend.h"
30#include "isl6423.h"
31
32static unsigned int verbose;
33module_param(verbose, int, 0644);
34MODULE_PARM_DESC(verbose, "Set Verbosity level");
35
36#define FE_ERROR 0
37#define FE_NOTICE 1
38#define FE_INFO 2
39#define FE_DEBUG 3
40#define FE_DEBUGREG 4
41
42#define dprintk(__y, __z, format, arg...) do { \
43 if (__z) { \
44 if ((verbose > FE_ERROR) && (verbose > __y)) \
45 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
46 else if ((verbose > FE_NOTICE) && (verbose > __y)) \
47 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
48 else if ((verbose > FE_INFO) && (verbose > __y)) \
49 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
50 else if ((verbose > FE_DEBUG) && (verbose > __y)) \
51 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
52 } else { \
53 if (verbose > __y) \
54 printk(format, ##arg); \
55 } \
56} while (0)
57
58struct isl6423_dev {
59 const struct isl6423_config *config;
60 struct i2c_adapter *i2c;
61
62 u8 reg_3;
63 u8 reg_4;
64
65 unsigned int verbose;
66};
67
68static int isl6423_write(struct isl6423_dev *isl6423, u8 reg)
69{
70 struct i2c_adapter *i2c = isl6423->i2c;
71 u8 addr = isl6423->config->addr;
72 int err = 0;
73
74 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = &reg, .len = 1 };
75
76 dprintk(FE_DEBUG, 1, "write reg %02X", reg);
77 err = i2c_transfer(i2c, &msg, 1);
78 if (err < 0)
79 goto exit;
80 return 0;
81
82exit:
83 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
84 return err;
85}
86
87static int isl6423_set_modulation(struct dvb_frontend *fe)
88{
89 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
90 const struct isl6423_config *config = isl6423->config;
91 int err = 0;
92 u8 reg_2 = 0;
93
94 reg_2 = 0x01 << 5;
95
96 if (config->mod_extern)
97 reg_2 |= (1 << 3);
98 else
99 reg_2 |= (1 << 4);
100
101 err = isl6423_write(isl6423, reg_2);
102 if (err < 0)
103 goto exit;
104 return 0;
105
106exit:
107 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
108 return err;
109}
110
111static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg)
112{
113 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
114 u8 reg_3 = isl6423->reg_3;
115 u8 reg_4 = isl6423->reg_4;
116 int err = 0;
117
118 if (arg) {
119 /* EN = 1, VSPEN = 1, VBOT = 1 */
120 reg_4 |= (1 << 4);
121 reg_4 |= 0x1;
122 reg_3 |= (1 << 3);
123 } else {
124 /* EN = 1, VSPEN = 1, VBOT = 0 */
125 reg_4 |= (1 << 4);
126 reg_4 &= ~0x1;
127 reg_3 |= (1 << 3);
128 }
129 err = isl6423_write(isl6423, reg_3);
130 if (err < 0)
131 goto exit;
132
133 err = isl6423_write(isl6423, reg_4);
134 if (err < 0)
135 goto exit;
136
137 isl6423->reg_3 = reg_3;
138 isl6423->reg_4 = reg_4;
139
140 return 0;
141exit:
142 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
143 return err;
144}
145
146
147static int isl6423_set_voltage(struct dvb_frontend *fe,
148 enum fe_sec_voltage voltage)
149{
150 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
151 u8 reg_3 = isl6423->reg_3;
152 u8 reg_4 = isl6423->reg_4;
153 int err = 0;
154
155 switch (voltage) {
156 case SEC_VOLTAGE_OFF:
157 /* EN = 0 */
158 reg_4 &= ~(1 << 4);
159 break;
160
161 case SEC_VOLTAGE_13:
162 /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */
163 reg_4 |= (1 << 4);
164 reg_4 &= ~0x3;
165 reg_3 |= (1 << 3);
166 break;
167
168 case SEC_VOLTAGE_18:
169 /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */
170 reg_4 |= (1 << 4);
171 reg_4 |= 0x2;
172 reg_4 &= ~0x1;
173 reg_3 |= (1 << 3);
174 break;
175
176 default:
177 break;
178 }
179 err = isl6423_write(isl6423, reg_3);
180 if (err < 0)
181 goto exit;
182
183 err = isl6423_write(isl6423, reg_4);
184 if (err < 0)
185 goto exit;
186
187 isl6423->reg_3 = reg_3;
188 isl6423->reg_4 = reg_4;
189
190 return 0;
191exit:
192 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
193 return err;
194}
195
196static int isl6423_set_current(struct dvb_frontend *fe)
197{
198 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
199 u8 reg_3 = isl6423->reg_3;
200 const struct isl6423_config *config = isl6423->config;
201 int err = 0;
202
203 switch (config->current_max) {
204 case SEC_CURRENT_275m:
205 /* 275mA */
206 /* ISELH = 0, ISELL = 0 */
207 reg_3 &= ~0x3;
208 break;
209
210 case SEC_CURRENT_515m:
211 /* 515mA */
212 /* ISELH = 0, ISELL = 1 */
213 reg_3 &= ~0x2;
214 reg_3 |= 0x1;
215 break;
216
217 case SEC_CURRENT_635m:
218 /* 635mA */
219 /* ISELH = 1, ISELL = 0 */
220 reg_3 &= ~0x1;
221 reg_3 |= 0x2;
222 break;
223
224 case SEC_CURRENT_800m:
225 /* 800mA */
226 /* ISELH = 1, ISELL = 1 */
227 reg_3 |= 0x3;
228 break;
229 }
230
231 err = isl6423_write(isl6423, reg_3);
232 if (err < 0)
233 goto exit;
234
235 switch (config->curlim) {
236 case SEC_CURRENT_LIM_ON:
237 /* DCL = 0 */
238 reg_3 &= ~0x10;
239 break;
240
241 case SEC_CURRENT_LIM_OFF:
242 /* DCL = 1 */
243 reg_3 |= 0x10;
244 break;
245 }
246
247 err = isl6423_write(isl6423, reg_3);
248 if (err < 0)
249 goto exit;
250
251 isl6423->reg_3 = reg_3;
252
253 return 0;
254exit:
255 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
256 return err;
257}
258
259static void isl6423_release(struct dvb_frontend *fe)
260{
261 isl6423_set_voltage(fe, SEC_VOLTAGE_OFF);
262
263 kfree(fe->sec_priv);
264 fe->sec_priv = NULL;
265}
266
267struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
268 struct i2c_adapter *i2c,
269 const struct isl6423_config *config)
270{
271 struct isl6423_dev *isl6423;
272
273 isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL);
274 if (!isl6423)
275 return NULL;
276
277 isl6423->config = config;
278 isl6423->i2c = i2c;
279 fe->sec_priv = isl6423;
280
281 /* SR3H = 0, SR3M = 1, SR3L = 0 */
282 isl6423->reg_3 = 0x02 << 5;
283 /* SR4H = 0, SR4M = 1, SR4L = 1 */
284 isl6423->reg_4 = 0x03 << 5;
285
286 if (isl6423_set_current(fe))
287 goto exit;
288
289 if (isl6423_set_modulation(fe))
290 goto exit;
291
292 fe->ops.release_sec = isl6423_release;
293 fe->ops.set_voltage = isl6423_set_voltage;
294 fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost;
295 isl6423->verbose = verbose;
296
297 return fe;
298
299exit:
300 kfree(isl6423);
301 fe->sec_priv = NULL;
302 return NULL;
303}
304EXPORT_SYMBOL(isl6423_attach);
305
306MODULE_DESCRIPTION("ISL6423 SEC");
307MODULE_AUTHOR("Manu Abraham");
308MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb/frontends/isl6423.h
new file mode 100644
index 000000000000..e1a37fba01ca
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6423.h
@@ -0,0 +1,63 @@
1/*
2 Intersil ISL6423 SEC and LNB Power supply controller
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef __ISL_6423_H
22#define __ISL_6423_H
23
24#include <linux/dvb/frontend.h>
25
26enum isl6423_current {
27 SEC_CURRENT_275m = 0,
28 SEC_CURRENT_515m,
29 SEC_CURRENT_635m,
30 SEC_CURRENT_800m,
31};
32
33enum isl6423_curlim {
34 SEC_CURRENT_LIM_ON = 1,
35 SEC_CURRENT_LIM_OFF
36};
37
38struct isl6423_config {
39 enum isl6423_current current_max;
40 enum isl6423_curlim curlim;
41 u8 addr;
42 u8 mod_extern;
43};
44
45#if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE))
46
47
48extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
49 struct i2c_adapter *i2c,
50 const struct isl6423_config *config);
51
52#else
53static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
54 struct i2c_adapter *i2c,
55 const struct isl6423_config *config)
56{
57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
58 return NULL;
59}
60
61#endif /* CONFIG_DVB_ISL6423 */
62
63#endif /* __ISL_6423_H */
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
index d92d0557a80b..fde8c59700fb 100644
--- a/drivers/media/dvb/frontends/lgdt3305.c
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -19,6 +19,7 @@
19 * 19 *
20 */ 20 */
21 21
22#include <asm/div64.h>
22#include <linux/dvb/frontend.h> 23#include <linux/dvb/frontend.h>
23#include "dvb_math.h" 24#include "dvb_math.h"
24#include "lgdt3305.h" 25#include "lgdt3305.h"
@@ -496,27 +497,15 @@ static int lgdt3305_set_if(struct lgdt3305_state *state,
496 497
497 nco = if_freq_khz / 10; 498 nco = if_freq_khz / 10;
498 499
499#define LGDT3305_64BIT_DIVISION_ENABLED 0
500 /* FIXME: 64bit division disabled to avoid linking error:
501 * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
502 */
503 switch (param->u.vsb.modulation) { 500 switch (param->u.vsb.modulation) {
504 case VSB_8: 501 case VSB_8:
505#if LGDT3305_64BIT_DIVISION_ENABLED
506 nco <<= 24; 502 nco <<= 24;
507 nco /= 625; 503 do_div(nco, 625);
508#else
509 nco *= ((1 << 24) / 625);
510#endif
511 break; 504 break;
512 case QAM_64: 505 case QAM_64:
513 case QAM_256: 506 case QAM_256:
514#if LGDT3305_64BIT_DIVISION_ENABLED
515 nco <<= 28; 507 nco <<= 28;
516 nco /= 625; 508 do_div(nco, 625);
517#else
518 nco *= ((1 << 28) / 625);
519#endif
520 break; 509 break;
521 default: 510 default:
522 return -EINVAL; 511 return -EINVAL;
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index f9785dfe735b..fde27645bbed 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -37,14 +37,14 @@
37 } while (0) 37 } while (0)
38 38
39static int debug; 39static int debug;
40static int fake_signal_str; 40static int fake_signal_str = 1;
41 41
42module_param(debug, int, 0644); 42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 43MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
44 44
45module_param(fake_signal_str, int, 0644); 45module_param(fake_signal_str, int, 0644);
46MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." 46MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
47"Signal strength calculation is slow.(default:off)."); 47"Signal strength calculation is slow.(default:on).");
48 48
49/* LGS8GXX internal helper functions */ 49/* LGS8GXX internal helper functions */
50 50
@@ -610,7 +610,7 @@ static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
610 else 610 else
611 cat = 0; 611 cat = 0;
612 612
613 *signal = cat; 613 *signal = cat * 65535 / 5;
614 614
615 return 0; 615 return 0;
616} 616}
@@ -630,8 +630,8 @@ static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
630 630
631 if (fake_signal_str) { 631 if (fake_signal_str) {
632 if ((t & 0xC0) == 0xC0) { 632 if ((t & 0xC0) == 0xC0) {
633 dprintk("Fake signal strength as 50\n"); 633 dprintk("Fake signal strength\n");
634 *signal = 0x32; 634 *signal = 0x7FFF;
635 } else 635 } else
636 *signal = 0; 636 *signal = 0;
637 return 0; 637 return 0;
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index 1dcc56f32bff..71f607fe8fc7 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -133,7 +133,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
133 /* override frontend ops */ 133 /* override frontend ops */
134 fe->ops.set_voltage = lnbp21_set_voltage; 134 fe->ops.set_voltage = lnbp21_set_voltage;
135 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 135 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
136 printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr); 136 printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
137 137
138 return fe; 138 return fe;
139} 139}
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 5ac9b15920f8..a621f727935f 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -77,7 +77,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
77 ret = i2c_transfer(state->i2c, msg, 2); 77 ret = i2c_transfer(state->i2c, msg, 2);
78 78
79 if (ret != 2) { 79 if (ret != 2) {
80 printk(KERN_ERR "%s: ret == %d\n", __func__, ret); 80 printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret);
81 return -EREMOTEIO; 81 return -EREMOTEIO;
82 } 82 }
83 83
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index a8429ebfa8a2..eac20650499f 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -879,7 +879,8 @@ static int nxt2002_init(struct dvb_frontend* fe)
879 879
880 /* request the firmware, this will block until someone uploads it */ 880 /* request the firmware, this will block until someone uploads it */
881 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); 881 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
882 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev); 882 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
883 state->i2c->dev.parent);
883 printk("nxt2002: Waiting for firmware upload(2)...\n"); 884 printk("nxt2002: Waiting for firmware upload(2)...\n");
884 if (ret) { 885 if (ret) {
885 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); 886 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
@@ -943,7 +944,8 @@ static int nxt2004_init(struct dvb_frontend* fe)
943 944
944 /* request the firmware, this will block until someone uploads it */ 945 /* request the firmware, this will block until someone uploads it */
945 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); 946 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
946 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev); 947 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
948 state->i2c->dev.parent);
947 printk("nxt2004: Waiting for firmware upload(2)...\n"); 949 printk("nxt2004: Waiting for firmware upload(2)...\n");
948 if (ret) { 950 if (ret) {
949 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); 951 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index 5ed32544de39..8133ea3cddd7 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -340,7 +340,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
340 } 340 }
341 printk("or51132: Waiting for firmware upload(%s)...\n", 341 printk("or51132: Waiting for firmware upload(%s)...\n",
342 fwname); 342 fwname);
343 ret = request_firmware(&fw, fwname, &state->i2c->dev); 343 ret = request_firmware(&fw, fwname, state->i2c->dev.parent);
344 if (ret) { 344 if (ret) {
345 printk(KERN_WARNING "or51132: No firmware up" 345 printk(KERN_WARNING "or51132: No firmware up"
346 "loaded(timeout or file not found?)\n"); 346 "loaded(timeout or file not found?)\n");
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
index 762d5af62d7a..67dc8ec634e2 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -60,8 +60,6 @@
60 } \ 60 } \
61 } while (0) 61 } while (0)
62 62
63#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a))
64
65static int stvdebug; 63static int stvdebug;
66 64
67#define dprintk(args...) \ 65#define dprintk(args...) \
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
new file mode 100644
index 000000000000..96ef745a2e4e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -0,0 +1,4299 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/mutex.h>
27
28#include <linux/dvb/frontend.h>
29#include "dvb_frontend.h"
30
31#include "stv6110x.h" /* for demodulator internal modes */
32
33#include "stv090x_reg.h"
34#include "stv090x.h"
35#include "stv090x_priv.h"
36
37static unsigned int verbose;
38module_param(verbose, int, 0644);
39
40struct mutex demod_lock;
41
42/* DVBS1 and DSS C/N Lookup table */
43static const struct stv090x_tab stv090x_s1cn_tab[] = {
44 { 0, 8917 }, /* 0.0dB */
45 { 5, 8801 }, /* 0.5dB */
46 { 10, 8667 }, /* 1.0dB */
47 { 15, 8522 }, /* 1.5dB */
48 { 20, 8355 }, /* 2.0dB */
49 { 25, 8175 }, /* 2.5dB */
50 { 30, 7979 }, /* 3.0dB */
51 { 35, 7763 }, /* 3.5dB */
52 { 40, 7530 }, /* 4.0dB */
53 { 45, 7282 }, /* 4.5dB */
54 { 50, 7026 }, /* 5.0dB */
55 { 55, 6781 }, /* 5.5dB */
56 { 60, 6514 }, /* 6.0dB */
57 { 65, 6241 }, /* 6.5dB */
58 { 70, 5965 }, /* 7.0dB */
59 { 75, 5690 }, /* 7.5dB */
60 { 80, 5424 }, /* 8.0dB */
61 { 85, 5161 }, /* 8.5dB */
62 { 90, 4902 }, /* 9.0dB */
63 { 95, 4654 }, /* 9.5dB */
64 { 100, 4417 }, /* 10.0dB */
65 { 105, 4186 }, /* 10.5dB */
66 { 110, 3968 }, /* 11.0dB */
67 { 115, 3757 }, /* 11.5dB */
68 { 120, 3558 }, /* 12.0dB */
69 { 125, 3366 }, /* 12.5dB */
70 { 130, 3185 }, /* 13.0dB */
71 { 135, 3012 }, /* 13.5dB */
72 { 140, 2850 }, /* 14.0dB */
73 { 145, 2698 }, /* 14.5dB */
74 { 150, 2550 }, /* 15.0dB */
75 { 160, 2283 }, /* 16.0dB */
76 { 170, 2042 }, /* 17.0dB */
77 { 180, 1827 }, /* 18.0dB */
78 { 190, 1636 }, /* 19.0dB */
79 { 200, 1466 }, /* 20.0dB */
80 { 210, 1315 }, /* 21.0dB */
81 { 220, 1181 }, /* 22.0dB */
82 { 230, 1064 }, /* 23.0dB */
83 { 240, 960 }, /* 24.0dB */
84 { 250, 869 }, /* 25.0dB */
85 { 260, 792 }, /* 26.0dB */
86 { 270, 724 }, /* 27.0dB */
87 { 280, 665 }, /* 28.0dB */
88 { 290, 616 }, /* 29.0dB */
89 { 300, 573 }, /* 30.0dB */
90 { 310, 537 }, /* 31.0dB */
91 { 320, 507 }, /* 32.0dB */
92 { 330, 483 }, /* 33.0dB */
93 { 400, 398 }, /* 40.0dB */
94 { 450, 381 }, /* 45.0dB */
95 { 500, 377 } /* 50.0dB */
96};
97
98/* DVBS2 C/N Lookup table */
99static const struct stv090x_tab stv090x_s2cn_tab[] = {
100 { -30, 13348 }, /* -3.0dB */
101 { -20, 12640 }, /* -2d.0B */
102 { -10, 11883 }, /* -1.0dB */
103 { 0, 11101 }, /* -0.0dB */
104 { 5, 10718 }, /* 0.5dB */
105 { 10, 10339 }, /* 1.0dB */
106 { 15, 9947 }, /* 1.5dB */
107 { 20, 9552 }, /* 2.0dB */
108 { 25, 9183 }, /* 2.5dB */
109 { 30, 8799 }, /* 3.0dB */
110 { 35, 8422 }, /* 3.5dB */
111 { 40, 8062 }, /* 4.0dB */
112 { 45, 7707 }, /* 4.5dB */
113 { 50, 7353 }, /* 5.0dB */
114 { 55, 7025 }, /* 5.5dB */
115 { 60, 6684 }, /* 6.0dB */
116 { 65, 6331 }, /* 6.5dB */
117 { 70, 6036 }, /* 7.0dB */
118 { 75, 5727 }, /* 7.5dB */
119 { 80, 5437 }, /* 8.0dB */
120 { 85, 5164 }, /* 8.5dB */
121 { 90, 4902 }, /* 9.0dB */
122 { 95, 4653 }, /* 9.5dB */
123 { 100, 4408 }, /* 10.0dB */
124 { 105, 4187 }, /* 10.5dB */
125 { 110, 3961 }, /* 11.0dB */
126 { 115, 3751 }, /* 11.5dB */
127 { 120, 3558 }, /* 12.0dB */
128 { 125, 3368 }, /* 12.5dB */
129 { 130, 3191 }, /* 13.0dB */
130 { 135, 3017 }, /* 13.5dB */
131 { 140, 2862 }, /* 14.0dB */
132 { 145, 2710 }, /* 14.5dB */
133 { 150, 2565 }, /* 15.0dB */
134 { 160, 2300 }, /* 16.0dB */
135 { 170, 2058 }, /* 17.0dB */
136 { 180, 1849 }, /* 18.0dB */
137 { 190, 1663 }, /* 19.0dB */
138 { 200, 1495 }, /* 20.0dB */
139 { 210, 1349 }, /* 21.0dB */
140 { 220, 1222 }, /* 22.0dB */
141 { 230, 1110 }, /* 23.0dB */
142 { 240, 1011 }, /* 24.0dB */
143 { 250, 925 }, /* 25.0dB */
144 { 260, 853 }, /* 26.0dB */
145 { 270, 789 }, /* 27.0dB */
146 { 280, 734 }, /* 28.0dB */
147 { 290, 690 }, /* 29.0dB */
148 { 300, 650 }, /* 30.0dB */
149 { 310, 619 }, /* 31.0dB */
150 { 320, 593 }, /* 32.0dB */
151 { 330, 571 }, /* 33.0dB */
152 { 400, 498 }, /* 40.0dB */
153 { 450, 484 }, /* 45.0dB */
154 { 500, 481 } /* 50.0dB */
155};
156
157/* RF level C/N lookup table */
158static const struct stv090x_tab stv090x_rf_tab[] = {
159 { -5, 0xcaa1 }, /* -5dBm */
160 { -10, 0xc229 }, /* -10dBm */
161 { -15, 0xbb08 }, /* -15dBm */
162 { -20, 0xb4bc }, /* -20dBm */
163 { -25, 0xad5a }, /* -25dBm */
164 { -30, 0xa298 }, /* -30dBm */
165 { -35, 0x98a8 }, /* -35dBm */
166 { -40, 0x8389 }, /* -40dBm */
167 { -45, 0x59be }, /* -45dBm */
168 { -50, 0x3a14 }, /* -50dBm */
169 { -55, 0x2d11 }, /* -55dBm */
170 { -60, 0x210d }, /* -60dBm */
171 { -65, 0xa14f }, /* -65dBm */
172 { -70, 0x07aa } /* -70dBm */
173};
174
175
176static struct stv090x_reg stv0900_initval[] = {
177
178 { STV090x_OUTCFG, 0x00 },
179 { STV090x_MODECFG, 0xff },
180 { STV090x_AGCRF1CFG, 0x11 },
181 { STV090x_AGCRF2CFG, 0x13 },
182 { STV090x_TSGENERAL1X, 0x14 },
183 { STV090x_TSTTNR2, 0x21 },
184 { STV090x_TSTTNR4, 0x21 },
185 { STV090x_P2_DISTXCTL, 0x22 },
186 { STV090x_P2_F22TX, 0xc0 },
187 { STV090x_P2_F22RX, 0xc0 },
188 { STV090x_P2_DISRXCTL, 0x00 },
189 { STV090x_P2_DMDCFGMD, 0xF9 },
190 { STV090x_P2_DEMOD, 0x08 },
191 { STV090x_P2_DMDCFG3, 0xc4 },
192 { STV090x_P2_CARFREQ, 0xed },
193 { STV090x_P2_LDT, 0xd0 },
194 { STV090x_P2_LDT2, 0xb8 },
195 { STV090x_P2_TMGCFG, 0xd2 },
196 { STV090x_P2_TMGTHRISE, 0x20 },
197 { STV090x_P1_TMGCFG, 0xd2 },
198
199 { STV090x_P2_TMGTHFALL, 0x00 },
200 { STV090x_P2_FECSPY, 0x88 },
201 { STV090x_P2_FSPYDATA, 0x3a },
202 { STV090x_P2_FBERCPT4, 0x00 },
203 { STV090x_P2_FSPYBER, 0x10 },
204 { STV090x_P2_ERRCTRL1, 0x35 },
205 { STV090x_P2_ERRCTRL2, 0xc1 },
206 { STV090x_P2_CFRICFG, 0xf8 },
207 { STV090x_P2_NOSCFG, 0x1c },
208 { STV090x_P2_DMDTOM, 0x20 },
209 { STV090x_P2_CORRELMANT, 0x70 },
210 { STV090x_P2_CORRELABS, 0x88 },
211 { STV090x_P2_AGC2O, 0x5b },
212 { STV090x_P2_AGC2REF, 0x38 },
213 { STV090x_P2_CARCFG, 0xe4 },
214 { STV090x_P2_ACLC, 0x1A },
215 { STV090x_P2_BCLC, 0x09 },
216 { STV090x_P2_CARHDR, 0x08 },
217 { STV090x_P2_KREFTMG, 0xc1 },
218 { STV090x_P2_SFRUPRATIO, 0xf0 },
219 { STV090x_P2_SFRLOWRATIO, 0x70 },
220 { STV090x_P2_SFRSTEP, 0x58 },
221 { STV090x_P2_TMGCFG2, 0x01 },
222 { STV090x_P2_CAR2CFG, 0x26 },
223 { STV090x_P2_BCLC2S2Q, 0x86 },
224 { STV090x_P2_BCLC2S28, 0x86 },
225 { STV090x_P2_SMAPCOEF7, 0x77 },
226 { STV090x_P2_SMAPCOEF6, 0x85 },
227 { STV090x_P2_SMAPCOEF5, 0x77 },
228 { STV090x_P2_TSCFGL, 0x20 },
229 { STV090x_P2_DMDCFG2, 0x3b },
230 { STV090x_P2_MODCODLST0, 0xff },
231 { STV090x_P2_MODCODLST1, 0xff },
232 { STV090x_P2_MODCODLST2, 0xff },
233 { STV090x_P2_MODCODLST3, 0xff },
234 { STV090x_P2_MODCODLST4, 0xff },
235 { STV090x_P2_MODCODLST5, 0xff },
236 { STV090x_P2_MODCODLST6, 0xff },
237 { STV090x_P2_MODCODLST7, 0xcc },
238 { STV090x_P2_MODCODLST8, 0xcc },
239 { STV090x_P2_MODCODLST9, 0xcc },
240 { STV090x_P2_MODCODLSTA, 0xcc },
241 { STV090x_P2_MODCODLSTB, 0xcc },
242 { STV090x_P2_MODCODLSTC, 0xcc },
243 { STV090x_P2_MODCODLSTD, 0xcc },
244 { STV090x_P2_MODCODLSTE, 0xcc },
245 { STV090x_P2_MODCODLSTF, 0xcf },
246 { STV090x_P1_DISTXCTL, 0x22 },
247 { STV090x_P1_F22TX, 0xc0 },
248 { STV090x_P1_F22RX, 0xc0 },
249 { STV090x_P1_DISRXCTL, 0x00 },
250 { STV090x_P1_DMDCFGMD, 0xf9 },
251 { STV090x_P1_DEMOD, 0x08 },
252 { STV090x_P1_DMDCFG3, 0xc4 },
253 { STV090x_P1_DMDTOM, 0x20 },
254 { STV090x_P1_CARFREQ, 0xed },
255 { STV090x_P1_LDT, 0xd0 },
256 { STV090x_P1_LDT2, 0xb8 },
257 { STV090x_P1_TMGCFG, 0xd2 },
258 { STV090x_P1_TMGTHRISE, 0x20 },
259 { STV090x_P1_TMGTHFALL, 0x00 },
260 { STV090x_P1_SFRUPRATIO, 0xf0 },
261 { STV090x_P1_SFRLOWRATIO, 0x70 },
262 { STV090x_P1_TSCFGL, 0x20 },
263 { STV090x_P1_FECSPY, 0x88 },
264 { STV090x_P1_FSPYDATA, 0x3a },
265 { STV090x_P1_FBERCPT4, 0x00 },
266 { STV090x_P1_FSPYBER, 0x10 },
267 { STV090x_P1_ERRCTRL1, 0x35 },
268 { STV090x_P1_ERRCTRL2, 0xc1 },
269 { STV090x_P1_CFRICFG, 0xf8 },
270 { STV090x_P1_NOSCFG, 0x1c },
271 { STV090x_P1_CORRELMANT, 0x70 },
272 { STV090x_P1_CORRELABS, 0x88 },
273 { STV090x_P1_AGC2O, 0x5b },
274 { STV090x_P1_AGC2REF, 0x38 },
275 { STV090x_P1_CARCFG, 0xe4 },
276 { STV090x_P1_ACLC, 0x1A },
277 { STV090x_P1_BCLC, 0x09 },
278 { STV090x_P1_CARHDR, 0x08 },
279 { STV090x_P1_KREFTMG, 0xc1 },
280 { STV090x_P1_SFRSTEP, 0x58 },
281 { STV090x_P1_TMGCFG2, 0x01 },
282 { STV090x_P1_CAR2CFG, 0x26 },
283 { STV090x_P1_BCLC2S2Q, 0x86 },
284 { STV090x_P1_BCLC2S28, 0x86 },
285 { STV090x_P1_SMAPCOEF7, 0x77 },
286 { STV090x_P1_SMAPCOEF6, 0x85 },
287 { STV090x_P1_SMAPCOEF5, 0x77 },
288 { STV090x_P1_DMDCFG2, 0x3b },
289 { STV090x_P1_MODCODLST0, 0xff },
290 { STV090x_P1_MODCODLST1, 0xff },
291 { STV090x_P1_MODCODLST2, 0xff },
292 { STV090x_P1_MODCODLST3, 0xff },
293 { STV090x_P1_MODCODLST4, 0xff },
294 { STV090x_P1_MODCODLST5, 0xff },
295 { STV090x_P1_MODCODLST6, 0xff },
296 { STV090x_P1_MODCODLST7, 0xcc },
297 { STV090x_P1_MODCODLST8, 0xcc },
298 { STV090x_P1_MODCODLST9, 0xcc },
299 { STV090x_P1_MODCODLSTA, 0xcc },
300 { STV090x_P1_MODCODLSTB, 0xcc },
301 { STV090x_P1_MODCODLSTC, 0xcc },
302 { STV090x_P1_MODCODLSTD, 0xcc },
303 { STV090x_P1_MODCODLSTE, 0xcc },
304 { STV090x_P1_MODCODLSTF, 0xcf },
305 { STV090x_GENCFG, 0x1d },
306 { STV090x_NBITER_NF4, 0x37 },
307 { STV090x_NBITER_NF5, 0x29 },
308 { STV090x_NBITER_NF6, 0x37 },
309 { STV090x_NBITER_NF7, 0x33 },
310 { STV090x_NBITER_NF8, 0x31 },
311 { STV090x_NBITER_NF9, 0x2f },
312 { STV090x_NBITER_NF10, 0x39 },
313 { STV090x_NBITER_NF11, 0x3a },
314 { STV090x_NBITER_NF12, 0x29 },
315 { STV090x_NBITER_NF13, 0x37 },
316 { STV090x_NBITER_NF14, 0x33 },
317 { STV090x_NBITER_NF15, 0x2f },
318 { STV090x_NBITER_NF16, 0x39 },
319 { STV090x_NBITER_NF17, 0x3a },
320 { STV090x_NBITERNOERR, 0x04 },
321 { STV090x_GAINLLR_NF4, 0x0C },
322 { STV090x_GAINLLR_NF5, 0x0F },
323 { STV090x_GAINLLR_NF6, 0x11 },
324 { STV090x_GAINLLR_NF7, 0x14 },
325 { STV090x_GAINLLR_NF8, 0x17 },
326 { STV090x_GAINLLR_NF9, 0x19 },
327 { STV090x_GAINLLR_NF10, 0x20 },
328 { STV090x_GAINLLR_NF11, 0x21 },
329 { STV090x_GAINLLR_NF12, 0x0D },
330 { STV090x_GAINLLR_NF13, 0x0F },
331 { STV090x_GAINLLR_NF14, 0x13 },
332 { STV090x_GAINLLR_NF15, 0x1A },
333 { STV090x_GAINLLR_NF16, 0x1F },
334 { STV090x_GAINLLR_NF17, 0x21 },
335 { STV090x_RCCFGH, 0x20 },
336 { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */
337 { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */
338 { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */
339 { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */
340};
341
342static struct stv090x_reg stv0903_initval[] = {
343 { STV090x_OUTCFG, 0x00 },
344 { STV090x_AGCRF1CFG, 0x11 },
345 { STV090x_STOPCLK1, 0x48 },
346 { STV090x_STOPCLK2, 0x14 },
347 { STV090x_TSTTNR1, 0x27 },
348 { STV090x_TSTTNR2, 0x21 },
349 { STV090x_P1_DISTXCTL, 0x22 },
350 { STV090x_P1_F22TX, 0xc0 },
351 { STV090x_P1_F22RX, 0xc0 },
352 { STV090x_P1_DISRXCTL, 0x00 },
353 { STV090x_P1_DMDCFGMD, 0xF9 },
354 { STV090x_P1_DEMOD, 0x08 },
355 { STV090x_P1_DMDCFG3, 0xc4 },
356 { STV090x_P1_CARFREQ, 0xed },
357 { STV090x_P1_TNRCFG2, 0x82 },
358 { STV090x_P1_LDT, 0xd0 },
359 { STV090x_P1_LDT2, 0xb8 },
360 { STV090x_P1_TMGCFG, 0xd2 },
361 { STV090x_P1_TMGTHRISE, 0x20 },
362 { STV090x_P1_TMGTHFALL, 0x00 },
363 { STV090x_P1_SFRUPRATIO, 0xf0 },
364 { STV090x_P1_SFRLOWRATIO, 0x70 },
365 { STV090x_P1_TSCFGL, 0x20 },
366 { STV090x_P1_FECSPY, 0x88 },
367 { STV090x_P1_FSPYDATA, 0x3a },
368 { STV090x_P1_FBERCPT4, 0x00 },
369 { STV090x_P1_FSPYBER, 0x10 },
370 { STV090x_P1_ERRCTRL1, 0x35 },
371 { STV090x_P1_ERRCTRL2, 0xc1 },
372 { STV090x_P1_CFRICFG, 0xf8 },
373 { STV090x_P1_NOSCFG, 0x1c },
374 { STV090x_P1_DMDTOM, 0x20 },
375 { STV090x_P1_CORRELMANT, 0x70 },
376 { STV090x_P1_CORRELABS, 0x88 },
377 { STV090x_P1_AGC2O, 0x5b },
378 { STV090x_P1_AGC2REF, 0x38 },
379 { STV090x_P1_CARCFG, 0xe4 },
380 { STV090x_P1_ACLC, 0x1A },
381 { STV090x_P1_BCLC, 0x09 },
382 { STV090x_P1_CARHDR, 0x08 },
383 { STV090x_P1_KREFTMG, 0xc1 },
384 { STV090x_P1_SFRSTEP, 0x58 },
385 { STV090x_P1_TMGCFG2, 0x01 },
386 { STV090x_P1_CAR2CFG, 0x26 },
387 { STV090x_P1_BCLC2S2Q, 0x86 },
388 { STV090x_P1_BCLC2S28, 0x86 },
389 { STV090x_P1_SMAPCOEF7, 0x77 },
390 { STV090x_P1_SMAPCOEF6, 0x85 },
391 { STV090x_P1_SMAPCOEF5, 0x77 },
392 { STV090x_P1_DMDCFG2, 0x3b },
393 { STV090x_P1_MODCODLST0, 0xff },
394 { STV090x_P1_MODCODLST1, 0xff },
395 { STV090x_P1_MODCODLST2, 0xff },
396 { STV090x_P1_MODCODLST3, 0xff },
397 { STV090x_P1_MODCODLST4, 0xff },
398 { STV090x_P1_MODCODLST5, 0xff },
399 { STV090x_P1_MODCODLST6, 0xff },
400 { STV090x_P1_MODCODLST7, 0xcc },
401 { STV090x_P1_MODCODLST8, 0xcc },
402 { STV090x_P1_MODCODLST9, 0xcc },
403 { STV090x_P1_MODCODLSTA, 0xcc },
404 { STV090x_P1_MODCODLSTB, 0xcc },
405 { STV090x_P1_MODCODLSTC, 0xcc },
406 { STV090x_P1_MODCODLSTD, 0xcc },
407 { STV090x_P1_MODCODLSTE, 0xcc },
408 { STV090x_P1_MODCODLSTF, 0xcf },
409 { STV090x_GENCFG, 0x1c },
410 { STV090x_NBITER_NF4, 0x37 },
411 { STV090x_NBITER_NF5, 0x29 },
412 { STV090x_NBITER_NF6, 0x37 },
413 { STV090x_NBITER_NF7, 0x33 },
414 { STV090x_NBITER_NF8, 0x31 },
415 { STV090x_NBITER_NF9, 0x2f },
416 { STV090x_NBITER_NF10, 0x39 },
417 { STV090x_NBITER_NF11, 0x3a },
418 { STV090x_NBITER_NF12, 0x29 },
419 { STV090x_NBITER_NF13, 0x37 },
420 { STV090x_NBITER_NF14, 0x33 },
421 { STV090x_NBITER_NF15, 0x2f },
422 { STV090x_NBITER_NF16, 0x39 },
423 { STV090x_NBITER_NF17, 0x3a },
424 { STV090x_NBITERNOERR, 0x04 },
425 { STV090x_GAINLLR_NF4, 0x0C },
426 { STV090x_GAINLLR_NF5, 0x0F },
427 { STV090x_GAINLLR_NF6, 0x11 },
428 { STV090x_GAINLLR_NF7, 0x14 },
429 { STV090x_GAINLLR_NF8, 0x17 },
430 { STV090x_GAINLLR_NF9, 0x19 },
431 { STV090x_GAINLLR_NF10, 0x20 },
432 { STV090x_GAINLLR_NF11, 0x21 },
433 { STV090x_GAINLLR_NF12, 0x0D },
434 { STV090x_GAINLLR_NF13, 0x0F },
435 { STV090x_GAINLLR_NF14, 0x13 },
436 { STV090x_GAINLLR_NF15, 0x1A },
437 { STV090x_GAINLLR_NF16, 0x1F },
438 { STV090x_GAINLLR_NF17, 0x21 },
439 { STV090x_RCCFGH, 0x20 },
440 { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */
441 { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/
442};
443
444static struct stv090x_reg stv0900_cut20_val[] = {
445
446 { STV090x_P2_DMDCFG3, 0xe8 },
447 { STV090x_P2_DMDCFG4, 0x10 },
448 { STV090x_P2_CARFREQ, 0x38 },
449 { STV090x_P2_CARHDR, 0x20 },
450 { STV090x_P2_KREFTMG, 0x5a },
451 { STV090x_P2_SMAPCOEF7, 0x06 },
452 { STV090x_P2_SMAPCOEF6, 0x00 },
453 { STV090x_P2_SMAPCOEF5, 0x04 },
454 { STV090x_P2_NOSCFG, 0x0c },
455 { STV090x_P1_DMDCFG3, 0xe8 },
456 { STV090x_P1_DMDCFG4, 0x10 },
457 { STV090x_P1_CARFREQ, 0x38 },
458 { STV090x_P1_CARHDR, 0x20 },
459 { STV090x_P1_KREFTMG, 0x5a },
460 { STV090x_P1_SMAPCOEF7, 0x06 },
461 { STV090x_P1_SMAPCOEF6, 0x00 },
462 { STV090x_P1_SMAPCOEF5, 0x04 },
463 { STV090x_P1_NOSCFG, 0x0c },
464 { STV090x_GAINLLR_NF4, 0x21 },
465 { STV090x_GAINLLR_NF5, 0x21 },
466 { STV090x_GAINLLR_NF6, 0x20 },
467 { STV090x_GAINLLR_NF7, 0x1F },
468 { STV090x_GAINLLR_NF8, 0x1E },
469 { STV090x_GAINLLR_NF9, 0x1E },
470 { STV090x_GAINLLR_NF10, 0x1D },
471 { STV090x_GAINLLR_NF11, 0x1B },
472 { STV090x_GAINLLR_NF12, 0x20 },
473 { STV090x_GAINLLR_NF13, 0x20 },
474 { STV090x_GAINLLR_NF14, 0x20 },
475 { STV090x_GAINLLR_NF15, 0x20 },
476 { STV090x_GAINLLR_NF16, 0x20 },
477 { STV090x_GAINLLR_NF17, 0x21 },
478};
479
480static struct stv090x_reg stv0903_cut20_val[] = {
481 { STV090x_P1_DMDCFG3, 0xe8 },
482 { STV090x_P1_DMDCFG4, 0x10 },
483 { STV090x_P1_CARFREQ, 0x38 },
484 { STV090x_P1_CARHDR, 0x20 },
485 { STV090x_P1_KREFTMG, 0x5a },
486 { STV090x_P1_SMAPCOEF7, 0x06 },
487 { STV090x_P1_SMAPCOEF6, 0x00 },
488 { STV090x_P1_SMAPCOEF5, 0x04 },
489 { STV090x_P1_NOSCFG, 0x0c },
490 { STV090x_GAINLLR_NF4, 0x21 },
491 { STV090x_GAINLLR_NF5, 0x21 },
492 { STV090x_GAINLLR_NF6, 0x20 },
493 { STV090x_GAINLLR_NF7, 0x1F },
494 { STV090x_GAINLLR_NF8, 0x1E },
495 { STV090x_GAINLLR_NF9, 0x1E },
496 { STV090x_GAINLLR_NF10, 0x1D },
497 { STV090x_GAINLLR_NF11, 0x1B },
498 { STV090x_GAINLLR_NF12, 0x20 },
499 { STV090x_GAINLLR_NF13, 0x20 },
500 { STV090x_GAINLLR_NF14, 0x20 },
501 { STV090x_GAINLLR_NF15, 0x20 },
502 { STV090x_GAINLLR_NF16, 0x20 },
503 { STV090x_GAINLLR_NF17, 0x21 }
504};
505
506/* Cut 2.0 Long Frame Tracking CR loop */
507static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = {
508 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
509 { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e },
510 { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e },
511 { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d },
512 { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
513 { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
514 { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
515 { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
516 { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
517 { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d },
518 { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d },
519 { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d },
520 { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
521 { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
522 { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
523};
524
525/* Cut 3.0 Long Frame Tracking CR loop */
526static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = {
527 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
528 { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b },
529 { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
530 { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
531 { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
532 { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
533 { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
534 { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
535 { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
536 { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 },
537 { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a },
538 { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a },
539 { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b },
540 { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b },
541 { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b }
542};
543
544/* Cut 2.0 Long Frame Tracking CR Loop */
545static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = {
546 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
547 { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c },
548 { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c },
549 { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
550 { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
551 { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
552 { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
553 { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
554 { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
555 { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
556 { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
557 { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }
558};
559
560/* Cut 3.0 Long Frame Tracking CR Loop */
561static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = {
562 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
563 { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a },
564 { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a },
565 { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
566 { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
567 { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
568 { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
569 { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
570 { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
571 { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
572 { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
573 { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }
574};
575
576static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = {
577 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
578 { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e },
579 { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e },
580 { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e }
581};
582
583static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = {
584 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
585 { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b },
586 { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b },
587 { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b }
588};
589
590/* Cut 2.0 Short Frame Tracking CR Loop */
591static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
592 /* MODCOD 2M 5M 10M 20M 30M */
593 { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d },
594 { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c },
595 { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d },
596 { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }
597};
598
599/* Cut 3.0 Short Frame Tracking CR Loop */
600static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
601 /* MODCOD 2M 5M 10M 20M 30M */
602 { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
603 { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
604 { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
605 { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }
606};
607
608static inline s32 comp2(s32 __x, s32 __width)
609{
610 if (__width == 32)
611 return __x;
612 else
613 return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x;
614}
615
616static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
617{
618 const struct stv090x_config *config = state->config;
619 int ret;
620
621 u8 b0[] = { reg >> 8, reg & 0xff };
622 u8 buf;
623
624 struct i2c_msg msg[] = {
625 { .addr = config->address, .flags = 0, .buf = b0, .len = 2 },
626 { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 }
627 };
628
629 ret = i2c_transfer(state->i2c, msg, 2);
630 if (ret != 2) {
631 if (ret != -ERESTARTSYS)
632 dprintk(FE_ERROR, 1,
633 "Read error, Reg=[0x%02x], Status=%d",
634 reg, ret);
635
636 return ret < 0 ? ret : -EREMOTEIO;
637 }
638 if (unlikely(*state->verbose >= FE_DEBUGREG))
639 dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
640 reg, buf);
641
642 return (unsigned int) buf;
643}
644
645static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count)
646{
647 const struct stv090x_config *config = state->config;
648 int ret;
649 u8 buf[2 + count];
650 struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
651
652 buf[0] = reg >> 8;
653 buf[1] = reg & 0xff;
654 memcpy(&buf[2], data, count);
655
656 if (unlikely(*state->verbose >= FE_DEBUGREG)) {
657 int i;
658
659 printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
660 for (i = 0; i < count; i++)
661 printk(" %02x", data[i]);
662 printk("\n");
663 }
664
665 ret = i2c_transfer(state->i2c, &i2c_msg, 1);
666 if (ret != 1) {
667 if (ret != -ERESTARTSYS)
668 dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
669 reg, data[0], count, ret);
670 return ret < 0 ? ret : -EREMOTEIO;
671 }
672
673 return 0;
674}
675
676static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
677{
678 return stv090x_write_regs(state, reg, &data, 1);
679}
680
681static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
682{
683 struct stv090x_state *state = fe->demodulator_priv;
684 u32 reg;
685
686 reg = STV090x_READ_DEMOD(state, I2CRPT);
687 if (enable) {
688 dprintk(FE_DEBUG, 1, "Enable Gate");
689 STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1);
690 if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0)
691 goto err;
692
693 } else {
694 dprintk(FE_DEBUG, 1, "Disable Gate");
695 STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0);
696 if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
697 goto err;
698 }
699 return 0;
700err:
701 dprintk(FE_ERROR, 1, "I/O error");
702 return -1;
703}
704
705static void stv090x_get_lock_tmg(struct stv090x_state *state)
706{
707 switch (state->algo) {
708 case STV090x_BLIND_SEARCH:
709 dprintk(FE_DEBUG, 1, "Blind Search");
710 if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/
711 state->DemodTimeout = 1500;
712 state->FecTimeout = 400;
713 } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/
714 state->DemodTimeout = 1000;
715 state->FecTimeout = 300;
716 } else { /*SR >20Msps*/
717 state->DemodTimeout = 700;
718 state->FecTimeout = 100;
719 }
720 break;
721
722 case STV090x_COLD_SEARCH:
723 case STV090x_WARM_SEARCH:
724 default:
725 dprintk(FE_DEBUG, 1, "Normal Search");
726 if (state->srate <= 1000000) { /*SR <=1Msps*/
727 state->DemodTimeout = 4500;
728 state->FecTimeout = 1700;
729 } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */
730 state->DemodTimeout = 2500;
731 state->FecTimeout = 1100;
732 } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */
733 state->DemodTimeout = 1000;
734 state->FecTimeout = 550;
735 } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */
736 state->DemodTimeout = 700;
737 state->FecTimeout = 250;
738 } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */
739 state->DemodTimeout = 400;
740 state->FecTimeout = 130;
741 } else { /*SR >20Msps*/
742 state->DemodTimeout = 300;
743 state->FecTimeout = 100;
744 }
745 break;
746 }
747
748 if (state->algo == STV090x_WARM_SEARCH)
749 state->DemodTimeout /= 2;
750}
751
752static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
753{
754 u32 sym;
755
756 if (srate > 60000000) {
757 sym = (srate << 4); /* SR * 2^16 / master_clk */
758 sym /= (state->mclk >> 12);
759 } else if (srate > 6000000) {
760 sym = (srate << 6);
761 sym /= (state->mclk >> 10);
762 } else {
763 sym = (srate << 9);
764 sym /= (state->mclk >> 7);
765 }
766
767 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
768 goto err;
769 if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */
770 goto err;
771
772 return 0;
773err:
774 dprintk(FE_ERROR, 1, "I/O error");
775 return -1;
776}
777
778static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate)
779{
780 u32 sym;
781
782 srate = 105 * (srate / 100);
783 if (srate > 60000000) {
784 sym = (srate << 4); /* SR * 2^16 / master_clk */
785 sym /= (state->mclk >> 12);
786 } else if (srate > 6000000) {
787 sym = (srate << 6);
788 sym /= (state->mclk >> 10);
789 } else {
790 sym = (srate << 9);
791 sym /= (state->mclk >> 7);
792 }
793
794 if (sym < 0x7fff) {
795 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */
796 goto err;
797 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */
798 goto err;
799 } else {
800 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */
801 goto err;
802 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */
803 goto err;
804 }
805
806 return 0;
807err:
808 dprintk(FE_ERROR, 1, "I/O error");
809 return -1;
810}
811
812static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate)
813{
814 u32 sym;
815
816 srate = 95 * (srate / 100);
817 if (srate > 60000000) {
818 sym = (srate << 4); /* SR * 2^16 / master_clk */
819 sym /= (state->mclk >> 12);
820 } else if (srate > 6000000) {
821 sym = (srate << 6);
822 sym /= (state->mclk >> 10);
823 } else {
824 sym = (srate << 9);
825 sym /= (state->mclk >> 7);
826 }
827
828 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0xff)) < 0) /* MSB */
829 goto err;
830 if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
831 goto err;
832 return 0;
833err:
834 dprintk(FE_ERROR, 1, "I/O error");
835 return -1;
836}
837
838static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff)
839{
840 u32 ro;
841
842 switch (rolloff) {
843 case STV090x_RO_20:
844 ro = 20;
845 break;
846 case STV090x_RO_25:
847 ro = 25;
848 break;
849 case STV090x_RO_35:
850 default:
851 ro = 35;
852 break;
853 }
854
855 return srate + (srate * ro) / 100;
856}
857
858static int stv090x_set_vit_thacq(struct stv090x_state *state)
859{
860 if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0)
861 goto err;
862 if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0)
863 goto err;
864 if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0)
865 goto err;
866 if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0)
867 goto err;
868 if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0)
869 goto err;
870 if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0)
871 goto err;
872 return 0;
873err:
874 dprintk(FE_ERROR, 1, "I/O error");
875 return -1;
876}
877
878static int stv090x_set_vit_thtracq(struct stv090x_state *state)
879{
880 if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0)
881 goto err;
882 if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0)
883 goto err;
884 if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0)
885 goto err;
886 if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0)
887 goto err;
888 if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0)
889 goto err;
890 if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0)
891 goto err;
892 return 0;
893err:
894 dprintk(FE_ERROR, 1, "I/O error");
895 return -1;
896}
897
898static int stv090x_set_viterbi(struct stv090x_state *state)
899{
900 switch (state->search_mode) {
901 case STV090x_SEARCH_AUTO:
902 if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */
903 goto err;
904 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */
905 goto err;
906 break;
907 case STV090x_SEARCH_DVBS1:
908 if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */
909 goto err;
910 switch (state->fec) {
911 case STV090x_PR12:
912 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
913 goto err;
914 break;
915
916 case STV090x_PR23:
917 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
918 goto err;
919 break;
920
921 case STV090x_PR34:
922 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0)
923 goto err;
924 break;
925
926 case STV090x_PR56:
927 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0)
928 goto err;
929 break;
930
931 case STV090x_PR78:
932 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0)
933 goto err;
934 break;
935
936 default:
937 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */
938 goto err;
939 break;
940 }
941 break;
942 case STV090x_SEARCH_DSS:
943 if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0)
944 goto err;
945 switch (state->fec) {
946 case STV090x_PR12:
947 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
948 goto err;
949 break;
950
951 case STV090x_PR23:
952 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
953 goto err;
954 break;
955
956 case STV090x_PR67:
957 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0)
958 goto err;
959 break;
960
961 default:
962 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */
963 goto err;
964 break;
965 }
966 break;
967 default:
968 break;
969 }
970 return 0;
971err:
972 dprintk(FE_ERROR, 1, "I/O error");
973 return -1;
974}
975
976static int stv090x_stop_modcod(struct stv090x_state *state)
977{
978 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
979 goto err;
980 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
981 goto err;
982 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
983 goto err;
984 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
985 goto err;
986 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
987 goto err;
988 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
989 goto err;
990 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
991 goto err;
992 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0)
993 goto err;
994 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0)
995 goto err;
996 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0)
997 goto err;
998 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0)
999 goto err;
1000 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0)
1001 goto err;
1002 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0)
1003 goto err;
1004 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0)
1005 goto err;
1006 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
1007 goto err;
1008 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0)
1009 goto err;
1010 return 0;
1011err:
1012 dprintk(FE_ERROR, 1, "I/O error");
1013 return -1;
1014}
1015
1016static int stv090x_activate_modcod(struct stv090x_state *state)
1017{
1018 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
1019 goto err;
1020 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0)
1021 goto err;
1022 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0)
1023 goto err;
1024 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0)
1025 goto err;
1026 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0)
1027 goto err;
1028 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0)
1029 goto err;
1030 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0)
1031 goto err;
1032 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
1033 goto err;
1034 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
1035 goto err;
1036 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
1037 goto err;
1038 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
1039 goto err;
1040 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
1041 goto err;
1042 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
1043 goto err;
1044 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
1045 goto err;
1046 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0)
1047 goto err;
1048 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
1049 goto err;
1050
1051 return 0;
1052err:
1053 dprintk(FE_ERROR, 1, "I/O error");
1054 return -1;
1055}
1056
1057static int stv090x_activate_modcod_single(struct stv090x_state *state)
1058{
1059
1060 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
1061 goto err;
1062 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0)
1063 goto err;
1064 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0)
1065 goto err;
1066 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0)
1067 goto err;
1068 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0)
1069 goto err;
1070 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0)
1071 goto err;
1072 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0)
1073 goto err;
1074 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0)
1075 goto err;
1076 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0)
1077 goto err;
1078 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0)
1079 goto err;
1080 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0)
1081 goto err;
1082 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0)
1083 goto err;
1084 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0)
1085 goto err;
1086 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0)
1087 goto err;
1088 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0)
1089 goto err;
1090 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0)
1091 goto err;
1092
1093 return 0;
1094
1095err:
1096 dprintk(FE_ERROR, 1, "I/O error");
1097 return -1;
1098}
1099
1100static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
1101{
1102 u32 reg;
1103
1104 switch (state->demod) {
1105 case STV090x_DEMODULATOR_0:
1106 mutex_lock(&demod_lock);
1107 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
1108 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
1109 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
1110 goto err;
1111 mutex_unlock(&demod_lock);
1112 break;
1113
1114 case STV090x_DEMODULATOR_1:
1115 mutex_lock(&demod_lock);
1116 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
1117 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
1118 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
1119 goto err;
1120 mutex_unlock(&demod_lock);
1121 break;
1122
1123 default:
1124 dprintk(FE_ERROR, 1, "Wrong demodulator!");
1125 break;
1126 }
1127 return 0;
1128err:
1129 mutex_unlock(&demod_lock);
1130 dprintk(FE_ERROR, 1, "I/O error");
1131 return -1;
1132}
1133
1134static int stv090x_dvbs_track_crl(struct stv090x_state *state)
1135{
1136 if (state->dev_ver >= 0x30) {
1137 /* Set ACLC BCLC optimised value vs SR */
1138 if (state->srate >= 15000000) {
1139 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
1140 goto err;
1141 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0)
1142 goto err;
1143 } else if ((state->srate >= 7000000) && (15000000 > state->srate)) {
1144 if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0)
1145 goto err;
1146 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0)
1147 goto err;
1148 } else if (state->srate < 7000000) {
1149 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0)
1150 goto err;
1151 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0)
1152 goto err;
1153 }
1154
1155 } else {
1156 /* Cut 2.0 */
1157 if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0)
1158 goto err;
1159 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
1160 goto err;
1161 }
1162 return 0;
1163err:
1164 dprintk(FE_ERROR, 1, "I/O error");
1165 return -1;
1166}
1167
1168static int stv090x_delivery_search(struct stv090x_state *state)
1169{
1170 u32 reg;
1171
1172 switch (state->search_mode) {
1173 case STV090x_SEARCH_DVBS1:
1174 case STV090x_SEARCH_DSS:
1175 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1176 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1177 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
1178 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1179 goto err;
1180
1181 /* Activate Viterbi decoder in legacy search,
1182 * do not use FRESVIT1, might impact VITERBI2
1183 */
1184 if (stv090x_vitclk_ctl(state, 0) < 0)
1185 goto err;
1186
1187 if (stv090x_dvbs_track_crl(state) < 0)
1188 goto err;
1189
1190 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */
1191 goto err;
1192
1193 if (stv090x_set_vit_thacq(state) < 0)
1194 goto err;
1195 if (stv090x_set_viterbi(state) < 0)
1196 goto err;
1197 break;
1198
1199 case STV090x_SEARCH_DVBS2:
1200 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1201 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
1202 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
1203 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1204 goto err;
1205 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1206 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
1207 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1208 goto err;
1209
1210 if (stv090x_vitclk_ctl(state, 1) < 0)
1211 goto err;
1212
1213 if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */
1214 goto err;
1215 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
1216 goto err;
1217
1218 if (state->dev_ver <= 0x20) {
1219 /* enable S2 carrier loop */
1220 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
1221 goto err;
1222 } else {
1223 /* > Cut 3: Stop carrier 3 */
1224 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
1225 goto err;
1226 }
1227
1228 if (state->demod_mode != STV090x_SINGLE) {
1229 /* Cut 2: enable link during search */
1230 if (stv090x_activate_modcod(state) < 0)
1231 goto err;
1232 } else {
1233 /* Single demodulator
1234 * Authorize SHORT and LONG frames,
1235 * QPSK, 8PSK, 16APSK and 32APSK
1236 */
1237 if (stv090x_activate_modcod_single(state) < 0)
1238 goto err;
1239 }
1240
1241 break;
1242
1243 case STV090x_SEARCH_AUTO:
1244 default:
1245 /* enable DVB-S2 and DVB-S2 in Auto MODE */
1246 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1247 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1248 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
1249 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1250 goto err;
1251
1252 if (stv090x_vitclk_ctl(state, 0) < 0)
1253 goto err;
1254
1255 if (stv090x_dvbs_track_crl(state) < 0)
1256 goto err;
1257
1258 if (state->dev_ver <= 0x20) {
1259 /* enable S2 carrier loop */
1260 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
1261 goto err;
1262 } else {
1263 /* > Cut 3: Stop carrier 3 */
1264 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
1265 goto err;
1266 }
1267
1268 if (state->demod_mode != STV090x_SINGLE) {
1269 /* Cut 2: enable link during search */
1270 if (stv090x_activate_modcod(state) < 0)
1271 goto err;
1272 } else {
1273 /* Single demodulator
1274 * Authorize SHORT and LONG frames,
1275 * QPSK, 8PSK, 16APSK and 32APSK
1276 */
1277 if (stv090x_activate_modcod_single(state) < 0)
1278 goto err;
1279 }
1280
1281 if (state->srate >= 2000000) {
1282 /* Srate >= 2MSPS, Viterbi threshold to acquire */
1283 if (stv090x_set_vit_thacq(state) < 0)
1284 goto err;
1285 } else {
1286 /* Srate < 2MSPS, Reset Viterbi thresholdto track
1287 * and then re-acquire
1288 */
1289 if (stv090x_set_vit_thtracq(state) < 0)
1290 goto err;
1291 }
1292
1293 if (stv090x_set_viterbi(state) < 0)
1294 goto err;
1295 break;
1296 }
1297 return 0;
1298err:
1299 dprintk(FE_ERROR, 1, "I/O error");
1300 return -1;
1301}
1302
1303static int stv090x_start_search(struct stv090x_state *state)
1304{
1305 u32 reg, freq_abs;
1306 s16 freq;
1307
1308 /* Reset demodulator */
1309 reg = STV090x_READ_DEMOD(state, DMDISTATE);
1310 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f);
1311 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
1312 goto err;
1313
1314 if (state->dev_ver <= 0x20) {
1315 if (state->srate <= 5000000) {
1316 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
1317 goto err;
1318 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
1319 goto err;
1320 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0xff) < 0)
1321 goto err;
1322 if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
1323 goto err;
1324 if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0)
1325 goto err;
1326
1327 /*enlarge the timing bandwith for Low SR*/
1328 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0)
1329 goto err;
1330 } else {
1331 /* If the symbol rate is >5 Msps
1332 Set The carrier search up and low to auto mode */
1333 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
1334 goto err;
1335 /*reduce the timing bandwith for high SR*/
1336 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
1337 goto err;
1338 }
1339 } else {
1340 /* >= Cut 3 */
1341 if (state->srate <= 5000000) {
1342 /* enlarge the timing bandwith for Low SR */
1343 STV090x_WRITE_DEMOD(state, RTCS2, 0x68);
1344 } else {
1345 /* reduce timing bandwith for high SR */
1346 STV090x_WRITE_DEMOD(state, RTCS2, 0x44);
1347 }
1348
1349 /* Set CFR min and max to manual mode */
1350 STV090x_WRITE_DEMOD(state, CARCFG, 0x46);
1351
1352 if (state->algo == STV090x_WARM_SEARCH) {
1353 /* WARM Start
1354 * CFR min = -1MHz,
1355 * CFR max = +1MHz
1356 */
1357 freq_abs = 1000 << 16;
1358 freq_abs /= (state->mclk / 1000);
1359 freq = (s16) freq_abs;
1360 } else {
1361 /* COLD Start
1362 * CFR min =- (SearchRange / 2 + 600KHz)
1363 * CFR max = +(SearchRange / 2 + 600KHz)
1364 * (600KHz for the tuner step size)
1365 */
1366 freq_abs = (state->search_range / 2000) + 600;
1367 freq_abs = freq_abs << 16;
1368 freq_abs /= (state->mclk / 1000);
1369 freq = (s16) freq_abs;
1370 }
1371
1372 if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
1373 goto err;
1374 if (STV090x_WRITE_DEMOD(state, CFRUP1, LSB(freq)) < 0)
1375 goto err;
1376
1377 freq *= -1;
1378
1379 if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0)
1380 goto err;
1381 if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0)
1382 goto err;
1383
1384 }
1385
1386 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0)
1387 goto err;
1388 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
1389 goto err;
1390
1391 if (state->dev_ver >= 0x20) {
1392 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
1393 goto err;
1394 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
1395 goto err;
1396
1397 if ((state->search_mode == STV090x_DVBS1) ||
1398 (state->search_mode == STV090x_DSS) ||
1399 (state->search_mode == STV090x_SEARCH_AUTO)) {
1400
1401 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
1402 goto err;
1403 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0)
1404 goto err;
1405 }
1406 }
1407
1408 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0)
1409 goto err;
1410 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0)
1411 goto err;
1412 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0)
1413 goto err;
1414
1415 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1416 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
1417 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
1418 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1419 goto err;
1420 reg = STV090x_READ_DEMOD(state, DMDCFG2);
1421 STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0);
1422 if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
1423 goto err;
1424
1425 if (state->dev_ver >= 0x20) {
1426 /*Frequency offset detector setting*/
1427 if (state->srate < 2000000) {
1428 if (state->dev_ver <= 0x20) {
1429 /* Cut 2 */
1430 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
1431 goto err;
1432 } else {
1433 /* Cut 2 */
1434 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
1435 goto err;
1436 }
1437 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
1438 goto err;
1439 }
1440
1441 if (state->srate < 10000000) {
1442 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
1443 goto err;
1444 } else {
1445 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
1446 goto err;
1447 }
1448 } else {
1449 if (state->srate < 10000000) {
1450 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0)
1451 goto err;
1452 } else {
1453 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0)
1454 goto err;
1455 }
1456 }
1457
1458 switch (state->algo) {
1459 case STV090x_WARM_SEARCH:
1460 /* The symbol rate and the exact
1461 * carrier Frequency are known
1462 */
1463 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
1464 goto err;
1465 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
1466 goto err;
1467 break;
1468
1469 case STV090x_COLD_SEARCH:
1470 /* The symbol rate is known */
1471 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
1472 goto err;
1473 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
1474 goto err;
1475 break;
1476
1477 default:
1478 break;
1479 }
1480 return 0;
1481err:
1482 dprintk(FE_ERROR, 1, "I/O error");
1483 return -1;
1484}
1485
1486static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1487{
1488 u32 agc2_min = 0, agc2 = 0, freq_init, freq_step, reg;
1489 s32 i, j, steps, dir;
1490
1491 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1492 goto err;
1493 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1494 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
1495 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
1496 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1497 goto err;
1498
1499 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */
1500 goto err;
1501 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
1502 goto err;
1503 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */
1504 goto err;
1505 if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
1506 goto err;
1507 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */
1508 goto err;
1509 if (stv090x_set_srate(state, 1000000) < 0)
1510 goto err;
1511
1512 steps = -1 + state->search_range / 1000000;
1513 steps /= 2;
1514 steps = (2 * steps) + 1;
1515 if (steps < 0)
1516 steps = 1;
1517
1518 dir = 1;
1519 freq_step = (1000000 * 256) / (state->mclk / 256);
1520 freq_init = 0;
1521
1522 for (i = 0; i < steps; i++) {
1523 if (dir > 0)
1524 freq_init = freq_init + (freq_step * i);
1525 else
1526 freq_init = freq_init - (freq_step * i);
1527
1528 dir = -1;
1529
1530 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
1531 goto err;
1532 if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0)
1533 goto err;
1534 if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0)
1535 goto err;
1536 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
1537 goto err;
1538 msleep(10);
1539 for (j = 0; j < 10; j++) {
1540 agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
1541 agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
1542 }
1543 agc2 /= 10;
1544 agc2_min = 0xffff;
1545 if (agc2 < 0xffff)
1546 agc2_min = agc2;
1547 }
1548
1549 return agc2_min;
1550err:
1551 dprintk(FE_ERROR, 1, "I/O error");
1552 return -1;
1553}
1554
1555static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk)
1556{
1557 u8 r3, r2, r1, r0;
1558 s32 srate, int_1, int_2, tmp_1, tmp_2;
1559
1560 r3 = STV090x_READ_DEMOD(state, SFR3);
1561 r2 = STV090x_READ_DEMOD(state, SFR2);
1562 r1 = STV090x_READ_DEMOD(state, SFR1);
1563 r0 = STV090x_READ_DEMOD(state, SFR0);
1564
1565 srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0);
1566
1567 int_1 = clk >> 16;
1568 int_2 = srate >> 16;
1569
1570 tmp_1 = clk % 0x10000;
1571 tmp_2 = srate % 0x10000;
1572
1573 srate = (int_1 * int_2) +
1574 ((int_1 * tmp_2) >> 16) +
1575 ((int_2 * tmp_1) >> 16);
1576
1577 return srate;
1578}
1579
1580static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1581{
1582 struct dvb_frontend *fe = &state->frontend;
1583
1584 int tmg_lock = 0, i;
1585 s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
1586 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
1587
1588 reg = STV090x_READ_DEMOD(state, DMDISTATE);
1589 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
1590 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
1591 goto err;
1592 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
1593 goto err;
1594 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
1595 goto err;
1596 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
1597 goto err;
1598 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1599 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
1600 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 1);
1601 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1602 goto err;
1603
1604 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0)
1605 goto err;
1606 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
1607 goto err;
1608 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0)
1609 goto err;
1610 if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
1611 goto err;
1612 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
1613 goto err;
1614 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x60) < 0)
1615 goto err;
1616
1617 if (state->dev_ver >= 0x30) {
1618 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
1619 goto err;
1620 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
1621 goto err;
1622
1623 } else if (state->dev_ver >= 0x20) {
1624 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
1625 goto err;
1626 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
1627 goto err;
1628 }
1629
1630 if (state->srate <= 2000000)
1631 car_step = 1000;
1632 else if (state->srate <= 5000000)
1633 car_step = 2000;
1634 else if (state->srate <= 12000000)
1635 car_step = 3000;
1636 else
1637 car_step = 5000;
1638
1639 steps = -1 + ((state->search_range / 1000) / car_step);
1640 steps /= 2;
1641 steps = (2 * steps) + 1;
1642 if (steps < 0)
1643 steps = 1;
1644 else if (steps > 10) {
1645 steps = 11;
1646 car_step = (state->search_range / 1000) / 10;
1647 }
1648 cur_step = 0;
1649 dir = 1;
1650 freq = state->frequency;
1651
1652 while ((!tmg_lock) && (cur_step < steps)) {
1653 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
1654 goto err;
1655 reg = STV090x_READ_DEMOD(state, DMDISTATE);
1656 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x00); /* trigger acquisition */
1657 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
1658 goto err;
1659 msleep(50);
1660 for (i = 0; i < 10; i++) {
1661 reg = STV090x_READ_DEMOD(state, DSTATUS);
1662 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
1663 tmg_cpt++;
1664 agc2 += STV090x_READ_DEMOD(state, AGC2I1) << 8;
1665 agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
1666 }
1667 agc2 /= 10;
1668 srate_coarse = stv090x_get_srate(state, state->mclk);
1669 cur_step++;
1670 dir *= -1;
1671 if ((tmg_cpt >= 5) && (agc2 < 0x1f00) && (srate_coarse < 55000000) && (srate_coarse > 850000))
1672 tmg_lock = 1;
1673 else if (cur_step < steps) {
1674 if (dir > 0)
1675 freq += cur_step * car_step;
1676 else
1677 freq -= cur_step * car_step;
1678
1679 /* Setup tuner */
1680 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
1681 goto err;
1682
1683 if (state->config->tuner_set_frequency) {
1684 if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
1685 goto err;
1686 }
1687
1688 if (state->config->tuner_set_bandwidth) {
1689 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
1690 goto err;
1691 }
1692
1693 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
1694 goto err;
1695
1696 msleep(50);
1697
1698 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
1699 goto err;
1700
1701 if (state->config->tuner_get_status) {
1702 if (state->config->tuner_get_status(fe, &reg) < 0)
1703 goto err;
1704 }
1705
1706 if (reg)
1707 dprintk(FE_DEBUG, 1, "Tuner phase locked");
1708 else
1709 dprintk(FE_DEBUG, 1, "Tuner unlocked");
1710
1711 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
1712 goto err;
1713
1714 }
1715 }
1716 if (!tmg_lock)
1717 srate_coarse = 0;
1718 else
1719 srate_coarse = stv090x_get_srate(state, state->mclk);
1720
1721 return srate_coarse;
1722err:
1723 dprintk(FE_ERROR, 1, "I/O error");
1724 return -1;
1725}
1726
1727static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1728{
1729 u32 srate_coarse, freq_coarse, sym, reg;
1730
1731 srate_coarse = stv090x_get_srate(state, state->mclk);
1732 freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8;
1733 freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
1734 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1735
1736 if (sym < state->srate)
1737 srate_coarse = 0;
1738 else {
1739 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
1740 goto err;
1741 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0x01) < 0)
1742 goto err;
1743 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
1744 goto err;
1745 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
1746 goto err;
1747 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
1748 goto err;
1749 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1750 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
1751 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1752 goto err;
1753
1754 if (state->dev_ver >= 0x30) {
1755 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
1756 goto err;
1757 } else if (state->dev_ver >= 0x20) {
1758 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
1759 goto err;
1760 }
1761
1762 if (srate_coarse > 3000000) {
1763 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1764 sym = (sym / 1000) * 65536;
1765 sym /= (state->mclk / 1000);
1766 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
1767 goto err;
1768 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
1769 goto err;
1770 sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
1771 sym = (sym / 1000) * 65536;
1772 sym /= (state->mclk / 1000);
1773 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
1774 goto err;
1775 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
1776 goto err;
1777 sym = (srate_coarse / 1000) * 65536;
1778 sym /= (state->mclk / 1000);
1779 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
1780 goto err;
1781 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
1782 goto err;
1783 } else {
1784 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1785 sym = (sym / 100) * 65536;
1786 sym /= (state->mclk / 100);
1787 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
1788 goto err;
1789 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
1790 goto err;
1791 sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
1792 sym = (sym / 100) * 65536;
1793 sym /= (state->mclk / 100);
1794 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
1795 goto err;
1796 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
1797 goto err;
1798 sym = (srate_coarse / 100) * 65536;
1799 sym /= (state->mclk / 100);
1800 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
1801 goto err;
1802 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
1803 goto err;
1804 }
1805 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
1806 goto err;
1807 if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0)
1808 goto err;
1809 if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0)
1810 goto err;
1811 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */
1812 goto err;
1813 }
1814
1815 return srate_coarse;
1816
1817err:
1818 dprintk(FE_ERROR, 1, "I/O error");
1819 return -1;
1820}
1821
1822static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)
1823{
1824 s32 timer = 0, lock = 0;
1825 u32 reg;
1826 u8 stat;
1827
1828 while ((timer < timeout) && (!lock)) {
1829 reg = STV090x_READ_DEMOD(state, DMDSTATE);
1830 stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
1831
1832 switch (stat) {
1833 case 0: /* searching */
1834 case 1: /* first PLH detected */
1835 default:
1836 dprintk(FE_DEBUG, 1, "Demodulator searching ..");
1837 lock = 0;
1838 break;
1839 case 2: /* DVB-S2 mode */
1840 case 3: /* DVB-S1/legacy mode */
1841 reg = STV090x_READ_DEMOD(state, DSTATUS);
1842 lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
1843 break;
1844 }
1845
1846 if (!lock)
1847 msleep(10);
1848 else
1849 dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK");
1850
1851 timer += 10;
1852 }
1853 return lock;
1854}
1855
1856static int stv090x_blind_search(struct stv090x_state *state)
1857{
1858 u32 agc2, reg, srate_coarse;
1859 s32 timeout_dmd = 500, cpt_fail, agc2_ovflw, i;
1860 u8 k_ref, k_max, k_min;
1861 int coarse_fail, lock;
1862
1863 k_max = 120;
1864 k_min = 30;
1865
1866 agc2 = stv090x_get_agc2_min_level(state);
1867
1868 if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) {
1869 lock = 0;
1870 } else {
1871
1872 if (state->dev_ver <= 0x20) {
1873 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
1874 goto err;
1875 } else {
1876 /* > Cut 3 */
1877 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0)
1878 goto err;
1879 }
1880
1881 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
1882 goto err;
1883
1884 if (state->dev_ver >= 0x20) {
1885 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
1886 goto err;
1887 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
1888 goto err;
1889 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
1890 goto err;
1891 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */
1892 goto err;
1893 }
1894
1895 k_ref = k_max;
1896 do {
1897 if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0)
1898 goto err;
1899 if (stv090x_srate_srch_coarse(state) != 0) {
1900 srate_coarse = stv090x_srate_srch_fine(state);
1901 if (srate_coarse != 0) {
1902 stv090x_get_lock_tmg(state);
1903 lock = stv090x_get_dmdlock(state, timeout_dmd);
1904 } else {
1905 lock = 0;
1906 }
1907 } else {
1908 cpt_fail = 0;
1909 agc2_ovflw = 0;
1910 for (i = 0; i < 10; i++) {
1911 agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8;
1912 agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
1913 if (agc2 >= 0xff00)
1914 agc2_ovflw++;
1915 reg = STV090x_READ_DEMOD(state, DSTATUS2);
1916 if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) &&
1917 (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01))
1918
1919 cpt_fail++;
1920 }
1921 if ((cpt_fail > 7) || (agc2_ovflw > 7))
1922 coarse_fail = 1;
1923
1924 lock = 0;
1925 }
1926 k_ref -= 30;
1927 } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
1928 }
1929
1930 return lock;
1931
1932err:
1933 dprintk(FE_ERROR, 1, "I/O error");
1934 return -1;
1935}
1936
1937static int stv090x_chk_tmg(struct stv090x_state *state)
1938{
1939 u32 reg;
1940 s32 tmg_cpt = 0, i;
1941 u8 freq, tmg_thh, tmg_thl;
1942 int tmg_lock;
1943
1944 freq = STV090x_READ_DEMOD(state, CARFREQ);
1945 tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
1946 tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL);
1947 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
1948 goto err;
1949 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
1950 goto err;
1951
1952 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1953 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */
1954 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1955 goto err;
1956 if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0)
1957 goto err;
1958
1959 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0)
1960 goto err;
1961 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0)
1962 goto err;
1963
1964 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */
1965 goto err;
1966 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
1967 goto err;
1968 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0)
1969 goto err;
1970
1971 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */
1972 goto err;
1973 msleep(10);
1974
1975 for (i = 0; i < 10; i++) {
1976 reg = STV090x_READ_DEMOD(state, DSTATUS);
1977 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
1978 tmg_cpt++;
1979 msleep(1);
1980 }
1981 if (tmg_cpt >= 3)
1982 tmg_lock = 1;
1983
1984 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1985 goto err;
1986 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */
1987 goto err;
1988 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */
1989 goto err;
1990
1991 if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0)
1992 goto err;
1993 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0)
1994 goto err;
1995 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0)
1996 goto err;
1997
1998 return tmg_lock;
1999
2000err:
2001 dprintk(FE_ERROR, 1, "I/O error");
2002 return -1;
2003}
2004
2005static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2006{
2007 struct dvb_frontend *fe = &state->frontend;
2008
2009 u32 reg;
2010 s32 car_step, steps, cur_step, dir, freq, timeout_lock;
2011 int lock = 0;
2012
2013 if (state->srate >= 10000000)
2014 timeout_lock = timeout_dmd / 3;
2015 else
2016 timeout_lock = timeout_dmd / 2;
2017
2018 lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
2019 if (!lock) {
2020 if (state->srate >= 10000000) {
2021 if (stv090x_chk_tmg(state)) {
2022 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
2023 goto err;
2024 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
2025 goto err;
2026 lock = stv090x_get_dmdlock(state, timeout_dmd);
2027 } else {
2028 lock = 0;
2029 }
2030 } else {
2031 if (state->srate <= 4000000)
2032 car_step = 1000;
2033 else if (state->srate <= 7000000)
2034 car_step = 2000;
2035 else if (state->srate <= 10000000)
2036 car_step = 3000;
2037 else
2038 car_step = 5000;
2039
2040 steps = (state->search_range / 1000) / car_step;
2041 steps /= 2;
2042 steps = 2 * (steps + 1);
2043 if (steps < 0)
2044 steps = 2;
2045 else if (steps > 12)
2046 steps = 12;
2047
2048 cur_step = 1;
2049 dir = 1;
2050
2051 if (!lock) {
2052 freq = state->frequency;
2053 state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
2054 while ((cur_step <= steps) && (!lock)) {
2055 if (dir > 0)
2056 freq += cur_step * car_step;
2057 else
2058 freq -= cur_step * car_step;
2059
2060 /* Setup tuner */
2061 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
2062 goto err;
2063
2064 if (state->config->tuner_set_frequency) {
2065 if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
2066 goto err;
2067 }
2068
2069 if (state->config->tuner_set_bandwidth) {
2070 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
2071 goto err;
2072 }
2073
2074 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
2075 goto err;
2076
2077 msleep(50);
2078
2079 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
2080 goto err;
2081
2082 if (state->config->tuner_get_status) {
2083 if (state->config->tuner_get_status(fe, &reg) < 0)
2084 goto err;
2085 }
2086
2087 if (reg)
2088 dprintk(FE_DEBUG, 1, "Tuner phase locked");
2089 else
2090 dprintk(FE_DEBUG, 1, "Tuner unlocked");
2091
2092 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
2093 goto err;
2094
2095 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
2096 if (state->delsys == STV090x_DVBS2) {
2097 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2098 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
2099 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
2100 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2101 goto err;
2102 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2103 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2104 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2105 goto err;
2106 }
2107 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
2108 goto err;
2109 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
2110 goto err;
2111 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
2112 goto err;
2113 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
2114 goto err;
2115 lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
2116
2117 dir *= -1;
2118 cur_step++;
2119 }
2120 }
2121 }
2122 }
2123
2124 return lock;
2125
2126err:
2127 dprintk(FE_ERROR, 1, "I/O error");
2128 return -1;
2129}
2130
2131static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps)
2132{
2133 s32 timeout, inc, steps_max, srate, car_max;
2134
2135 srate = state->srate;
2136 car_max = state->search_range / 1000;
2137 car_max += car_max / 10;
2138 car_max = 65536 * (car_max / 2);
2139 car_max /= (state->mclk / 1000);
2140
2141 if (car_max > 0x4000)
2142 car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
2143
2144 inc = srate;
2145 inc /= state->mclk / 1000;
2146 inc *= 256;
2147 inc *= 256;
2148 inc /= 1000;
2149
2150 switch (state->search_mode) {
2151 case STV090x_SEARCH_DVBS1:
2152 case STV090x_SEARCH_DSS:
2153 inc *= 3; /* freq step = 3% of srate */
2154 timeout = 20;
2155 break;
2156
2157 case STV090x_SEARCH_DVBS2:
2158 inc *= 4;
2159 timeout = 25;
2160 break;
2161
2162 case STV090x_SEARCH_AUTO:
2163 default:
2164 inc *= 3;
2165 timeout = 25;
2166 break;
2167 }
2168 inc /= 100;
2169 if ((inc > car_max) || (inc < 0))
2170 inc = car_max / 2; /* increment <= 1/8 Mclk */
2171
2172 timeout *= 27500; /* 27.5 Msps reference */
2173 if (srate > 0)
2174 timeout /= (srate / 1000);
2175
2176 if ((timeout > 100) || (timeout < 0))
2177 timeout = 100;
2178
2179 steps_max = (car_max / inc) + 1; /* min steps = 3 */
2180 if ((steps_max > 100) || (steps_max < 0)) {
2181 steps_max = 100; /* max steps <= 100 */
2182 inc = car_max / steps_max;
2183 }
2184 *freq_inc = inc;
2185 *timeout_sw = timeout;
2186 *steps = steps_max;
2187
2188 return 0;
2189}
2190
2191static int stv090x_chk_signal(struct stv090x_state *state)
2192{
2193 s32 offst_car, agc2, car_max;
2194 int no_signal;
2195
2196 offst_car = STV090x_READ_DEMOD(state, CFR2) << 8;
2197 offst_car |= STV090x_READ_DEMOD(state, CFR1);
2198 offst_car = comp2(offst_car, 16);
2199
2200 agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8;
2201 agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
2202 car_max = state->search_range / 1000;
2203
2204 car_max += (car_max / 10); /* 10% margin */
2205 car_max = (65536 * car_max / 2);
2206 car_max /= state->mclk / 1000;
2207
2208 if (car_max > 0x4000)
2209 car_max = 0x4000;
2210
2211 if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) {
2212 no_signal = 1;
2213 dprintk(FE_DEBUG, 1, "No Signal");
2214 } else {
2215 no_signal = 0;
2216 dprintk(FE_DEBUG, 1, "Found Signal");
2217 }
2218
2219 return no_signal;
2220}
2221
2222static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max)
2223{
2224 int no_signal, lock = 0;
2225 s32 cpt_step = 0, offst_freq, car_max;
2226 u32 reg;
2227
2228 car_max = state->search_range / 1000;
2229 car_max += (car_max / 10);
2230 car_max = (65536 * car_max / 2);
2231 car_max /= (state->mclk / 1000);
2232 if (car_max > 0x4000)
2233 car_max = 0x4000;
2234
2235 if (zigzag)
2236 offst_freq = 0;
2237 else
2238 offst_freq = -car_max + inc;
2239
2240 do {
2241 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0)
2242 goto err;
2243 if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0)
2244 goto err;
2245 if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0)
2246 goto err;
2247 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
2248 goto err;
2249
2250 reg = STV090x_READ_DEMOD(state, PDELCTRL1);
2251 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */
2252 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
2253 goto err;
2254
2255 if (zigzag) {
2256 if (offst_freq >= 0)
2257 offst_freq = -offst_freq - 2 * inc;
2258 else
2259 offst_freq = -offst_freq;
2260 } else {
2261 offst_freq += 2 * inc;
2262 }
2263
2264 cpt_step++;
2265
2266 lock = stv090x_get_dmdlock(state, timeout);
2267 no_signal = stv090x_chk_signal(state);
2268
2269 } while ((!lock) &&
2270 (!no_signal) &&
2271 ((offst_freq - inc) < car_max) &&
2272 ((offst_freq + inc) > -car_max) &&
2273 (cpt_step < steps_max));
2274
2275 reg = STV090x_READ_DEMOD(state, PDELCTRL1);
2276 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0);
2277 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
2278 goto err;
2279
2280 return lock;
2281err:
2282 dprintk(FE_ERROR, 1, "I/O error");
2283 return -1;
2284}
2285
2286static int stv090x_sw_algo(struct stv090x_state *state)
2287{
2288 int no_signal, zigzag, lock = 0;
2289 u32 reg;
2290
2291 s32 dvbs2_fly_wheel;
2292 s32 inc, timeout_step, trials, steps_max;
2293
2294 /* get params */
2295 stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max);
2296
2297 switch (state->search_mode) {
2298 case STV090x_SEARCH_DVBS1:
2299 case STV090x_SEARCH_DSS:
2300 /* accelerate the frequency detector */
2301 if (state->dev_ver >= 0x20) {
2302 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
2303 goto err;
2304 }
2305
2306 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0)
2307 goto err;
2308 zigzag = 0;
2309 break;
2310
2311 case STV090x_SEARCH_DVBS2:
2312 if (state->dev_ver >= 0x20) {
2313 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2314 goto err;
2315 }
2316
2317 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
2318 goto err;
2319 zigzag = 1;
2320 break;
2321
2322 case STV090x_SEARCH_AUTO:
2323 default:
2324 /* accelerate the frequency detector */
2325 if (state->dev_ver >= 0x20) {
2326 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
2327 goto err;
2328 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2329 goto err;
2330 }
2331
2332 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0)
2333 goto err;
2334 zigzag = 0;
2335 break;
2336 }
2337
2338 trials = 0;
2339 do {
2340 lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max);
2341 no_signal = stv090x_chk_signal(state);
2342 trials++;
2343
2344 /*run the SW search 2 times maximum*/
2345 if (lock || no_signal || (trials == 2)) {
2346 /*Check if the demod is not losing lock in DVBS2*/
2347 if (state->dev_ver >= 0x20) {
2348 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
2349 goto err;
2350 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
2351 goto err;
2352 }
2353
2354 reg = STV090x_READ_DEMOD(state, DMDSTATE);
2355 if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) {
2356 /*Check if the demod is not losing lock in DVBS2*/
2357 msleep(timeout_step);
2358 reg = STV090x_READ_DEMOD(state, DMDFLYW);
2359 dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
2360 if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */
2361 msleep(timeout_step);
2362 reg = STV090x_READ_DEMOD(state, DMDFLYW);
2363 dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
2364 }
2365 if (dvbs2_fly_wheel < 0xd) {
2366 /*FALSE lock, The demod is loosing lock */
2367 lock = 0;
2368 if (trials < 2) {
2369 if (state->dev_ver >= 0x20) {
2370 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2371 goto err;
2372 }
2373
2374 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
2375 goto err;
2376 }
2377 }
2378 }
2379 }
2380 } while ((!lock) && (trials < 2) && (!no_signal));
2381
2382 return lock;
2383err:
2384 dprintk(FE_ERROR, 1, "I/O error");
2385 return -1;
2386}
2387
2388static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state)
2389{
2390 u32 reg;
2391 enum stv090x_delsys delsys;
2392
2393 reg = STV090x_READ_DEMOD(state, DMDSTATE);
2394 if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2)
2395 delsys = STV090x_DVBS2;
2396 else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) {
2397 reg = STV090x_READ_DEMOD(state, FECM);
2398 if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1)
2399 delsys = STV090x_DSS;
2400 else
2401 delsys = STV090x_DVBS1;
2402 } else {
2403 delsys = STV090x_ERROR;
2404 }
2405
2406 return delsys;
2407}
2408
2409/* in Hz */
2410static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
2411{
2412 s32 derot, int_1, int_2, tmp_1, tmp_2;
2413
2414 derot = STV090x_READ_DEMOD(state, CFR2) << 16;
2415 derot |= STV090x_READ_DEMOD(state, CFR1) << 8;
2416 derot |= STV090x_READ_DEMOD(state, CFR0);
2417
2418 derot = comp2(derot, 24);
2419 int_1 = state->mclk >> 12;
2420 int_2 = derot >> 12;
2421
2422 /* carrier_frequency = MasterClock * Reg / 2^24 */
2423 tmp_1 = state->mclk % 0x1000;
2424 tmp_2 = derot % 0x1000;
2425
2426 derot = (int_1 * int_2) +
2427 ((int_1 * tmp_2) >> 12) +
2428 ((int_1 * tmp_1) >> 12);
2429
2430 return derot;
2431}
2432
2433static int stv090x_get_viterbi(struct stv090x_state *state)
2434{
2435 u32 reg, rate;
2436
2437 reg = STV090x_READ_DEMOD(state, VITCURPUN);
2438 rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD);
2439
2440 switch (rate) {
2441 case 13:
2442 state->fec = STV090x_PR12;
2443 break;
2444
2445 case 18:
2446 state->fec = STV090x_PR23;
2447 break;
2448
2449 case 21:
2450 state->fec = STV090x_PR34;
2451 break;
2452
2453 case 24:
2454 state->fec = STV090x_PR56;
2455 break;
2456
2457 case 25:
2458 state->fec = STV090x_PR67;
2459 break;
2460
2461 case 26:
2462 state->fec = STV090x_PR78;
2463 break;
2464
2465 default:
2466 state->fec = STV090x_PRERR;
2467 break;
2468 }
2469
2470 return 0;
2471}
2472
2473static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state)
2474{
2475 struct dvb_frontend *fe = &state->frontend;
2476
2477 u8 tmg;
2478 u32 reg;
2479 s32 i = 0, offst_freq;
2480
2481 msleep(5);
2482
2483 if (state->algo == STV090x_BLIND_SEARCH) {
2484 tmg = STV090x_READ_DEMOD(state, TMGREG2);
2485 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c);
2486 while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) {
2487 tmg = STV090x_READ_DEMOD(state, TMGREG2);
2488 msleep(5);
2489 i += 5;
2490 }
2491 }
2492 state->delsys = stv090x_get_std(state);
2493
2494 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
2495 goto err;
2496
2497 if (state->config->tuner_get_frequency) {
2498 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
2499 goto err;
2500 }
2501
2502 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
2503 goto err;
2504
2505 offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000;
2506 state->frequency += offst_freq;
2507
2508 if (stv090x_get_viterbi(state) < 0)
2509 goto err;
2510
2511 reg = STV090x_READ_DEMOD(state, DMDMODCOD);
2512 state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
2513 state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
2514 state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1;
2515 reg = STV090x_READ_DEMOD(state, TMGOBS);
2516 state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
2517 reg = STV090x_READ_DEMOD(state, FECM);
2518 state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD);
2519
2520 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {
2521
2522 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
2523 goto err;
2524
2525 if (state->config->tuner_get_frequency) {
2526 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
2527 goto err;
2528 }
2529
2530 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
2531 goto err;
2532
2533 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
2534 return STV090x_RANGEOK;
2535 else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
2536 return STV090x_RANGEOK;
2537 else
2538 return STV090x_OUTOFRANGE; /* Out of Range */
2539 } else {
2540 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
2541 return STV090x_RANGEOK;
2542 else
2543 return STV090x_OUTOFRANGE;
2544 }
2545
2546 return STV090x_OUTOFRANGE;
2547err:
2548 dprintk(FE_ERROR, 1, "I/O error");
2549 return -1;
2550}
2551
2552static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate)
2553{
2554 s32 offst_tmg;
2555
2556 offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16;
2557 offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8;
2558 offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0);
2559
2560 offst_tmg = comp2(offst_tmg, 24); /* 2's complement */
2561 if (!offst_tmg)
2562 offst_tmg = 1;
2563
2564 offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg);
2565 offst_tmg /= 320;
2566
2567 return offst_tmg;
2568}
2569
2570static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots)
2571{
2572 u8 aclc = 0x29;
2573 s32 i;
2574 struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
2575
2576 if (state->dev_ver == 0x20) {
2577 car_loop = stv090x_s2_crl_cut20;
2578 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20;
2579 car_loop_apsk_low = stv090x_s2_apsk_crl_cut20;
2580 } else {
2581 /* >= Cut 3 */
2582 car_loop = stv090x_s2_crl_cut30;
2583 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30;
2584 car_loop_apsk_low = stv090x_s2_apsk_crl_cut30;
2585 }
2586
2587 if (modcod < STV090x_QPSK_12) {
2588 i = 0;
2589 while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod))
2590 i++;
2591
2592 if (i >= 3)
2593 i = 2;
2594
2595 } else {
2596 i = 0;
2597 while ((i < 14) && (modcod != car_loop[i].modcod))
2598 i++;
2599
2600 if (i >= 14) {
2601 i = 0;
2602 while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod))
2603 i++;
2604
2605 if (i >= 11)
2606 i = 10;
2607 }
2608 }
2609
2610 if (modcod <= STV090x_QPSK_25) {
2611 if (pilots) {
2612 if (state->srate <= 3000000)
2613 aclc = car_loop_qpsk_low[i].crl_pilots_on_2;
2614 else if (state->srate <= 7000000)
2615 aclc = car_loop_qpsk_low[i].crl_pilots_on_5;
2616 else if (state->srate <= 15000000)
2617 aclc = car_loop_qpsk_low[i].crl_pilots_on_10;
2618 else if (state->srate <= 25000000)
2619 aclc = car_loop_qpsk_low[i].crl_pilots_on_20;
2620 else
2621 aclc = car_loop_qpsk_low[i].crl_pilots_on_30;
2622 } else {
2623 if (state->srate <= 3000000)
2624 aclc = car_loop_qpsk_low[i].crl_pilots_off_2;
2625 else if (state->srate <= 7000000)
2626 aclc = car_loop_qpsk_low[i].crl_pilots_off_5;
2627 else if (state->srate <= 15000000)
2628 aclc = car_loop_qpsk_low[i].crl_pilots_off_10;
2629 else if (state->srate <= 25000000)
2630 aclc = car_loop_qpsk_low[i].crl_pilots_off_20;
2631 else
2632 aclc = car_loop_qpsk_low[i].crl_pilots_off_30;
2633 }
2634
2635 } else if (modcod <= STV090x_8PSK_910) {
2636 if (pilots) {
2637 if (state->srate <= 3000000)
2638 aclc = car_loop[i].crl_pilots_on_2;
2639 else if (state->srate <= 7000000)
2640 aclc = car_loop[i].crl_pilots_on_5;
2641 else if (state->srate <= 15000000)
2642 aclc = car_loop[i].crl_pilots_on_10;
2643 else if (state->srate <= 25000000)
2644 aclc = car_loop[i].crl_pilots_on_20;
2645 else
2646 aclc = car_loop[i].crl_pilots_on_30;
2647 } else {
2648 if (state->srate <= 3000000)
2649 aclc = car_loop[i].crl_pilots_off_2;
2650 else if (state->srate <= 7000000)
2651 aclc = car_loop[i].crl_pilots_off_5;
2652 else if (state->srate <= 15000000)
2653 aclc = car_loop[i].crl_pilots_off_10;
2654 else if (state->srate <= 25000000)
2655 aclc = car_loop[i].crl_pilots_off_20;
2656 else
2657 aclc = car_loop[i].crl_pilots_off_30;
2658 }
2659 } else { /* 16APSK and 32APSK */
2660 if (state->srate <= 3000000)
2661 aclc = car_loop_apsk_low[i].crl_pilots_on_2;
2662 else if (state->srate <= 7000000)
2663 aclc = car_loop_apsk_low[i].crl_pilots_on_5;
2664 else if (state->srate <= 15000000)
2665 aclc = car_loop_apsk_low[i].crl_pilots_on_10;
2666 else if (state->srate <= 25000000)
2667 aclc = car_loop_apsk_low[i].crl_pilots_on_20;
2668 else
2669 aclc = car_loop_apsk_low[i].crl_pilots_on_30;
2670 }
2671
2672 return aclc;
2673}
2674
2675static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
2676{
2677 struct stv090x_short_frame_crloop *short_crl;
2678 s32 index = 0;
2679 u8 aclc = 0x0b;
2680
2681 switch (state->modulation) {
2682 case STV090x_QPSK:
2683 default:
2684 index = 0;
2685 break;
2686 case STV090x_8PSK:
2687 index = 1;
2688 break;
2689 case STV090x_16APSK:
2690 index = 2;
2691 break;
2692 case STV090x_32APSK:
2693 index = 3;
2694 break;
2695 }
2696
2697 if (state->dev_ver >= 0x30)
2698 short_crl = stv090x_s2_short_crl_cut20;
2699 else if (state->dev_ver >= 0x20)
2700 short_crl = stv090x_s2_short_crl_cut30;
2701
2702 if (state->srate <= 3000000)
2703 aclc = short_crl[index].crl_2;
2704 else if (state->srate <= 7000000)
2705 aclc = short_crl[index].crl_5;
2706 else if (state->srate <= 15000000)
2707 aclc = short_crl[index].crl_10;
2708 else if (state->srate <= 25000000)
2709 aclc = short_crl[index].crl_20;
2710 else
2711 aclc = short_crl[index].crl_30;
2712
2713 return aclc;
2714}
2715
2716static int stv090x_optimize_track(struct stv090x_state *state)
2717{
2718 struct dvb_frontend *fe = &state->frontend;
2719
2720 enum stv090x_rolloff rolloff;
2721 enum stv090x_modcod modcod;
2722
2723 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
2724 u32 reg;
2725
2726 srate = stv090x_get_srate(state, state->mclk);
2727 srate += stv090x_get_tmgoffst(state, srate);
2728
2729 switch (state->delsys) {
2730 case STV090x_DVBS1:
2731 case STV090x_DSS:
2732 if (state->algo == STV090x_SEARCH_AUTO) {
2733 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2734 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2735 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
2736 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2737 goto err;
2738 }
2739 reg = STV090x_READ_DEMOD(state, DEMOD);
2740 STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
2741 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01);
2742 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
2743 goto err;
2744
2745 if (state->dev_ver >= 0x30) {
2746 if (stv090x_get_viterbi(state) < 0)
2747 goto err;
2748
2749 if (state->fec == STV090x_PR12) {
2750 if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0)
2751 goto err;
2752 if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
2753 goto err;
2754 } else {
2755 if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0)
2756 goto err;
2757 if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
2758 goto err;
2759 }
2760 }
2761
2762 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
2763 goto err;
2764 break;
2765
2766 case STV090x_DVBS2:
2767 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2768 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
2769 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2770 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2771 goto err;
2772 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
2773 goto err;
2774 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
2775 goto err;
2776 if (state->frame_len == STV090x_LONG_FRAME) {
2777 reg = STV090x_READ_DEMOD(state, DMDMODCOD);
2778 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
2779 pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
2780 aclc = stv090x_optimize_carloop(state, modcod, pilots);
2781 if (modcod <= STV090x_QPSK_910) {
2782 STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc);
2783 } else if (modcod <= STV090x_8PSK_910) {
2784 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2785 goto err;
2786 if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
2787 goto err;
2788 }
2789 if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) {
2790 if (modcod <= STV090x_16APSK_910) {
2791 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2792 goto err;
2793 if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
2794 goto err;
2795 } else {
2796 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2797 goto err;
2798 if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
2799 goto err;
2800 }
2801 }
2802 } else {
2803 /*Carrier loop setting for short frame*/
2804 aclc = stv090x_optimize_carloop_short(state);
2805 if (state->modulation == STV090x_QPSK) {
2806 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0)
2807 goto err;
2808 } else if (state->modulation == STV090x_8PSK) {
2809 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2810 goto err;
2811 if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
2812 goto err;
2813 } else if (state->modulation == STV090x_16APSK) {
2814 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2815 goto err;
2816 if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
2817 goto err;
2818 } else if (state->modulation == STV090x_32APSK) {
2819 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2820 goto err;
2821 if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
2822 goto err;
2823 }
2824 }
2825
2826 STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
2827 break;
2828
2829 case STV090x_UNKNOWN:
2830 default:
2831 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2832 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2833 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2834 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2835 goto err;
2836 break;
2837 }
2838
2839 f_1 = STV090x_READ_DEMOD(state, CFR2);
2840 f_0 = STV090x_READ_DEMOD(state, CFR1);
2841 reg = STV090x_READ_DEMOD(state, TMGOBS);
2842 rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
2843
2844 if (state->algo == STV090x_BLIND_SEARCH) {
2845 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);
2846 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2847 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00);
2848 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
2849 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2850 goto err;
2851 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
2852 goto err;
2853
2854 if (stv090x_set_srate(state, srate) < 0)
2855 goto err;
2856 blind_tune = 1;
2857 }
2858
2859 if (state->dev_ver >= 0x20) {
2860 if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
2861 (state->search_mode == STV090x_SEARCH_DSS) ||
2862 (state->search_mode == STV090x_SEARCH_AUTO)) {
2863
2864 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0)
2865 goto err;
2866 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0)
2867 goto err;
2868 }
2869 }
2870
2871 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
2872 goto err;
2873
2874 /* AUTO tracking MODE */
2875 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0)
2876 goto err;
2877 /* AUTO tracking MODE */
2878 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
2879 goto err;
2880
2881 if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) {
2882 /* update initial carrier freq with the found freq offset */
2883 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
2884 goto err;
2885 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
2886 goto err;
2887 state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
2888
2889 if ((state->dev_ver >= 0x20) || (blind_tune == 1)) {
2890
2891 if (state->algo != STV090x_WARM_SEARCH) {
2892
2893 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
2894 goto err;
2895
2896 if (state->config->tuner_set_bandwidth) {
2897 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
2898 goto err;
2899 }
2900
2901 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
2902 goto err;
2903
2904 }
2905 }
2906 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000))
2907 msleep(50); /* blind search: wait 50ms for SR stabilization */
2908 else
2909 msleep(5);
2910
2911 stv090x_get_lock_tmg(state);
2912
2913 if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) {
2914 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
2915 goto err;
2916 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
2917 goto err;
2918 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
2919 goto err;
2920 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
2921 goto err;
2922
2923 i = 0;
2924
2925 while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) {
2926
2927 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
2928 goto err;
2929 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
2930 goto err;
2931 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
2932 goto err;
2933 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
2934 goto err;
2935 i++;
2936 }
2937 }
2938
2939 }
2940
2941 if (state->dev_ver >= 0x20) {
2942 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
2943 goto err;
2944 }
2945
2946 if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS))
2947 stv090x_set_vit_thtracq(state);
2948
2949 return 0;
2950err:
2951 dprintk(FE_ERROR, 1, "I/O error");
2952 return -1;
2953}
2954
2955static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout)
2956{
2957 s32 timer = 0, lock = 0, stat;
2958 u32 reg;
2959
2960 while ((timer < timeout) && (!lock)) {
2961 reg = STV090x_READ_DEMOD(state, DMDSTATE);
2962 stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
2963
2964 switch (stat) {
2965 case 0: /* searching */
2966 case 1: /* first PLH detected */
2967 default:
2968 lock = 0;
2969 break;
2970
2971 case 2: /* DVB-S2 mode */
2972 reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
2973 lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD);
2974 break;
2975
2976 case 3: /* DVB-S1/legacy mode */
2977 reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
2978 lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD);
2979 break;
2980 }
2981 if (!lock) {
2982 msleep(10);
2983 timer += 10;
2984 }
2985 }
2986 return lock;
2987}
2988
2989static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec)
2990{
2991 u32 reg;
2992 s32 timer = 0;
2993 int lock;
2994
2995 lock = stv090x_get_dmdlock(state, timeout_dmd);
2996 if (lock)
2997 lock = stv090x_get_feclock(state, timeout_fec);
2998
2999 if (lock) {
3000 lock = 0;
3001
3002 while ((timer < timeout_fec) && (!lock)) {
3003 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3004 lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD);
3005 msleep(1);
3006 timer++;
3007 }
3008 }
3009
3010 return lock;
3011}
3012
3013static int stv090x_set_s2rolloff(struct stv090x_state *state)
3014{
3015 u32 reg;
3016
3017 if (state->dev_ver <= 0x20) {
3018 /* rolloff to auto mode if DVBS2 */
3019 reg = STV090x_READ_DEMOD(state, DEMOD);
3020 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
3021 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
3022 goto err;
3023 } else {
3024 /* DVB-S2 rolloff to auto mode if DVBS2 */
3025 reg = STV090x_READ_DEMOD(state, DEMOD);
3026 STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00);
3027 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
3028 goto err;
3029 }
3030 return 0;
3031err:
3032 dprintk(FE_ERROR, 1, "I/O error");
3033 return -1;
3034}
3035
3036
3037static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3038{
3039 struct dvb_frontend *fe = &state->frontend;
3040 enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
3041 u32 reg;
3042 s32 timeout_dmd = 500, timeout_fec = 50, agc1_power, power_iq = 0, i;
3043 int lock = 0, low_sr = 0, no_signal = 0;
3044
3045 reg = STV090x_READ_DEMOD(state, TSCFGH);
3046 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */
3047 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3048 goto err;
3049
3050 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
3051 goto err;
3052
3053 if (state->dev_ver >= 0x20) {
3054 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) /* cut 2.0 */
3055 goto err;
3056 }
3057
3058 stv090x_get_lock_tmg(state);
3059
3060 if (state->algo == STV090x_BLIND_SEARCH) {
3061 state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */
3062 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */
3063 goto err;
3064 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
3065 goto err;
3066 if (stv090x_set_srate(state, 1000000) < 0) /* inital srate = 1Msps */
3067 goto err;
3068 } else {
3069 /* known srate */
3070 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
3071 goto err;
3072 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
3073 goto err;
3074
3075 if (state->srate < 2000000) {
3076 /* SR < 2MSPS */
3077 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0)
3078 goto err;
3079 } else {
3080 /* SR >= 2Msps */
3081 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
3082 goto err;
3083 }
3084
3085 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
3086 goto err;
3087
3088 if (state->dev_ver >= 0x20) {
3089 if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
3090 goto err;
3091 if (state->algo == STV090x_COLD_SEARCH)
3092 state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10;
3093 else if (state->algo == STV090x_WARM_SEARCH)
3094 state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000;
3095 }
3096
3097 /* if cold start or warm (Symbolrate is known)
3098 * use a Narrow symbol rate scan range
3099 */
3100 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */
3101 goto err;
3102
3103 if (stv090x_set_srate(state, state->srate) < 0)
3104 goto err;
3105
3106 if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0)
3107 goto err;
3108 if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0)
3109 goto err;
3110
3111 if (state->srate >= 10000000)
3112 low_sr = 0;
3113 else
3114 low_sr = 1;
3115 }
3116
3117 /* Setup tuner */
3118 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
3119 goto err;
3120
3121 if (state->config->tuner_set_bbgain) {
3122 if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */
3123 goto err;
3124 }
3125
3126 if (state->config->tuner_set_frequency) {
3127 if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
3128 goto err;
3129 }
3130
3131 if (state->config->tuner_set_bandwidth) {
3132 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
3133 goto err;
3134 }
3135
3136 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
3137 goto err;
3138
3139 msleep(50);
3140
3141 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
3142 goto err;
3143
3144 if (state->config->tuner_get_status) {
3145 if (state->config->tuner_get_status(fe, &reg) < 0)
3146 goto err;
3147 }
3148
3149 if (reg)
3150 dprintk(FE_DEBUG, 1, "Tuner phase locked");
3151 else
3152 dprintk(FE_DEBUG, 1, "Tuner unlocked");
3153
3154 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
3155 goto err;
3156
3157 msleep(10);
3158 agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
3159 STV090x_READ_DEMOD(state, AGCIQIN0));
3160
3161 if (agc1_power == 0) {
3162 /* If AGC1 integrator value is 0
3163 * then read POWERI, POWERQ
3164 */
3165 for (i = 0; i < 5; i++) {
3166 power_iq += (STV090x_READ_DEMOD(state, POWERI) +
3167 STV090x_READ_DEMOD(state, POWERQ)) >> 1;
3168 }
3169 power_iq /= 5;
3170 }
3171
3172 if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
3173 dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
3174 lock = 0;
3175
3176 } else {
3177 reg = STV090x_READ_DEMOD(state, DEMOD);
3178 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
3179
3180 if (state->dev_ver <= 0x20) {
3181 /* rolloff to auto mode if DVBS2 */
3182 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
3183 } else {
3184 /* DVB-S2 rolloff to auto mode if DVBS2 */
3185 STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1);
3186 }
3187 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
3188 goto err;
3189
3190 if (stv090x_delivery_search(state) < 0)
3191 goto err;
3192
3193 if (state->algo != STV090x_BLIND_SEARCH) {
3194 if (stv090x_start_search(state) < 0)
3195 goto err;
3196 }
3197 }
3198
3199 /* need to check for AGC1 state */
3200
3201
3202
3203 if (state->algo == STV090x_BLIND_SEARCH)
3204 lock = stv090x_blind_search(state);
3205
3206 else if (state->algo == STV090x_COLD_SEARCH)
3207 lock = stv090x_get_coldlock(state, timeout_dmd);
3208
3209 else if (state->algo == STV090x_WARM_SEARCH)
3210 lock = stv090x_get_dmdlock(state, timeout_dmd);
3211
3212 if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
3213 if (!low_sr) {
3214 if (stv090x_chk_tmg(state))
3215 lock = stv090x_sw_algo(state);
3216 }
3217 }
3218
3219 if (lock)
3220 signal_state = stv090x_get_sig_params(state);
3221
3222 if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
3223 stv090x_optimize_track(state);
3224
3225 if (state->dev_ver >= 0x20) {
3226 /* >= Cut 2.0 :release TS reset after
3227 * demod lock and optimized Tracking
3228 */
3229 reg = STV090x_READ_DEMOD(state, TSCFGH);
3230 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
3231 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3232 goto err;
3233
3234 msleep(3);
3235
3236 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */
3237 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3238 goto err;
3239
3240 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
3241 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3242 goto err;
3243 }
3244
3245 if (stv090x_get_lock(state, timeout_fec, timeout_fec)) {
3246 lock = 1;
3247 if (state->delsys == STV090x_DVBS2) {
3248 stv090x_set_s2rolloff(state);
3249
3250 reg = STV090x_READ_DEMOD(state, PDELCTRL2);
3251 STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1);
3252 if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
3253 goto err;
3254 /* Reset DVBS2 packet delinator error counter */
3255 reg = STV090x_READ_DEMOD(state, PDELCTRL2);
3256 STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0);
3257 if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
3258 goto err;
3259
3260 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */
3261 goto err;
3262 } else {
3263 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
3264 goto err;
3265 }
3266 /* Reset the Total packet counter */
3267 if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0)
3268 goto err;
3269 /* Reset the packet Error counter2 */
3270 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
3271 goto err;
3272 } else {
3273 lock = 0;
3274 signal_state = STV090x_NODATA;
3275 no_signal = stv090x_chk_signal(state);
3276 }
3277 }
3278 return signal_state;
3279
3280err:
3281 dprintk(FE_ERROR, 1, "I/O error");
3282 return -1;
3283}
3284
3285static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
3286{
3287 struct stv090x_state *state = fe->demodulator_priv;
3288 struct dtv_frontend_properties *props = &fe->dtv_property_cache;
3289
3290 state->delsys = props->delivery_system;
3291 state->frequency = p->frequency;
3292 state->srate = p->u.qpsk.symbol_rate;
3293 state->search_mode = STV090x_SEARCH_AUTO;
3294 state->algo = STV090x_COLD_SEARCH;
3295 state->fec = STV090x_PRERR;
3296 state->search_range = 2000000;
3297
3298 if (stv090x_algo(state) == STV090x_RANGEOK) {
3299 dprintk(FE_DEBUG, 1, "Search success!");
3300 return DVBFE_ALGO_SEARCH_SUCCESS;
3301 } else {
3302 dprintk(FE_DEBUG, 1, "Search failed!");
3303 return DVBFE_ALGO_SEARCH_FAILED;
3304 }
3305
3306 return DVBFE_ALGO_SEARCH_ERROR;
3307}
3308
3309/* FIXME! */
3310static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
3311{
3312 struct stv090x_state *state = fe->demodulator_priv;
3313 u32 reg;
3314 u8 search_state;
3315
3316 reg = STV090x_READ_DEMOD(state, DMDSTATE);
3317 search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
3318
3319 switch (search_state) {
3320 case 0: /* searching */
3321 case 1: /* first PLH detected */
3322 default:
3323 dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
3324 *status = 0;
3325 break;
3326
3327 case 2: /* DVB-S2 mode */
3328 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
3329 reg = STV090x_READ_DEMOD(state, DSTATUS);
3330 if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
3331 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3332 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3333 *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
3334 }
3335 }
3336 break;
3337
3338 case 3: /* DVB-S1/legacy mode */
3339 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
3340 reg = STV090x_READ_DEMOD(state, DSTATUS);
3341 if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
3342 reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
3343 if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
3344 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3345 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3346 *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
3347 }
3348 }
3349 }
3350 break;
3351 }
3352
3353 return 0;
3354}
3355
3356static int stv090x_read_per(struct dvb_frontend *fe, u32 *per)
3357{
3358 struct stv090x_state *state = fe->demodulator_priv;
3359
3360 s32 count_4, count_3, count_2, count_1, count_0, count;
3361 u32 reg, h, m, l;
3362 enum fe_status status;
3363
3364 stv090x_read_status(fe, &status);
3365 if (!(status & FE_HAS_LOCK)) {
3366 *per = 1 << 23; /* Max PER */
3367 } else {
3368 /* Counter 2 */
3369 reg = STV090x_READ_DEMOD(state, ERRCNT22);
3370 h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD);
3371
3372 reg = STV090x_READ_DEMOD(state, ERRCNT21);
3373 m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD);
3374
3375 reg = STV090x_READ_DEMOD(state, ERRCNT20);
3376 l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD);
3377
3378 *per = ((h << 16) | (m << 8) | l);
3379
3380 count_4 = STV090x_READ_DEMOD(state, FBERCPT4);
3381 count_3 = STV090x_READ_DEMOD(state, FBERCPT3);
3382 count_2 = STV090x_READ_DEMOD(state, FBERCPT2);
3383 count_1 = STV090x_READ_DEMOD(state, FBERCPT1);
3384 count_0 = STV090x_READ_DEMOD(state, FBERCPT0);
3385
3386 if ((!count_4) && (!count_3)) {
3387 count = (count_2 & 0xff) << 16;
3388 count |= (count_1 & 0xff) << 8;
3389 count |= count_0 & 0xff;
3390 } else {
3391 count = 1 << 24;
3392 }
3393 if (count == 0)
3394 *per = 1;
3395 }
3396 if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0)
3397 goto err;
3398 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
3399 goto err;
3400
3401 return 0;
3402err:
3403 dprintk(FE_ERROR, 1, "I/O error");
3404 return -1;
3405}
3406
3407static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
3408{
3409 int res = 0;
3410 int min = 0, med;
3411
3412 if (val < tab[min].read)
3413 res = tab[min].real;
3414 else if (val >= tab[max].read)
3415 res = tab[max].real;
3416 else {
3417 while ((max - min) > 1) {
3418 med = (max + min) / 2;
3419 if (val >= tab[min].read && val < tab[med].read)
3420 max = med;
3421 else
3422 min = med;
3423 }
3424 res = ((val - tab[min].read) *
3425 (tab[max].real - tab[min].real) /
3426 (tab[max].read - tab[min].read)) +
3427 tab[min].real;
3428 }
3429
3430 return res;
3431}
3432
3433static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
3434{
3435 struct stv090x_state *state = fe->demodulator_priv;
3436 u32 reg;
3437 s32 agc;
3438
3439 reg = STV090x_READ_DEMOD(state, AGCIQIN1);
3440 agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
3441
3442 *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
3443 if (agc > stv090x_rf_tab[0].read)
3444 *strength = 5;
3445 else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
3446 *strength = -100;
3447
3448 return 0;
3449}
3450
3451static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
3452{
3453 struct stv090x_state *state = fe->demodulator_priv;
3454 u32 reg_0, reg_1, reg, i;
3455 s32 val_0, val_1, val = 0;
3456 u8 lock_f;
3457
3458 switch (state->delsys) {
3459 case STV090x_DVBS2:
3460 reg = STV090x_READ_DEMOD(state, DSTATUS);
3461 lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
3462 if (lock_f) {
3463 msleep(5);
3464 for (i = 0; i < 16; i++) {
3465 reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
3466 val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
3467 reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
3468 val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
3469 val += MAKEWORD16(val_1, val_0);
3470 msleep(1);
3471 }
3472 val /= 16;
3473 *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
3474 if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read)
3475 *cnr = 1000;
3476 }
3477 break;
3478
3479 case STV090x_DVBS1:
3480 case STV090x_DSS:
3481 reg = STV090x_READ_DEMOD(state, DSTATUS);
3482 lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
3483 if (lock_f) {
3484 msleep(5);
3485 for (i = 0; i < 16; i++) {
3486 reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
3487 val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
3488 reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
3489 val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
3490 val += MAKEWORD16(val_1, val_0);
3491 msleep(1);
3492 }
3493 val /= 16;
3494 *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
3495 if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read)
3496 *cnr = 1000;
3497 }
3498 break;
3499 default:
3500 break;
3501 }
3502
3503 return 0;
3504}
3505
3506static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
3507{
3508 struct stv090x_state *state = fe->demodulator_priv;
3509 u32 reg;
3510
3511 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3512 switch (tone) {
3513 case SEC_TONE_ON:
3514 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
3515 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3516 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3517 goto err;
3518 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
3519 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3520 goto err;
3521 break;
3522
3523 case SEC_TONE_OFF:
3524 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
3525 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3526 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3527 goto err;
3528 break;
3529 default:
3530 return -EINVAL;
3531 }
3532
3533 return 0;
3534err:
3535 dprintk(FE_ERROR, 1, "I/O error");
3536 return -1;
3537}
3538
3539
3540static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe)
3541{
3542 return DVBFE_ALGO_CUSTOM;
3543}
3544
3545static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
3546{
3547 struct stv090x_state *state = fe->demodulator_priv;
3548 u32 reg, idle = 0, fifo_full = 1;
3549 int i;
3550
3551 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3552
3553 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2);
3554 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3555 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3556 goto err;
3557 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
3558 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3559 goto err;
3560
3561 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
3562 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3563 goto err;
3564
3565 for (i = 0; i < cmd->msg_len; i++) {
3566
3567 while (fifo_full) {
3568 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3569 fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
3570 }
3571
3572 if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0)
3573 goto err;
3574 }
3575 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3576 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
3577 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3578 goto err;
3579
3580 i = 0;
3581
3582 while ((!idle) && (i < 10)) {
3583 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3584 idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
3585 msleep(10);
3586 i++;
3587 }
3588
3589 return 0;
3590err:
3591 dprintk(FE_ERROR, 1, "I/O error");
3592 return -1;
3593}
3594
3595static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
3596{
3597 struct stv090x_state *state = fe->demodulator_priv;
3598 u32 reg, idle = 0, fifo_full = 1;
3599 u8 mode, value;
3600 int i;
3601
3602 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3603
3604 if (burst == SEC_MINI_A) {
3605 mode = 3;
3606 value = 0x00;
3607 } else {
3608 mode = 2;
3609 value = 0xFF;
3610 }
3611
3612 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode);
3613 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3614 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3615 goto err;
3616 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
3617 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3618 goto err;
3619
3620 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
3621 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3622 goto err;
3623
3624 while (fifo_full) {
3625 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3626 fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
3627 }
3628
3629 if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0)
3630 goto err;
3631
3632 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3633 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
3634 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3635 goto err;
3636
3637 i = 0;
3638
3639 while ((!idle) && (i < 10)) {
3640 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3641 idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
3642 msleep(10);
3643 i++;
3644 }
3645
3646 return 0;
3647err:
3648 dprintk(FE_ERROR, 1, "I/O error");
3649 return -1;
3650}
3651
3652static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
3653{
3654 struct stv090x_state *state = fe->demodulator_priv;
3655 u32 reg = 0, i = 0, rx_end = 0;
3656
3657 while ((rx_end != 1) && (i < 10)) {
3658 msleep(10);
3659 i++;
3660 reg = STV090x_READ_DEMOD(state, DISRX_ST0);
3661 rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD);
3662 }
3663
3664 if (rx_end) {
3665 reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD);
3666 for (i = 0; i < reply->msg_len; i++)
3667 reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA);
3668 }
3669
3670 return 0;
3671}
3672
3673static int stv090x_sleep(struct dvb_frontend *fe)
3674{
3675 struct stv090x_state *state = fe->demodulator_priv;
3676 u32 reg;
3677
3678 dprintk(FE_DEBUG, 1, "Set %s to sleep",
3679 state->device == STV0900 ? "STV0900" : "STV0903");
3680
3681 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3682 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3683 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3684 goto err;
3685
3686 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3687 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
3688 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3689 goto err;
3690
3691 return 0;
3692err:
3693 dprintk(FE_ERROR, 1, "I/O error");
3694 return -1;
3695}
3696
3697static int stv090x_wakeup(struct dvb_frontend *fe)
3698{
3699 struct stv090x_state *state = fe->demodulator_priv;
3700 u32 reg;
3701
3702 dprintk(FE_DEBUG, 1, "Wake %s from standby",
3703 state->device == STV0900 ? "STV0900" : "STV0903");
3704
3705 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3706 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
3707 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3708 goto err;
3709
3710 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3711 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
3712 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3713 goto err;
3714
3715 return 0;
3716err:
3717 dprintk(FE_ERROR, 1, "I/O error");
3718 return -1;
3719}
3720
3721static void stv090x_release(struct dvb_frontend *fe)
3722{
3723 struct stv090x_state *state = fe->demodulator_priv;
3724
3725 kfree(state);
3726}
3727
3728static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode)
3729{
3730 u32 reg = 0;
3731
3732 switch (ldpc_mode) {
3733 case STV090x_DUAL:
3734 default:
3735 if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) {
3736 /* set LDPC to dual mode */
3737 if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0)
3738 goto err;
3739
3740 state->demod_mode = STV090x_DUAL;
3741
3742 reg = stv090x_read_reg(state, STV090x_TSTRES0);
3743 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
3744 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
3745 goto err;
3746 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
3747 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
3748 goto err;
3749
3750 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
3751 goto err;
3752 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
3753 goto err;
3754 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
3755 goto err;
3756 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
3757 goto err;
3758 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
3759 goto err;
3760 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
3761 goto err;
3762 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
3763 goto err;
3764
3765 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
3766 goto err;
3767 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
3768 goto err;
3769 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
3770 goto err;
3771 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
3772 goto err;
3773 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
3774 goto err;
3775 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
3776 goto err;
3777 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
3778 goto err;
3779
3780 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
3781 goto err;
3782 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
3783 goto err;
3784 }
3785 break;
3786
3787 case STV090x_SINGLE:
3788 if (stv090x_stop_modcod(state) < 0)
3789 goto err;
3790 if (stv090x_activate_modcod_single(state) < 0)
3791 goto err;
3792
3793 if (state->demod == STV090x_DEMODULATOR_1) {
3794 if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */
3795 goto err;
3796 } else {
3797 if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */
3798 goto err;
3799 }
3800
3801 reg = stv090x_read_reg(state, STV090x_TSTRES0);
3802 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
3803 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
3804 goto err;
3805 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
3806 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
3807 goto err;
3808
3809 reg = STV090x_READ_DEMOD(state, PDELCTRL1);
3810 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01);
3811 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
3812 goto err;
3813 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00);
3814 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
3815 goto err;
3816 break;
3817 }
3818
3819 return 0;
3820err:
3821 dprintk(FE_ERROR, 1, "I/O error");
3822 return -1;
3823}
3824
3825/* return (Hz), clk in Hz*/
3826static u32 stv090x_get_mclk(struct stv090x_state *state)
3827{
3828 const struct stv090x_config *config = state->config;
3829 u32 div, reg;
3830 u8 ratio;
3831
3832 div = stv090x_read_reg(state, STV090x_NCOARSE);
3833 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3834 ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6;
3835
3836 return (div + 1) * config->xtal / ratio; /* kHz */
3837}
3838
3839static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
3840{
3841 const struct stv090x_config *config = state->config;
3842 u32 reg, div, clk_sel;
3843
3844 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3845 clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6);
3846
3847 div = ((clk_sel * mclk) / config->xtal) - 1;
3848
3849 reg = stv090x_read_reg(state, STV090x_NCOARSE);
3850 STV090x_SETFIELD(reg, M_DIV_FIELD, div);
3851 if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
3852 goto err;
3853
3854 state->mclk = stv090x_get_mclk(state);
3855
3856 /*Set the DiseqC frequency to 22KHz */
3857 div = state->mclk / 704000;
3858 if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
3859 goto err;
3860 if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
3861 goto err;
3862
3863 return 0;
3864err:
3865 dprintk(FE_ERROR, 1, "I/O error");
3866 return -1;
3867}
3868
3869static int stv090x_set_tspath(struct stv090x_state *state)
3870{
3871 u32 reg;
3872
3873 if (state->dev_ver >= 0x20) {
3874 switch (state->config->ts1_mode) {
3875 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3876 case STV090x_TSMODE_DVBCI:
3877 switch (state->config->ts2_mode) {
3878 case STV090x_TSMODE_SERIAL_PUNCTURED:
3879 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3880 default:
3881 stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
3882 break;
3883
3884 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3885 case STV090x_TSMODE_DVBCI:
3886 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */
3887 goto err;
3888 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
3889 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
3890 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
3891 goto err;
3892 reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
3893 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
3894 if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
3895 goto err;
3896 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
3897 goto err;
3898 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
3899 goto err;
3900 break;
3901 }
3902 break;
3903
3904 case STV090x_TSMODE_SERIAL_PUNCTURED:
3905 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3906 default:
3907 switch (state->config->ts2_mode) {
3908 case STV090x_TSMODE_SERIAL_PUNCTURED:
3909 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3910 default:
3911 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
3912 goto err;
3913 break;
3914
3915 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3916 case STV090x_TSMODE_DVBCI:
3917 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0)
3918 goto err;
3919 break;
3920 }
3921 break;
3922 }
3923 } else {
3924 switch (state->config->ts1_mode) {
3925 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3926 case STV090x_TSMODE_DVBCI:
3927 switch (state->config->ts2_mode) {
3928 case STV090x_TSMODE_SERIAL_PUNCTURED:
3929 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3930 default:
3931 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
3932 break;
3933
3934 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3935 case STV090x_TSMODE_DVBCI:
3936 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16);
3937 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
3938 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
3939 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
3940 goto err;
3941 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
3942 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0);
3943 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
3944 goto err;
3945 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
3946 goto err;
3947 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
3948 goto err;
3949 break;
3950 }
3951 break;
3952
3953 case STV090x_TSMODE_SERIAL_PUNCTURED:
3954 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3955 default:
3956 switch (state->config->ts2_mode) {
3957 case STV090x_TSMODE_SERIAL_PUNCTURED:
3958 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3959 default:
3960 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
3961 break;
3962
3963 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3964 case STV090x_TSMODE_DVBCI:
3965 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12);
3966 break;
3967 }
3968 break;
3969 }
3970 }
3971
3972 switch (state->config->ts1_mode) {
3973 case STV090x_TSMODE_PARALLEL_PUNCTURED:
3974 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
3975 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
3976 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
3977 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
3978 goto err;
3979 break;
3980
3981 case STV090x_TSMODE_DVBCI:
3982 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
3983 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
3984 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
3985 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
3986 goto err;
3987 break;
3988
3989 case STV090x_TSMODE_SERIAL_PUNCTURED:
3990 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
3991 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
3992 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
3993 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
3994 goto err;
3995 break;
3996
3997 case STV090x_TSMODE_SERIAL_CONTINUOUS:
3998 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
3999 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4000 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4001 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4002 goto err;
4003 break;
4004
4005 default:
4006 break;
4007 }
4008
4009 switch (state->config->ts2_mode) {
4010 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4011 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4012 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4013 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4014 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4015 goto err;
4016 break;
4017
4018 case STV090x_TSMODE_DVBCI:
4019 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4020 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4021 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4022 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4023 goto err;
4024 break;
4025
4026 case STV090x_TSMODE_SERIAL_PUNCTURED:
4027 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4028 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4029 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4030 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4031 goto err;
4032 break;
4033
4034 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4035 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4036 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4037 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4038 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4039 goto err;
4040 break;
4041
4042 default:
4043 break;
4044 }
4045 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4046 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
4047 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4048 goto err;
4049 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
4050 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4051 goto err;
4052
4053 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4054 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
4055 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4056 goto err;
4057 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
4058 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4059 goto err;
4060
4061 return 0;
4062err:
4063 dprintk(FE_ERROR, 1, "I/O error");
4064 return -1;
4065}
4066
4067static int stv090x_init(struct dvb_frontend *fe)
4068{
4069 struct stv090x_state *state = fe->demodulator_priv;
4070 const struct stv090x_config *config = state->config;
4071 u32 reg;
4072
4073 if (stv090x_wakeup(fe) < 0) {
4074 dprintk(FE_ERROR, 1, "Error waking device");
4075 goto err;
4076 }
4077
4078 if (stv090x_ldpc_mode(state, state->demod_mode) < 0)
4079 goto err;
4080
4081 reg = STV090x_READ_DEMOD(state, TNRCFG2);
4082 STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion);
4083 if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0)
4084 goto err;
4085 reg = STV090x_READ_DEMOD(state, DEMOD);
4086 STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
4087 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
4088 goto err;
4089
4090 if (stv090x_i2c_gate_ctrl(fe, 1) < 0)
4091 goto err;
4092
4093 if (config->tuner_set_mode) {
4094 if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
4095 goto err;
4096 }
4097
4098 if (config->tuner_init) {
4099 if (config->tuner_init(fe) < 0)
4100 goto err;
4101 }
4102
4103 if (stv090x_i2c_gate_ctrl(fe, 0) < 0)
4104 goto err;
4105
4106 if (stv090x_set_tspath(state) < 0)
4107 goto err;
4108
4109 return 0;
4110err:
4111 dprintk(FE_ERROR, 1, "I/O error");
4112 return -1;
4113}
4114
4115static int stv090x_setup(struct dvb_frontend *fe)
4116{
4117 struct stv090x_state *state = fe->demodulator_priv;
4118 const struct stv090x_config *config = state->config;
4119 const struct stv090x_reg *stv090x_initval = NULL;
4120 const struct stv090x_reg *stv090x_cut20_val = NULL;
4121 unsigned long t1_size = 0, t2_size = 0;
4122 u32 reg = 0;
4123
4124 int i;
4125
4126 if (state->device == STV0900) {
4127 dprintk(FE_DEBUG, 1, "Initializing STV0900");
4128 stv090x_initval = stv0900_initval;
4129 t1_size = ARRAY_SIZE(stv0900_initval);
4130 stv090x_cut20_val = stv0900_cut20_val;
4131 t2_size = ARRAY_SIZE(stv0900_cut20_val);
4132 } else if (state->device == STV0903) {
4133 dprintk(FE_DEBUG, 1, "Initializing STV0903");
4134 stv090x_initval = stv0903_initval;
4135 t1_size = ARRAY_SIZE(stv0903_initval);
4136 stv090x_cut20_val = stv0903_cut20_val;
4137 t2_size = ARRAY_SIZE(stv0903_cut20_val);
4138 }
4139
4140 /* STV090x init */
4141 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */
4142 goto err;
4143
4144 msleep(5);
4145
4146 if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */
4147 goto err;
4148
4149 STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
4150 if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */
4151 goto err;
4152
4153 if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
4154 goto err;
4155 msleep(5);
4156 if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */
4157 goto err;
4158 if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */
4159 goto err;
4160 msleep(5);
4161
4162 /* write initval */
4163 dprintk(FE_DEBUG, 1, "Setting up initial values");
4164 for (i = 0; i < t1_size; i++) {
4165 if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0)
4166 goto err;
4167 }
4168
4169 state->dev_ver = stv090x_read_reg(state, STV090x_MID);
4170 if (state->dev_ver >= 0x20) {
4171 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
4172 goto err;
4173
4174 /* write cut20_val*/
4175 dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values");
4176 for (i = 0; i < t2_size; i++) {
4177 if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0)
4178 goto err;
4179 }
4180
4181 } else if (state->dev_ver < 0x20) {
4182 dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
4183 state->dev_ver);
4184
4185 goto err;
4186 } else if (state->dev_ver > 0x30) {
4187 /* we shouldn't bail out from here */
4188 dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
4189 state->dev_ver);
4190 }
4191
4192 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
4193 goto err;
4194 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
4195 goto err;
4196
4197 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
4198 msleep(5);
4199 if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0)
4200 goto err;
4201 stv090x_get_mclk(state);
4202
4203 return 0;
4204err:
4205 dprintk(FE_ERROR, 1, "I/O error");
4206 return -1;
4207}
4208
4209static struct dvb_frontend_ops stv090x_ops = {
4210
4211 .info = {
4212 .name = "STV090x Multistandard",
4213 .type = FE_QPSK,
4214 .frequency_min = 950000,
4215 .frequency_max = 2150000,
4216 .frequency_stepsize = 0,
4217 .frequency_tolerance = 0,
4218 .symbol_rate_min = 1000000,
4219 .symbol_rate_max = 45000000,
4220 .caps = FE_CAN_INVERSION_AUTO |
4221 FE_CAN_FEC_AUTO |
4222 FE_CAN_QPSK |
4223 FE_CAN_2G_MODULATION
4224 },
4225
4226 .release = stv090x_release,
4227 .init = stv090x_init,
4228
4229 .sleep = stv090x_sleep,
4230 .get_frontend_algo = stv090x_frontend_algo,
4231
4232 .i2c_gate_ctrl = stv090x_i2c_gate_ctrl,
4233
4234 .diseqc_send_master_cmd = stv090x_send_diseqc_msg,
4235 .diseqc_send_burst = stv090x_send_diseqc_burst,
4236 .diseqc_recv_slave_reply = stv090x_recv_slave_reply,
4237 .set_tone = stv090x_set_tone,
4238
4239 .search = stv090x_search,
4240 .read_status = stv090x_read_status,
4241 .read_ber = stv090x_read_per,
4242 .read_signal_strength = stv090x_read_signal_strength,
4243 .read_snr = stv090x_read_cnr
4244};
4245
4246
4247struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4248 struct i2c_adapter *i2c,
4249 enum stv090x_demodulator demod)
4250{
4251 struct stv090x_state *state = NULL;
4252
4253 state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
4254 if (state == NULL)
4255 goto error;
4256
4257 state->verbose = &verbose;
4258 state->config = config;
4259 state->i2c = i2c;
4260 state->frontend.ops = stv090x_ops;
4261 state->frontend.demodulator_priv = state;
4262 state->demod = demod;
4263 state->demod_mode = config->demod_mode; /* Single or Dual mode */
4264 state->device = config->device;
4265 state->rolloff = STV090x_RO_35; /* default */
4266
4267 if (state->demod == STV090x_DEMODULATOR_0)
4268 mutex_init(&demod_lock);
4269
4270 if (stv090x_sleep(&state->frontend) < 0) {
4271 dprintk(FE_ERROR, 1, "Error putting device to sleep");
4272 goto error;
4273 }
4274
4275 if (stv090x_setup(&state->frontend) < 0) {
4276 dprintk(FE_ERROR, 1, "Error setting up device");
4277 goto error;
4278 }
4279 if (stv090x_wakeup(&state->frontend) < 0) {
4280 dprintk(FE_ERROR, 1, "Error waking device");
4281 goto error;
4282 }
4283
4284 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n",
4285 state->device == STV0900 ? "STV0900" : "STV0903",
4286 demod,
4287 state->dev_ver);
4288
4289 return &state->frontend;
4290
4291error:
4292 kfree(state);
4293 return NULL;
4294}
4295EXPORT_SYMBOL(stv090x_attach);
4296MODULE_PARM_DESC(verbose, "Set Verbosity level");
4297MODULE_AUTHOR("Manu Abraham");
4298MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
4299MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
new file mode 100644
index 000000000000..e968c98bb70f
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -0,0 +1,106 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __STV090x_H
23#define __STV090x_H
24
25enum stv090x_demodulator {
26 STV090x_DEMODULATOR_0 = 1,
27 STV090x_DEMODULATOR_1
28};
29
30enum stv090x_device {
31 STV0903 = 0,
32 STV0900,
33};
34
35enum stv090x_mode {
36 STV090x_DUAL = 0,
37 STV090x_SINGLE
38};
39
40enum stv090x_tsmode {
41 STV090x_TSMODE_SERIAL_PUNCTURED = 1,
42 STV090x_TSMODE_SERIAL_CONTINUOUS,
43 STV090x_TSMODE_PARALLEL_PUNCTURED,
44 STV090x_TSMODE_DVBCI
45};
46
47enum stv090x_clkmode {
48 STV090x_CLK_INT = 0, /* Clk i/p = CLKI */
49 STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */
50};
51
52enum stv090x_i2crpt {
53 STV090x_RPTLEVEL_256 = 0,
54 STV090x_RPTLEVEL_128 = 1,
55 STV090x_RPTLEVEL_64 = 2,
56 STV090x_RPTLEVEL_32 = 3,
57 STV090x_RPTLEVEL_16 = 4,
58 STV090x_RPTLEVEL_8 = 5,
59 STV090x_RPTLEVEL_4 = 6,
60 STV090x_RPTLEVEL_2 = 7,
61};
62
63struct stv090x_config {
64 enum stv090x_device device;
65 enum stv090x_mode demod_mode;
66 enum stv090x_clkmode clk_mode;
67
68 u32 xtal; /* default: 8000000 */
69 u8 address; /* default: 0x68 */
70
71 u32 ref_clk; /* default: 16000000 FIXME to tuner config */
72
73 u8 ts1_mode;
74 u8 ts2_mode;
75
76 enum stv090x_i2crpt repeater_level;
77
78 int (*tuner_init) (struct dvb_frontend *fe);
79 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
80 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
81 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
82 int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
83 int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
84 int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
85 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
86 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
87 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
88};
89
90#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
91
92extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
93 struct i2c_adapter *i2c,
94 enum stv090x_demodulator demod);
95#else
96
97static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
98 struct i2c_adapter *i2c,
99 enum stv090x_demodulator demod)
100{
101 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
102 return NULL;
103}
104#endif /* CONFIG_DVB_STV090x */
105
106#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
new file mode 100644
index 000000000000..5a4a01740d88
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x_priv.h
@@ -0,0 +1,269 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __STV090x_PRIV_H
23#define __STV090x_PRIV_H
24
25#include "dvb_frontend.h"
26
27#define FE_ERROR 0
28#define FE_NOTICE 1
29#define FE_INFO 2
30#define FE_DEBUG 3
31#define FE_DEBUGREG 4
32
33#define dprintk(__y, __z, format, arg...) do { \
34 if (__z) { \
35 if ((verbose > FE_ERROR) && (verbose > __y)) \
36 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
37 else if ((verbose > FE_NOTICE) && (verbose > __y)) \
38 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
39 else if ((verbose > FE_INFO) && (verbose > __y)) \
40 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
41 else if ((verbose > FE_DEBUG) && (verbose > __y)) \
42 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
43 } else { \
44 if (verbose > __y) \
45 printk(format, ##arg); \
46 } \
47} while (0)
48
49#define STV090x_READ_DEMOD(__state, __reg) (( \
50 (__state)->demod == STV090x_DEMODULATOR_1) ? \
51 stv090x_read_reg(__state, STV090x_P2_##__reg) : \
52 stv090x_read_reg(__state, STV090x_P1_##__reg))
53
54#define STV090x_WRITE_DEMOD(__state, __reg, __data) (( \
55 (__state)->demod == STV090x_DEMODULATOR_1) ? \
56 stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\
57 stv090x_write_reg(__state, STV090x_P1_##__reg, __data))
58
59#define STV090x_ADDR_OFFST(__state, __x) (( \
60 (__state->demod) == STV090x_DEMODULATOR_1) ? \
61 STV090x_P1_##__x : \
62 STV090x_P2_##__x)
63
64
65#define STV090x_SETFIELD(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\
66 STV090x_OFFST_##bitf))) | \
67 (val << STV090x_OFFST_##bitf))
68
69#define STV090x_GETFIELD(val, bitf) ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1))
70
71
72#define STV090x_SETFIELD_Px(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\
73 STV090x_OFFST_Px_##bitf))) | \
74 (val << STV090x_OFFST_Px_##bitf))
75
76#define STV090x_GETFIELD_Px(val, bitf) ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1))
77
78#define MAKEWORD16(__a, __b) (((__a) << 8) | (__b))
79
80#define MSB(__x) ((__x >> 8) & 0xff)
81#define LSB(__x) (__x & 0xff)
82
83
84#define STV090x_IQPOWER_THRESHOLD 30
85#define STV090x_SEARCH_AGC2_TH_CUT20 700
86#define STV090x_SEARCH_AGC2_TH_CUT30 1200
87
88#define STV090x_SEARCH_AGC2_TH(__ver) \
89 ((__ver <= 0x20) ? \
90 STV090x_SEARCH_AGC2_TH_CUT20 : \
91 STV090x_SEARCH_AGC2_TH_CUT30)
92
93enum stv090x_signal_state {
94 STV090x_NOCARRIER,
95 STV090x_NODATA,
96 STV090x_DATAOK,
97 STV090x_RANGEOK,
98 STV090x_OUTOFRANGE
99};
100
101enum stv090x_fec {
102 STV090x_PR12 = 0,
103 STV090x_PR23,
104 STV090x_PR34,
105 STV090x_PR45,
106 STV090x_PR56,
107 STV090x_PR67,
108 STV090x_PR78,
109 STV090x_PR89,
110 STV090x_PR910,
111 STV090x_PRERR
112};
113
114enum stv090x_modulation {
115 STV090x_QPSK,
116 STV090x_8PSK,
117 STV090x_16APSK,
118 STV090x_32APSK,
119 STV090x_UNKNOWN
120};
121
122enum stv090x_frame {
123 STV090x_LONG_FRAME,
124 STV090x_SHORT_FRAME
125};
126
127enum stv090x_pilot {
128 STV090x_PILOTS_OFF,
129 STV090x_PILOTS_ON
130};
131
132enum stv090x_rolloff {
133 STV090x_RO_35,
134 STV090x_RO_25,
135 STV090x_RO_20
136};
137
138enum stv090x_inversion {
139 STV090x_IQ_AUTO,
140 STV090x_IQ_NORMAL,
141 STV090x_IQ_SWAP
142};
143
144enum stv090x_modcod {
145 STV090x_DUMMY_PLF = 0,
146 STV090x_QPSK_14,
147 STV090x_QPSK_13,
148 STV090x_QPSK_25,
149 STV090x_QPSK_12,
150 STV090x_QPSK_35,
151 STV090x_QPSK_23,
152 STV090x_QPSK_34,
153 STV090x_QPSK_45,
154 STV090x_QPSK_56,
155 STV090x_QPSK_89,
156 STV090x_QPSK_910,
157 STV090x_8PSK_35,
158 STV090x_8PSK_23,
159 STV090x_8PSK_34,
160 STV090x_8PSK_56,
161 STV090x_8PSK_89,
162 STV090x_8PSK_910,
163 STV090x_16APSK_23,
164 STV090x_16APSK_34,
165 STV090x_16APSK_45,
166 STV090x_16APSK_56,
167 STV090x_16APSK_89,
168 STV090x_16APSK_910,
169 STV090x_32APSK_34,
170 STV090x_32APSK_45,
171 STV090x_32APSK_56,
172 STV090x_32APSK_89,
173 STV090x_32APSK_910,
174 STV090x_MODCODE_UNKNOWN
175};
176
177enum stv090x_search {
178 STV090x_SEARCH_DSS = 0,
179 STV090x_SEARCH_DVBS1,
180 STV090x_SEARCH_DVBS2,
181 STV090x_SEARCH_AUTO
182};
183
184enum stv090x_algo {
185 STV090x_BLIND_SEARCH,
186 STV090x_COLD_SEARCH,
187 STV090x_WARM_SEARCH
188};
189
190enum stv090x_delsys {
191 STV090x_ERROR = 0,
192 STV090x_DVBS1 = 1,
193 STV090x_DVBS2,
194 STV090x_DSS
195};
196
197struct stv090x_long_frame_crloop {
198 enum stv090x_modcod modcod;
199
200 u8 crl_pilots_on_2;
201 u8 crl_pilots_off_2;
202 u8 crl_pilots_on_5;
203 u8 crl_pilots_off_5;
204 u8 crl_pilots_on_10;
205 u8 crl_pilots_off_10;
206 u8 crl_pilots_on_20;
207 u8 crl_pilots_off_20;
208 u8 crl_pilots_on_30;
209 u8 crl_pilots_off_30;
210};
211
212struct stv090x_short_frame_crloop {
213 enum stv090x_modulation modulation;
214
215 u8 crl_2; /* SR < 3M */
216 u8 crl_5; /* 3 < SR <= 7M */
217 u8 crl_10; /* 7 < SR <= 15M */
218 u8 crl_20; /* 10 < SR <= 25M */
219 u8 crl_30; /* 10 < SR <= 45M */
220};
221
222struct stv090x_reg {
223 u16 addr;
224 u8 data;
225};
226
227struct stv090x_tab {
228 s32 real;
229 s32 read;
230};
231
232struct stv090x_state {
233 enum stv090x_device device;
234 enum stv090x_demodulator demod;
235 enum stv090x_mode demod_mode;
236 u32 dev_ver;
237
238 struct i2c_adapter *i2c;
239 const struct stv090x_config *config;
240 struct dvb_frontend frontend;
241
242 u32 *verbose; /* Cached module verbosity */
243
244 enum stv090x_delsys delsys;
245 enum stv090x_fec fec;
246 enum stv090x_modulation modulation;
247 enum stv090x_modcod modcod;
248 enum stv090x_search search_mode;
249 enum stv090x_frame frame_len;
250 enum stv090x_pilot pilots;
251 enum stv090x_rolloff rolloff;
252 enum stv090x_inversion inversion;
253 enum stv090x_algo algo;
254
255 u32 frequency;
256 u32 srate;
257
258 s32 mclk; /* Masterclock Divider factor */
259 s32 tuner_bw;
260
261 u32 tuner_refclk;
262
263 s32 search_range;
264
265 s32 DemodTimeout;
266 s32 FecTimeout;
267};
268
269#endif /* __STV090x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
new file mode 100644
index 000000000000..57b6abbbd32d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -0,0 +1,2373 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef __STV090x_REG_H
23#define __STV090x_REG_H
24
25#define STV090x_MID 0xf100
26#define STV090x_OFFST_MCHIP_IDENT_FIELD 4
27#define STV090x_WIDTH_MCHIP_IDENT_FIELD 4
28#define STV090x_OFFST_MRELEASE_FIELD 0
29#define STV090x_WIDTH_MRELEASE_FIELD 4
30
31#define STV090x_DACR1 0xf113
32#define STV090x_OFFST_DACR1_MODE_FIELD 5
33#define STV090x_WIDTH_DACR1_MODE_FIELD 3
34#define STV090x_OFFST_DACR1_VALUE_FIELD 0
35#define STV090x_WIDTH_DACR1_VALUE_FIELD 4
36
37#define STV090x_DACR2 0xf114
38#define STV090x_OFFST_DACR2_VALUE_FIELD 0
39#define STV090x_WIDTH_DACR2_VALUE_FIELD 8
40
41#define STV090x_OUTCFG 0xf11c
42#define STV090x_OFFST_OUTSERRS1_HZ_FIELD 6
43#define STV090x_WIDTH_OUTSERRS1_HZ_FIELD 1
44#define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5
45#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1
46#define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4
47#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1
48#define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3
49#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1
50
51#define STV090x_MODECFG 0xf11d
52
53#define STV090x_IRQSTATUS3 0xf120
54#define STV090x_OFFST_SPLL_LOCK_FIELD 5
55#define STV090x_WIDTH_SPLL_LOCK_FIELD 1
56#define STV090x_OFFST_SSTREAM_LCK_3_FIELD 4
57#define STV090x_WIDTH_SSTREAM_LCK_3_FIELD 1
58#define STV090x_OFFST_SSTREAM_LCK_2_FIELD 3
59#define STV090x_WIDTH_SSTREAM_LCK_2_FIELD 1
60#define STV090x_OFFST_SSTREAM_LCK_1_FIELD 2
61#define STV090x_WIDTH_SSTREAM_LCK_1_FIELD 1
62#define STV090x_OFFST_SDVBS1_PRF_2_FIELD 1
63#define STV090x_WIDTH_SDVBS1_PRF_2_FIELD 1
64#define STV090x_OFFST_SDVBS1_PRF_1_FIELD 0
65#define STV090x_WIDTH_SDVBS1_PRF_1_FIELD 1
66
67#define STV090x_IRQSTATUS2 0xf121
68#define STV090x_OFFST_SSPY_ENDSIM_3_FIELD 7
69#define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD 1
70#define STV090x_OFFST_SSPY_ENDSIM_2_FIELD 6
71#define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD 1
72#define STV090x_OFFST_SSPY_ENDSIM_1_FIELD 5
73#define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD 1
74#define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD 4
75#define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD 1
76#define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD 3
77#define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD 1
78#define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD 2
79#define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD 1
80#define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD 1
81#define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD 1
82#define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD 0
83#define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD 1
84
85#define STV090x_IRQSTATUS1 0xf122
86#define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD 7
87#define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD 1
88#define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD 2
89#define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD 1
90#define STV090x_OFFST_SDEMOD_LOCK_2_FIELD 1
91#define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD 1
92#define STV090x_OFFST_SDEMOD_IRQ_2_FIELD 0
93#define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD 1
94
95#define STV090x_IRQSTATUS0 0xf123
96#define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD 7
97#define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD 1
98#define STV090x_OFFST_SDEMOD_LOCK_1_FIELD 6
99#define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD 1
100#define STV090x_OFFST_SDEMOD_IRQ_1_FIELD 5
101#define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD 1
102#define STV090x_OFFST_SBCH_ERRFLAG_FIELD 4
103#define STV090x_WIDTH_SBCH_ERRFLAG_FIELD 1
104#define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD 3
105#define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD 1
106#define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD 2
107#define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD 1
108#define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD 1
109#define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD 1
110#define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD 0
111#define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD 1
112
113#define STV090x_IRQMASK3 0xf124
114#define STV090x_OFFST_MPLL_LOCK_FIELD 5
115#define STV090x_WIDTH_MPLL_LOCK_FIELD 1
116#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 2
117#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 3
118#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 2
119#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 3
120#define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2
121#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 3
122#define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1
123#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1
124#define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0
125#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1
126
127#define STV090x_IRQMASK2 0xf125
128#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 5
129#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 3
130#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 5
131#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 3
132#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5
133#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 3
134#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4
135#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1
136#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3
137#define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD 1
138#define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD 2
139#define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD 1
140#define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD 1
141#define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD 1
142#define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD 0
143#define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD 1
144
145#define STV090x_IRQMASK1 0xf126
146#define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD 7
147#define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD 1
148#define STV090x_OFFST_MEXTPINB2_FIELD 6
149#define STV090x_WIDTH_MEXTPINB2_FIELD 1
150#define STV090x_OFFST_MEXTPIN2_FIELD 5
151#define STV090x_WIDTH_MEXTPIN2_FIELD 1
152#define STV090x_OFFST_MEXTPINB1_FIELD 4
153#define STV090x_WIDTH_MEXTPINB1_FIELD 1
154#define STV090x_OFFST_MEXTPIN1_FIELD 3
155#define STV090x_WIDTH_MEXTPIN1_FIELD 1
156#define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD 2
157#define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD 1
158#define STV090x_OFFST_MDEMOD_LOCK_2_FIELD 1
159#define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD 1
160#define STV090x_OFFST_MDEMOD_IRQ_2_FIELD 0
161#define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD 1
162
163#define STV090x_IRQMASK0 0xf127
164#define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD 7
165#define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD 1
166#define STV090x_OFFST_MDEMOD_LOCK_1_FIELD 6
167#define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD 1
168#define STV090x_OFFST_MDEMOD_IRQ_1_FIELD 5
169#define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD 1
170#define STV090x_OFFST_MBCH_ERRFLAG_FIELD 4
171#define STV090x_WIDTH_MBCH_ERRFLAG_FIELD 1
172#define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD 3
173#define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD 1
174#define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD 2
175#define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD 1
176#define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD 1
177#define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD 1
178#define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD 0
179#define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD 1
180
181#define STV090x_I2CCFG 0xf129
182#define STV090x_OFFST_12C_FASTMODE_FIELD 3
183#define STV090x_WIDTH_12C_FASTMODE_FIELD 1
184#define STV090x_OFFST_12CADDR_INC_FIELD 0
185#define STV090x_WIDTH_12CADDR_INC_FIELD 2
186
187#define STV090x_Px_I2CRPT(__x) (0xf12a + (__x - 1) * 0x1)
188#define STV090x_P1_I2CRPT STV090x_Px_I2CRPT(1)
189#define STV090x_P2_I2CRPT STV090x_Px_I2CRPT(2)
190#define STV090x_OFFST_Px_I2CT_ON_FIELD 7
191#define STV090x_WIDTH_Px_I2CT_ON_FIELD 1
192#define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD 4
193#define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD 3
194#define STV090x_OFFST_Px_SCLT_DELAY_FIELD 3
195#define STV090x_WIDTH_Px_SCLT_DELAY_FIELD 1
196#define STV090x_OFFST_Px_STOP_ENABLE_FIELD 2
197#define STV090x_WIDTH_Px_STOP_ENABLE_FIELD 1
198#define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD 1
199#define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD 1
200
201#define STV090x_CLKI2CFG 0xf140
202#define STV090x_OFFST_CLKI2_OPD_FIELD 7
203#define STV090x_WIDTH_CLKI2_OPD_FIELD 1
204#define STV090x_OFFST_CLKI2_CONFIG_FIELD 1
205#define STV090x_WIDTH_CLKI2_CONFIG_FIELD 6
206#define STV090x_OFFST_CLKI2_XOR_FIELD 0
207#define STV090x_WIDTH_CLKI2_XOR_FIELD 1
208
209#define STV090x_GPIOxCFG(__x) (0xf141 + (__x - 1))
210#define STV090x_GPIO1CFG STV090x_GPIOxCFG(1)
211#define STV090x_GPIO2CFG STV090x_GPIOxCFG(2)
212#define STV090x_GPIO3CFG STV090x_GPIOxCFG(3)
213#define STV090x_GPIO4CFG STV090x_GPIOxCFG(4)
214#define STV090x_GPIO5CFG STV090x_GPIOxCFG(5)
215#define STV090x_GPIO6CFG STV090x_GPIOxCFG(6)
216#define STV090x_GPIO7CFG STV090x_GPIOxCFG(7)
217#define STV090x_GPIO8CFG STV090x_GPIOxCFG(8)
218#define STV090x_GPIO9CFG STV090x_GPIOxCFG(9)
219#define STV090x_GPIO10CFG STV090x_GPIOxCFG(10)
220#define STV090x_GPIO11CFG STV090x_GPIOxCFG(11)
221#define STV090x_GPIO12CFG STV090x_GPIOxCFG(12)
222#define STV090x_GPIO13CFG STV090x_GPIOxCFG(13)
223#define STV090x_OFFST_GPIOx_OPD_FIELD 7
224#define STV090x_WIDTH_GPIOx_OPD_FIELD 1
225#define STV090x_OFFST_GPIOx_CONFIG_FIELD 1
226#define STV090x_WIDTH_GPIOx_CONFIG_FIELD 6
227#define STV090x_OFFST_GPIOx_XOR_FIELD 0
228#define STV090x_WIDTH_GPIOx_XOR_FIELD 1
229
230#define STV090x_CSxCFG(__x) (0xf14e + __x * 0x1)
231#define STV090x_CS0CFG STV090x_CSxCFG(0)
232#define STV090x_CS1CFG STV090x_CSxCFG(1)
233#define STV090x_OFFST_CSX_OPD_FIELD 7
234#define STV090x_WIDTH_CSX_OPD_FIELD 1
235#define STV090x_OFFST_CSX_CONFIG_FIELD 1
236#define STV090x_WIDTH_CSX_CONFIG_FIELD 6
237#define STV090x_OFFST_CSX_XOR_FIELD 0
238#define STV090x_WIDTH_CSX_XOR_FIELD 1
239
240
241#define STV090x_STDBYCFG 0xf150
242#define STV090x_OFFST_STDBY_OPD_FIELD 7
243#define STV090x_WIDTH_STDBY_OPD_FIELD 1
244#define STV090x_OFFST_STDBY_CONFIG_FIELD 1
245#define STV090x_WIDTH_STDBY_CONFIG_FIELD 6
246#define STV090x_OFFST_STDBY_XOR_FIELD 0
247#define STV090x_WIDTH_STDBY_XOR_FIELD 1
248
249#define STV090x_DIRCLKCFG 0xf151
250#define STV090x_OFFST_DIRCLK_OPD_FIELD 7
251#define STV090x_WIDTH_DIRCLK_OPD_FIELD 1
252#define STV090x_OFFST_DIRCLK_CONFIG_FIELD 1
253#define STV090x_WIDTH_DIRCLK_CONFIG_FIELD 6
254#define STV090x_OFFST_DIRCLK_XOR_FIELD 0
255#define STV090x_WIDTH_DIRCLK_XOR_FIELD 1
256
257
258#define STV090x_AGCRFxCFG(__x) (0xf152 + (__x - 1) * 0x4)
259#define STV090x_AGCRF1CFG STV090x_AGCRFxCFG(1)
260#define STV090x_AGCRF2CFG STV090x_AGCRFxCFG(2)
261#define STV090x_OFFST_AGCRFx_OPD_FIELD 7
262#define STV090x_WIDTH_AGCRFx_OPD_FIELD 1
263#define STV090x_OFFST_AGCRFx_CONFIG_FIELD 1
264#define STV090x_WIDTH_AGCRFx_CONFIG_FIELD 6
265#define STV090x_OFFST_AGCRFx_XOR_FIELD 0
266#define STV090x_WIDTH_AGCRFx_XOR_FIELD 1
267
268#define STV090x_SDATxCFG(__x) (0xf153 + (__x - 1) * 0x4)
269#define STV090x_SDAT1CFG STV090x_SDATxCFG(1)
270#define STV090x_SDAT2CFG STV090x_SDATxCFG(2)
271#define STV090x_OFFST_SDATx_OPD_FIELD 7
272#define STV090x_WIDTH_SDATx_OPD_FIELD 1
273#define STV090x_OFFST_SDATx_CONFIG_FIELD 1
274#define STV090x_WIDTH_SDATx_CONFIG_FIELD 6
275#define STV090x_OFFST_SDATx_XOR_FIELD 0
276#define STV090x_WIDTH_SDATx_XOR_FIELD 1
277
278#define STV090x_SCLTxCFG(__x) (0xf154 + (__x - 1) * 0x4)
279#define STV090x_SCLT1CFG STV090x_SCLTxCFG(1)
280#define STV090x_SCLT2CFG STV090x_SCLTxCFG(2)
281#define STV090x_OFFST_SCLTx_OPD_FIELD 7
282#define STV090x_WIDTH_SCLTx_OPD_FIELD 1
283#define STV090x_OFFST_SCLTx_CONFIG_FIELD 1
284#define STV090x_WIDTH_SCLTx_CONFIG_FIELD 6
285#define STV090x_OFFST_SCLTx_XOR_FIELD 0
286#define STV090x_WIDTH_SCLTx_XOR_FIELD 1
287
288#define STV090x_DISEQCOxCFG(__x) (0xf155 + (__x - 1) * 0x4)
289#define STV090x_DISEQCO1CFG STV090x_DISEQCOxCFG(1)
290#define STV090x_DISEQCO2CFG STV090x_DISEQCOxCFG(2)
291#define STV090x_OFFST_DISEQCOx_OPD_FIELD 7
292#define STV090x_WIDTH_DISEQCOx_OPD_FIELD 1
293#define STV090x_OFFST_DISEQCOx_CONFIG_FIELD 1
294#define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD 6
295#define STV090x_OFFST_DISEQCOx_XOR_FIELD 0
296#define STV090x_WIDTH_DISEQCOx_XOR_FIELD 1
297
298#define STV090x_CLKOUT27CFG 0xf15a
299#define STV090x_OFFST_CLKOUT27_OPD_FIELD 7
300#define STV090x_WIDTH_CLKOUT27_OPD_FIELD 1
301#define STV090x_OFFST_CLKOUT27_CONFIG_FIELD 1
302#define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD 6
303#define STV090x_OFFST_CLKOUT27_XOR_FIELD 0
304#define STV090x_WIDTH_CLKOUT27_XOR_FIELD 1
305
306#define STV090x_ERRORxCFG(__x) (0xf15b + (__x - 1) * 0x5)
307#define STV090x_ERROR1CFG STV090x_ERRORxCFG(1)
308#define STV090x_ERROR2CFG STV090x_ERRORxCFG(2)
309#define STV090x_ERROR3CFG STV090x_ERRORxCFG(3)
310#define STV090x_OFFST_ERRORx_OPD_FIELD 7
311#define STV090x_WIDTH_ERRORx_OPD_FIELD 1
312#define STV090x_OFFST_ERRORx_CONFIG_FIELD 1
313#define STV090x_WIDTH_ERRORx_CONFIG_FIELD 6
314#define STV090x_OFFST_ERRORx_XOR_FIELD 0
315#define STV090x_WIDTH_ERRORx_XOR_FIELD 1
316
317#define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5)
318#define STV090x_DPN1CFG STV090x_DPNxCFG(1)
319#define STV090x_DPN2CFG STV090x_DPNxCFG(2)
320#define STV090x_DPN3CFG STV090x_DPNxCFG(3)
321#define STV090x_OFFST_DPNx_OPD_FIELD 7
322#define STV090x_WIDTH_DPNx_OPD_FIELD 1
323#define STV090x_OFFST_DPNx_CONFIG_FIELD 1
324#define STV090x_WIDTH_DPNx_CONFIG_FIELD 6
325#define STV090x_OFFST_DPNx_XOR_FIELD 0
326#define STV090x_WIDTH_DPNx_XOR_FIELD 1
327
328#define STV090x_STROUTxCFG(__x) (0xf15d + (__x - 1) * 0x5)
329#define STV090x_STROUT1CFG STV090x_STROUTxCFG(1)
330#define STV090x_STROUT2CFG STV090x_STROUTxCFG(2)
331#define STV090x_STROUT3CFG STV090x_STROUTxCFG(3)
332#define STV090x_OFFST_STROUTx_OPD_FIELD 7
333#define STV090x_WIDTH_STROUTx_OPD_FIELD 1
334#define STV090x_OFFST_STROUTx_CONFIG_FIELD 1
335#define STV090x_WIDTH_STROUTx_CONFIG_FIELD 6
336#define STV090x_OFFST_STROUTx_XOR_FIELD 0
337#define STV090x_WIDTH_STROUTx_XOR_FIELD 1
338
339#define STV090x_CLKOUTxCFG(__x) (0xf15e + (__x - 1) * 0x5)
340#define STV090x_CLKOUT1CFG STV090x_CLKOUTxCFG(1)
341#define STV090x_CLKOUT2CFG STV090x_CLKOUTxCFG(2)
342#define STV090x_CLKOUT3CFG STV090x_CLKOUTxCFG(3)
343#define STV090x_OFFST_CLKOUTx_OPD_FIELD 7
344#define STV090x_WIDTH_CLKOUTx_OPD_FIELD 1
345#define STV090x_OFFST_CLKOUTx_CONFIG_FIELD 1
346#define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD 6
347#define STV090x_OFFST_CLKOUTx_XOR_FIELD 0
348#define STV090x_WIDTH_CLKOUTx_XOR_FIELD 1
349
350#define STV090x_DATAxCFG(__x) (0xf15f + (__x - 71) * 0x5)
351#define STV090x_DATA71CFG STV090x_DATAxCFG(71)
352#define STV090x_DATA72CFG STV090x_DATAxCFG(72)
353#define STV090x_DATA73CFG STV090x_DATAxCFG(73)
354#define STV090x_OFFST_DATAx_OPD_FIELD 7
355#define STV090x_WIDTH_DATAx_OPD_FIELD 1
356#define STV090x_OFFST_DATAx_CONFIG_FIELD 1
357#define STV090x_WIDTH_DATAx_CONFIG_FIELD 6
358#define STV090x_OFFST_DATAx_XOR_FIELD 0
359#define STV090x_WIDTH_DATAx_XOR_FIELD 1
360
361#define STV090x_NCOARSE 0xf1b3
362#define STV090x_OFFST_M_DIV_FIELD 0
363#define STV090x_WIDTH_M_DIV_FIELD 8
364
365#define STV090x_SYNTCTRL 0xf1b6
366#define STV090x_OFFST_STANDBY_FIELD 7
367#define STV090x_WIDTH_STANDBY_FIELD 1
368#define STV090x_OFFST_BYPASSPLLCORE_FIELD 6
369#define STV090x_WIDTH_BYPASSPLLCORE_FIELD 1
370#define STV090x_OFFST_SELX1RATIO_FIELD 5
371#define STV090x_WIDTH_SELX1RATIO_FIELD 1
372#define STV090x_OFFST_STOP_PLL_FIELD 3
373#define STV090x_WIDTH_SELX1RATIO_FIELD 1
374#define STV090x_OFFST_BYPASSPLLFSK_FIELD 2
375#define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1
376#define STV090x_OFFST_SELOSCI_FIELD 1
377#define STV090x_WIDTH_SELOSCI_FIELD 1
378#define STV090x_OFFST_BYPASSPLLADC_FIELD 0
379#define STV090x_WIDTH_BYPASSPLLADC_FIELD 1
380
381#define STV090x_FILTCTRL 0xf1b7
382#define STV090x_OFFST_INV_CLK135_FIELD 7
383#define STV090x_WIDTH_INV_CLK135_FIELD 1
384#define STV090x_OFFST_SEL_FSKCKDIV_FIELD 2
385#define STV090x_WIDTH_SEL_FSKCKDIV_FIELD 1
386#define STV090x_OFFST_INV_CLKFSK_FIELD 1
387#define STV090x_WIDTH_INV_CLKFSK_FIELD 1
388#define STV090x_OFFST_BYPASS_APPLI_FIELD 0
389#define STV090x_WIDTH_BYPASS_APPLI_FIELD 1
390
391#define STV090x_PLLSTAT 0xf1b8
392#define STV090x_OFFST_PLLLOCK_FIELD 0
393#define STV090x_WIDTH_PLLLOCK_FIELD 1
394
395#define STV090x_STOPCLK1 0xf1c2
396#define STV090x_OFFST_STOP_CLKPKDT2_FIELD 6
397#define STV090x_WIDTH_STOP_CLKPKDT2_FIELD 1
398#define STV090x_OFFST_STOP_CLKPKDT1_FIELD 5
399#define STV090x_WIDTH_STOP_CLKPKDT1_FIELD 1
400#define STV090x_OFFST_STOP_CLKFEC_FIELD 4
401#define STV090x_WIDTH_STOP_CLKFEC_FIELD 1
402#define STV090x_OFFST_STOP_CLKADCI2_FIELD 3
403#define STV090x_WIDTH_STOP_CLKADCI2_FIELD 1
404#define STV090x_OFFST_INV_CLKADCI2_FIELD 2
405#define STV090x_WIDTH_INV_CLKADCI2_FIELD 1
406#define STV090x_OFFST_STOP_CLKADCI1_FIELD 1
407#define STV090x_WIDTH_STOP_CLKADCI1_FIELD 1
408#define STV090x_OFFST_INV_CLKADCI1_FIELD 0
409#define STV090x_WIDTH_INV_CLKADCI1_FIELD 1
410
411#define STV090x_STOPCLK2 0xf1c3
412#define STV090x_OFFST_STOP_CLKSAMP2_FIELD 4
413#define STV090x_WIDTH_STOP_CLKSAMP2_FIELD 1
414#define STV090x_OFFST_STOP_CLKSAMP1_FIELD 3
415#define STV090x_WIDTH_STOP_CLKSAMP1_FIELD 1
416#define STV090x_OFFST_STOP_CLKVIT2_FIELD 2
417#define STV090x_WIDTH_STOP_CLKVIT2_FIELD 1
418#define STV090x_OFFST_STOP_CLKVIT1_FIELD 1
419#define STV090x_WIDTH_STOP_CLKVIT1_FIELD 1
420#define STV090x_OFFST_STOP_CLKTS_FIELD 0
421#define STV090x_WIDTH_STOP_CLKTS_FIELD 1
422
423#define STV090x_TSTTNR0 0xf1df
424#define STV090x_OFFST_SEL_FSK_FIELD 7
425#define STV090x_WIDTH_SEL_FSK_FIELD 1
426#define STV090x_OFFST_FSK_PON_FIELD 2
427#define STV090x_WIDTH_FSK_PON_FIELD 1
428
429#define STV090x_TSTTNR1 0xf1e0
430#define STV090x_OFFST_ADC1_PON_FIELD 1
431#define STV090x_WIDTH_ADC1_PON_FIELD 1
432#define STV090x_OFFST_ADC1_INMODE_FIELD 0
433#define STV090x_WIDTH_ADC1_INMODE_FIELD 1
434
435#define STV090x_TSTTNR2 0xf1e1
436#define STV090x_OFFST_DISEQC1_PON_FIELD 5
437#define STV090x_WIDTH_DISEQC1_PON_FIELD 1
438
439#define STV090x_TSTTNR3 0xf1e2
440#define STV090x_OFFST_ADC2_PON_FIELD 1
441#define STV090x_WIDTH_ADC2_PON_FIELD 1
442#define STV090x_OFFST_ADC2_INMODE_FIELD 0
443#define STV090x_WIDTH_ADC2_INMODE_FIELD 1
444
445#define STV090x_TSTTNR4 0xf1e3
446#define STV090x_OFFST_DISEQC2_PON_FIELD 5
447#define STV090x_WIDTH_DISEQC2_PON_FIELD 1
448
449#define STV090x_FSKTFC2 0xf170
450#define STV090x_OFFST_FSKT_KMOD_FIELD 2
451#define STV090x_WIDTH_FSKT_KMOD_FIELD 6
452#define STV090x_OFFST_FSKT_CAR_FIELD 0
453#define STV090x_WIDTH_FSKT_CAR_FIELD 2
454
455#define STV090x_FSKTFC1 0xf171
456#define STV090x_OFFST_FSKTC1_CAR_FIELD 0
457#define STV090x_WIDTH_FSKTC1_CAR_FIELD 8
458
459#define STV090x_FSKTFC0 0xf172
460#define STV090x_OFFST_FSKTC0_CAR_FIELD 0
461#define STV090x_WIDTH_FSKTC0_CAR_FIELD 8
462
463#define STV090x_FSKTDELTAF1 0xf173
464#define STV090x_OFFST_FSKTF1_DELTAF_FIELD 0
465#define STV090x_WIDTH_FSKTF1_DELTAF_FIELD 4
466
467#define STV090x_FSKTDELTAF0 0xf174
468#define STV090x_OFFST_FSKTF0_DELTAF_FIELD 0
469#define STV090x_WIDTH_FSKTF0_DELTAF_FIELD 8
470
471#define STV090x_FSKTCTRL 0xf175
472#define STV090x_OFFST_FSKT_EN_SGN_FIELD 6
473#define STV090x_WIDTH_FSKT_EN_SGN_FIELD 1
474#define STV090x_OFFST_FSKT_MOD_SGN_FIELD 5
475#define STV090x_WIDTH_FSKT_MOD_SGN_FIELD 1
476#define STV090x_OFFST_FSKT_MOD_EN_FIELD 2
477#define STV090x_WIDTH_FSKT_MOD_EN_FIELD 3
478#define STV090x_OFFST_FSKT_DACMODE_FIELD 0
479#define STV090x_WIDTH_FSKT_DACMODE_FIELD 2
480
481#define STV090x_FSKRFC2 0xf176
482#define STV090x_OFFST_FSKRC2_DETSGN_FIELD 6
483#define STV090x_WIDTH_FSKRC2_DETSGN_FIELD 1
484#define STV090x_OFFST_FSKRC2_OUTSGN_FIELD 5
485#define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD 1
486#define STV090x_OFFST_FSKRC2_KAGC_FIELD 2
487#define STV090x_WIDTH_FSKRC2_KAGC_FIELD 3
488#define STV090x_OFFST_FSKRC2_CAR_FIELD 0
489#define STV090x_WIDTH_FSKRC2_CAR_FIELD 2
490
491#define STV090x_FSKRFC1 0xf177
492#define STV090x_OFFST_FSKRC1_CAR_FIELD 0
493#define STV090x_WIDTH_FSKRC1_CAR_FIELD 8
494
495#define STV090x_FSKRFC0 0xf178
496#define STV090x_OFFST_FSKRC0_CAR_FIELD 0
497#define STV090x_WIDTH_FSKRC0_CAR_FIELD 8
498
499#define STV090x_FSKRK1 0xf179
500#define STV090x_OFFST_FSKR_K1_EXP_FIELD 5
501#define STV090x_WIDTH_FSKR_K1_EXP_FIELD 3
502#define STV090x_OFFST_FSKR_K1_MANT_FIELD 0
503#define STV090x_WIDTH_FSKR_K1_MANT_FIELD 5
504
505#define STV090x_FSKRK2 0xf17a
506#define STV090x_OFFST_FSKR_K2_EXP_FIELD 5
507#define STV090x_WIDTH_FSKR_K2_EXP_FIELD 3
508#define STV090x_OFFST_FSKR_K2_MANT_FIELD 0
509#define STV090x_WIDTH_FSKR_K2_MANT_FIELD 5
510
511#define STV090x_FSKRAGCR 0xf17b
512#define STV090x_OFFST_FSKR_OUTCTL_FIELD 6
513#define STV090x_WIDTH_FSKR_OUTCTL_FIELD 2
514#define STV090x_OFFST_FSKR_AGC_REF_FIELD 0
515#define STV090x_WIDTH_FSKR_AGC_REF_FIELD 6
516
517#define STV090x_FSKRAGC 0xf17c
518#define STV090x_OFFST_FSKR_AGC_ACCU_FIELD 0
519#define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD 8
520
521#define STV090x_FSKRALPHA 0xf17d
522#define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD 2
523#define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD 3
524#define STV090x_OFFST_FSKR_ALPHA_M_FIELD 0
525#define STV090x_WIDTH_FSKR_ALPHA_M_FIELD 2
526
527#define STV090x_FSKRPLTH1 0xf17e
528#define STV090x_OFFST_FSKR_BETA_FIELD 4
529#define STV090x_WIDTH_FSKR_BETA_FIELD 4
530#define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD 0
531#define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD 4
532
533#define STV090x_FSKRPLTH0 0xf17f
534#define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD 0
535#define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD 8
536
537#define STV090x_FSKRDF1 0xf180
538#define STV090x_OFFST_FSKR_DELTAF1_FIELD 0
539#define STV090x_WIDTH_FSKR_DELTAF1_FIELD 5
540
541#define STV090x_FSKRDF0 0xf181
542#define STV090x_OFFST_FSKR_DELTAF0_FIELD 0
543#define STV090x_WIDTH_FSKR_DELTAF0_FIELD 8
544
545#define STV090x_FSKRSTEPP 0xf182
546#define STV090x_OFFST_FSKR_STEP_PLUS_FIELD 0
547#define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD 8
548
549#define STV090x_FSKRSTEPM 0xf183
550#define STV090x_OFFST_FSKR_STEP_MINUS_FIELD 0
551#define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD 8
552
553#define STV090x_FSKRDET1 0xf184
554#define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD 0
555#define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD 4
556
557#define STV090x_FSKRDET0 0xf185
558#define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD 0
559#define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD 8
560
561#define STV090x_FSKRDTH1 0xf186
562#define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD 4
563#define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD 4
564#define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD 0
565#define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD 4
566
567#define STV090x_FSKRDTH0 0xf187
568#define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD 0
569#define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD 8
570
571#define STV090x_FSKRLOSS 0xf188
572#define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD 0
573#define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD 8
574
575#define STV090x_Px_DISTXCTL(__x) (0xF1A0 - (__x - 1) * 0x10)
576#define STV090x_P1_DISTXCTL STV090x_Px_DISTXCTL(1)
577#define STV090x_P2_DISTXCTL STV090x_Px_DISTXCTL(2)
578#define STV090x_OFFST_Px_TIM_OFF_FIELD 7
579#define STV090x_WIDTH_Px_TIM_OFF_FIELD 1
580#define STV090x_OFFST_Px_DISEQC_RESET_FIELD 6
581#define STV090x_WIDTH_Px_DISEQC_RESET_FIELD 1
582#define STV090x_OFFST_Px_TIM_CMD_FIELD 4
583#define STV090x_WIDTH_Px_TIM_CMD_FIELD 2
584#define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD 3
585#define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD 1
586#define STV090x_OFFST_Px_DISTX_MODE_FIELD 0
587#define STV090x_WIDTH_Px_DISTX_MODE_FIELD 3
588
589#define STV090x_Px_DISRXCTL(__x) (0xf1a1 - (__x - 1) * 0x10)
590#define STV090x_P1_DISRXCTL STV090x_Px_DISRXCTL(1)
591#define STV090x_P2_DISRXCTL STV090x_Px_DISRXCTL(2)
592#define STV090x_OFFST_Px_RECEIVER_ON_FIELD 7
593#define STV090x_WIDTH_Px_RECEIVER_ON_FIELD 1
594#define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD 6
595#define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD 1
596#define STV090x_OFFST_Px_ONECHIP_TRX_FIELD 5
597#define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD 1
598#define STV090x_OFFST_Px_EXT_ENVELOP_FIELD 4
599#define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD 1
600#define STV090x_OFFST_Px_PIN_SELECT_FIELD 2
601#define STV090x_WIDTH_Px_PIN_SELECT_FIELD 2
602#define STV090x_OFFST_Px_IRQ_RXEND_FIELD 1
603#define STV090x_WIDTH_Px_IRQ_RXEND_FIELD 1
604#define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD 0
605#define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD 1
606
607#define STV090x_Px_DISRX_ST0(__x) (0xf1a4 - (__x - 1) * 0x10)
608#define STV090x_P1_DISRX_ST0 STV090x_Px_DISRX_ST0(1)
609#define STV090x_P2_DISRX_ST0 STV090x_Px_DISRX_ST0(2)
610#define STV090x_OFFST_Px_RX_END_FIELD 7
611#define STV090x_WIDTH_Px_RX_END_FIELD 1
612#define STV090x_OFFST_Px_RX_ACTIVE_FIELD 6
613#define STV090x_WIDTH_Px_RX_ACTIVE_FIELD 1
614#define STV090x_OFFST_Px_SHORT_22KHZ_FIELD 5
615#define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD 1
616#define STV090x_OFFST_Px_CONT_TONE_FIELD 4
617#define STV090x_WIDTH_Px_CONT_TONE_FIELD 1
618#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3
619#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 2
620#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2
621#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1
622#define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0
623#define STV090x_WIDTH_Px_ABORT_DISRX_FIELD 1
624
625#define STV090x_Px_DISRX_ST1(__x) (0xf1a5 - (__x - 1) * 0x10)
626#define STV090x_P1_DISRX_ST1 STV090x_Px_DISRX_ST1(1)
627#define STV090x_P2_DISRX_ST1 STV090x_Px_DISRX_ST1(2)
628#define STV090x_OFFST_Px_RX_FAIL_FIELD 7
629#define STV090x_WIDTH_Px_RX_FAIL_FIELD 1
630#define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6
631#define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1
632#define STV090x_OFFST_Px_RX_NONBYTE_FIELD 5
633#define STV090x_WIDTH_Px_RX_NONBYTE_FIELD 1
634#define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD 4
635#define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD 1
636#define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD 0
637#define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD 4
638
639#define STV090x_Px_DISRXDATA(__x) (0xf1a6 - (__x - 1) * 0x10)
640#define STV090x_P1_DISRXDATA STV090x_Px_DISRXDATA(1)
641#define STV090x_P2_DISRXDATA STV090x_Px_DISRXDATA(2)
642#define STV090x_OFFST_Px_DISRX_DATA_FIELD 0
643#define STV090x_WIDTH_Px_DISRX_DATA_FIELD 8
644
645#define STV090x_Px_DISTXDATA(__x) (0xf1a7 - (__x - 1) * 0x10)
646#define STV090x_P1_DISTXDATA STV090x_Px_DISTXDATA(1)
647#define STV090x_P2_DISTXDATA STV090x_Px_DISTXDATA(2)
648#define STV090x_OFFST_Px_DISEQC_FIFO_FIELD 0
649#define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD 8
650
651#define STV090x_Px_DISTXSTATUS(__x) (0xf1a8 - (__x - 1) * 0x10)
652#define STV090x_P1_DISTXSTATUS STV090x_Px_DISTXSTATUS(1)
653#define STV090x_P2_DISTXSTATUS STV090x_Px_DISTXSTATUS(2)
654#define STV090x_OFFST_Px_TX_FAIL_FIELD 7
655#define STV090x_WIDTH_Px_TX_FAIL_FIELD 1
656#define STV090x_OFFST_Px_FIFO_FULL_FIELD 6
657#define STV090x_WIDTH_Px_FIFO_FULL_FIELD 1
658#define STV090x_OFFST_Px_TX_IDLE_FIELD 5
659#define STV090x_WIDTH_Px_TX_IDLE_FIELD 1
660#define STV090x_OFFST_Px_GAP_BURST_FIELD 4
661#define STV090x_WIDTH_Px_GAP_BURST_FIELD 1
662#define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD 0
663#define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD 4
664
665#define STV090x_Px_F22TX(__x) (0xf1a9 - (__x - 1) * 0x10)
666#define STV090x_P1_F22TX STV090x_Px_F22TX(1)
667#define STV090x_P2_F22TX STV090x_Px_F22TX(2)
668#define STV090x_OFFST_Px_F22_REG_FIELD 0
669#define STV090x_WIDTH_Px_F22_REG_FIELD 8
670
671#define STV090x_Px_F22RX(__x) (0xf1aa - (__x - 1) * 0x10)
672#define STV090x_P1_F22RX STV090x_Px_F22RX(1)
673#define STV090x_P2_F22RX STV090x_Px_F22RX(2)
674#define STV090x_OFFST_Px_F22RX_REG_FIELD 0
675#define STV090x_WIDTH_Px_F22RX_REG_FIELD 8
676
677#define STV090x_Px_ACRPRESC(__x) (0xf1ac - (__x - 1) * 0x10)
678#define STV090x_P1_ACRPRESC STV090x_Px_ACRPRESC(1)
679#define STV090x_P2_ACRPRESC STV090x_Px_ACRPRESC(2)
680#define STV090x_OFFST_Px_ACR_PRESC_FIELD 0
681#define STV090x_WIDTH_Px_ACR_PRESC_FIELD 3
682
683#define STV090x_Px_ACRDIV(__x) (0xf1ad - (__x - 1) * 0x10)
684#define STV090x_P1_ACRDIV STV090x_Px_ACRDIV(1)
685#define STV090x_P2_ACRDIV STV090x_Px_ACRDIV(2)
686#define STV090x_OFFST_Px_ACR_DIV_FIELD 0
687#define STV090x_WIDTH_Px_ACR_DIV_FIELD 8
688
689#define STV090x_Px_IQCONST(__x) (0xF400 - (__x - 1) * 0x200)
690#define STV090x_P1_IQCONST STV090x_Px_IQCONST(1)
691#define STV090x_P2_IQCONST STV090x_Px_IQCONST(2)
692#define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD 5
693#define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD 2
694
695#define STV090x_Px_NOSCFG(__x) (0xF401 - (__x - 1) * 0x200)
696#define STV090x_P1_NOSCFG STV090x_Px_NOSCFG(1)
697#define STV090x_P2_NOSCFG STV090x_Px_NOSCFG(2)
698#define STV090x_OFFST_Px_NOSPLH_BETA_FIELD 3
699#define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD 2
700#define STV090x_OFFST_Px_NOSDATA_BETA_FIELD 0
701#define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD 3
702
703#define STV090x_Px_ISYMB(__x) (0xF402 - (__x - 1) * 0x200)
704#define STV090x_P1_ISYMB STV090x_Px_ISYMB(1)
705#define STV090x_P2_ISYMB STV090x_Px_ISYMB(2)
706#define STV090x_OFFST_Px_I_SYMBOL_FIELD 0
707#define STV090x_WIDTH_Px_I_SYMBOL_FIELD 8
708
709#define STV090x_Px_QSYMB(__x) (0xF403 - (__x - 1) * 0x200)
710#define STV090x_P1_QSYMB STV090x_Px_QSYMB(1)
711#define STV090x_P2_QSYMB STV090x_Px_QSYMB(2)
712#define STV090x_OFFST_Px_Q_SYMBOL_FIELD 0
713#define STV090x_WIDTH_Px_Q_SYMBOL_FIELD 8
714
715#define STV090x_Px_AGC1CFG(__x) (0xF404 - (__x - 1) * 0x200)
716#define STV090x_P1_AGC1CFG STV090x_Px_AGC1CFG(1)
717#define STV090x_P2_AGC1CFG STV090x_Px_AGC1CFG(2)
718#define STV090x_OFFST_Px_DC_FROZEN_FIELD 7
719#define STV090x_WIDTH_Px_DC_FROZEN_FIELD 1
720#define STV090x_OFFST_Px_DC_CORRECT_FIELD 6
721#define STV090x_WIDTH_Px_DC_CORRECT_FIELD 1
722#define STV090x_OFFST_Px_AMM_FROZEN_FIELD 5
723#define STV090x_WIDTH_Px_AMM_FROZEN_FIELD 1
724#define STV090x_OFFST_Px_AMM_CORRECT_FIELD 4
725#define STV090x_WIDTH_Px_AMM_CORRECT_FIELD 1
726#define STV090x_OFFST_Px_QUAD_FROZEN_FIELD 3
727#define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD 1
728#define STV090x_OFFST_Px_QUAD_CORRECT_FIELD 2
729#define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD 1
730
731#define STV090x_Px_AGC1CN(__x) (0xF406 - (__x - 1) * 0x200)
732#define STV090x_P1_AGC1CN STV090x_Px_AGC1CN(1)
733#define STV090x_P2_AGC1CN STV090x_Px_AGC1CN(2)
734#define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD 7
735#define STV090x_OFFST_Px_AGC1_LOCKED_FIELD 1
736#define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD 4
737#define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD 1
738#define STV090x_OFFST_Px_AGCOUT_FAST_FIELD 3
739#define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD 1
740#define STV090x_OFFST_Px_AGCIQ_BETA_FIELD 0
741#define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD 3
742
743#define STV090x_Px_AGC1REF(__x) (0xF407 - (__x - 1) * 0x200)
744#define STV090x_P1_AGC1REF STV090x_Px_AGC1REF(1)
745#define STV090x_P2_AGC1REF STV090x_Px_AGC1REF(2)
746#define STV090x_OFFST_Px_AGCIQ_REF_FIELD 0
747#define STV090x_WIDTH_Px_AGCIQ_REF_FIELD 8
748
749#define STV090x_Px_IDCCOMP(__x) (0xF408 - (__x - 1) * 0x200)
750#define STV090x_P1_IDCCOMP STV090x_Px_IDCCOMP(1)
751#define STV090x_P2_IDCCOMP STV090x_Px_IDCCOMP(2)
752#define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD 0
753#define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD 8
754
755#define STV090x_Px_QDCCOMP(__x) (0xF409 - (__x - 1) * 0x200)
756#define STV090x_P1_QDCCOMP STV090x_Px_QDCCOMP(1)
757#define STV090x_P2_QDCCOMP STV090x_Px_QDCCOMP(2)
758#define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD 0
759#define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD 8
760
761#define STV090x_Px_POWERI(__x) (0xF40A - (__x - 1) * 0x200)
762#define STV090x_P1_POWERI STV090x_Px_POWERI(1)
763#define STV090x_P2_POWERI STV090x_Px_POWERI(2)
764#define STV090x_OFFST_Px_POWER_I_FIELD 0
765#define STV090x_WIDTH_Px_POWER_I_FIELD 8
766
767#define STV090x_Px_POWERQ(__x) (0xF40B - (__x - 1) * 0x200)
768#define STV090x_P1_POWERQ STV090x_Px_POWERQ(1)
769#define STV090x_P2_POWERQ STV090x_Px_POWERQ(2)
770#define STV090x_OFFST_Px_POWER_Q_FIELD 0
771#define STV090x_WIDTH_Px_POWER_Q_FIELD 8
772
773#define STV090x_Px_AGC1AMM(__x) (0xF40C - (__x - 1) * 0x200)
774#define STV090x_P1_AGC1AMM STV090x_Px_AGC1AMM(1)
775#define STV090x_P2_AGC1AMM STV090x_Px_AGC1AMM(2)
776#define STV090x_OFFST_Px_AMM_VALUE_FIELD 0
777#define STV090x_WIDTH_Px_AMM_VALUE_FIELD 8
778
779#define STV090x_Px_AGC1QUAD(__x) (0xF40D - (__x - 1) * 0x200)
780#define STV090x_P1_AGC1QUAD STV090x_Px_AGC1QUAD(1)
781#define STV090x_P2_AGC1QUAD STV090x_Px_AGC1QUAD(2)
782#define STV090x_OFFST_Px_QUAD_VALUE_FIELD 0
783#define STV090x_WIDTH_Px_QUAD_VALUE_FIELD 8
784
785#define STV090x_Px_AGCIQINy(__x, __y) (0xF40F - (__x-1) * 0x200 - __y * 0x1)
786#define STV090x_P1_AGCIQIN0 STV090x_Px_AGCIQINy(1, 0)
787#define STV090x_P1_AGCIQIN1 STV090x_Px_AGCIQINy(1, 1)
788#define STV090x_P2_AGCIQIN0 STV090x_Px_AGCIQINy(2, 0)
789#define STV090x_P2_AGCIQIN1 STV090x_Px_AGCIQINy(2, 1)
790#define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD 0
791#define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD 8
792
793#define STV090x_Px_DEMOD(__x) (0xF410 - (__x - 1) * 0x200)
794#define STV090x_P1_DEMOD STV090x_Px_DEMOD(1)
795#define STV090x_P2_DEMOD STV090x_Px_DEMOD(2)
796#define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD 7
797#define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD 1
798#define STV090x_OFFST_Px_DEMOD_STOP_FIELD 6
799#define STV090x_WIDTH_Px_DEMOD_STOP_FIELD 1
800#define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4
801#define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2
802#define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD 3
803#define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD 1
804#define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD 2
805#define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD 1
806#define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0
807#define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2
808
809#define STV090x_Px_DMDMODCOD(__x) (0xF411 - (__x - 1) * 0x200)
810#define STV090x_P1_DMDMODCOD STV090x_Px_DMDMODCOD(1)
811#define STV090x_P2_DMDMODCOD STV090x_Px_DMDMODCOD(2)
812#define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD 7
813#define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD 1
814#define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD 2
815#define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD 5
816#define STV090x_OFFST_Px_DEMOD_TYPE_FIELD 0
817#define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD 2
818
819#define STV090x_Px_DSTATUS(__x) (0xF412 - (__x - 1) * 0x200)
820#define STV090x_P1_DSTATUS STV090x_Px_DSTATUS(1)
821#define STV090x_P2_DSTATUS STV090x_Px_DSTATUS(2)
822#define STV090x_OFFST_Px_CAR_LOCK_FIELD 7
823#define STV090x_WIDTH_Px_CAR_LOCK_FIELD 1
824#define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5
825#define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2
826#define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD 3
827#define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD 1
828
829#define STV090x_Px_DSTATUS2(__x) (0xF413 - (__x - 1) * 0x200)
830#define STV090x_P1_DSTATUS2 STV090x_Px_DSTATUS2(1)
831#define STV090x_P2_DSTATUS2 STV090x_Px_DSTATUS2(2)
832#define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD 7
833#define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD 1
834#define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD 3
835#define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD 1
836#define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD 2
837#define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD 1
838#define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD 1
839#define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD 1
840#define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0
841#define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1
842
843#define STV090x_Px_DMDCFGMD(__x) (0xF414 - (__x - 1) * 0x200)
844#define STV090x_P1_DMDCFGMD STV090x_Px_DMDCFGMD(1)
845#define STV090x_P2_DMDCFGMD STV090x_Px_DMDCFGMD(2)
846#define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD 7
847#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1
848#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6
849#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1
850#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 5 /* check */
851#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1
852#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4 /* check */
853#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1
854#define STV090x_OFFST_Px_TUN_AUTOSCAN_FIELD 3
855#define STV090x_WIDTH_Px_TUN_AUTOSCAN_FIELD 1
856#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2
857#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1
858#define STV090x_OFFST_Px_TUN_RNG_FIELD 0
859#define STV090x_WIDTH_Px_TUN_RNG_FIELD 2
860
861#define STV090x_Px_DMDCFG2(__x) (0xF415 - (__x - 1) * 0x200)
862#define STV090x_P1_DMDCFG2 STV090x_Px_DMDCFG2(1)
863#define STV090x_P2_DMDCFG2 STV090x_Px_DMDCFG2(2)
864#define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6
865#define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1
866
867#define STV090x_Px_DMDISTATE(__x) (0xF416 - (__x - 1) * 0x200)
868#define STV090x_P1_DMDISTATE STV090x_Px_DMDISTATE(1)
869#define STV090x_P2_DMDISTATE STV090x_Px_DMDISTATE(2)
870#define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD 0
871#define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD 5
872
873#define STV090x_Px_DMDTOM(__x) (0xF417 - (__x - 1) * 0x200) /* check */
874#define STV090x_P1_DMDTOM STV090x_Px_DMDTOM(1)
875#define STV090x_P2_DMDTOM STV090x_Px_DMDTOM(2)
876
877#define STV090x_Px_DMDSTATE(__x) (0xF41B - (__x - 1) * 0x200)
878#define STV090x_P1_DMDSTATE STV090x_Px_DMDSTATE(1)
879#define STV090x_P2_DMDSTATE STV090x_Px_DMDSTATE(2)
880#define STV090x_OFFST_Px_HEADER_MODE_FIELD 5
881#define STV090x_WIDTH_Px_HEADER_MODE_FIELD 2
882
883#define STV090x_Px_DMDFLYW(__x) (0xF41C - (__x - 1) * 0x200)
884#define STV090x_P1_DMDFLYW STV090x_Px_DMDFLYW(1)
885#define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2)
886#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4
887#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4
888#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0 /* check */
889#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4
890
891#define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200)
892#define STV090x_P1_DSTATUS3 STV090x_Px_DSTATUS3(1)
893#define STV090x_P2_DSTATUS3 STV090x_Px_DSTATUS3(2)
894#define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD 5
895#define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD 2
896
897#define STV090x_Px_DMDCFG3(__x) (0xF41E - (__x - 1) * 0x200)
898#define STV090x_P1_DMDCFG3 STV090x_Px_DMDCFG3(1)
899#define STV090x_P2_DMDCFG3 STV090x_Px_DMDCFG3(2)
900#define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3
901#define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1
902
903#define STV090x_Px_DMDCFG4(__x) (0xf41f - (__x - 1) * 0x200)
904#define STV090x_P1_DMDCFG4 STV090x_Px_DMDCFG4(1)
905#define STV090x_P2_DMDCFG4 STV090x_Px_DMDCFG4(2)
906
907#define STV090x_Px_CORRELMANT(__x) (0xF420 - (__x - 1) * 0x200)
908#define STV090x_P1_CORRELMANT STV090x_Px_CORRELMANT(1)
909#define STV090x_P2_CORRELMANT STV090x_Px_CORRELMANT(2)
910#define STV090x_OFFST_Px_CORREL_MANT_FIELD 0
911#define STV090x_WIDTH_Px_CORREL_MANT_FIELD 8
912
913#define STV090x_Px_CORRELABS(__x) (0xF421 - (__x - 1) * 0x200)
914#define STV090x_P1_CORRELABS STV090x_Px_CORRELABS(1)
915#define STV090x_P2_CORRELABS STV090x_Px_CORRELABS(2)
916#define STV090x_OFFST_Px_CORREL_ABS_FIELD 0
917#define STV090x_WIDTH_Px_CORREL_ABS_FIELD 8
918
919#define STV090x_Px_CORRELEXP(__x) (0xF422 - (__x - 1) * 0x200)
920#define STV090x_P1_CORRELEXP STV090x_Px_CORRELEXP(1)
921#define STV090x_P2_CORRELEXP STV090x_Px_CORRELEXP(2)
922#define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD 4
923#define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD 4
924#define STV090x_OFFST_Px_CORREL_EXP_FIELD 0
925#define STV090x_WIDTH_Px_CORREL_EXP_FIELD 4
926
927#define STV090x_Px_PLHMODCOD(__x) (0xF424 - (__x - 1) * 0x200)
928#define STV090x_P1_PLHMODCOD STV090x_Px_PLHMODCOD(1)
929#define STV090x_P2_PLHMODCOD STV090x_Px_PLHMODCOD(2)
930#define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD 7
931#define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD 1
932#define STV090x_OFFST_Px_PLH_MODCOD_FIELD 2
933#define STV090x_WIDTH_Px_PLH_MODCOD_FIELD 5
934#define STV090x_OFFST_Px_PLH_TYPE_FIELD 0
935#define STV090x_WIDTH_Px_PLH_TYPE_FIELD 2
936
937#define STV090x_Px_AGCK32(__x) (0xf42b - (__x - 1) * 0x200)
938#define STV090x_P1_AGCK32 STV090x_Px_AGCK32(1)
939#define STV090x_P2_AGCK32 STV090x_Px_AGCK32(2)
940
941#define STV090x_Px_AGC2O(__x) (0xF42C - (__x - 1) * 0x200)
942#define STV090x_P1_AGC2O STV090x_Px_AGC2O(1)
943#define STV090x_P2_AGC2O STV090x_Px_AGC2O(2)
944
945#define STV090x_Px_AGC2REF(__x) (0xF42D - (__x - 1) * 0x200)
946#define STV090x_P1_AGC2REF STV090x_Px_AGC2REF(1)
947#define STV090x_P2_AGC2REF STV090x_Px_AGC2REF(2)
948#define STV090x_OFFST_Px_AGC2_REF_FIELD 0
949#define STV090x_WIDTH_Px_AGC2_REF_FIELD 8
950
951#define STV090x_Px_AGC1ADJ(__x) (0xF42E - (__x - 1) * 0x200)
952#define STV090x_P1_AGC1ADJ STV090x_Px_AGC1ADJ(1)
953#define STV090x_P2_AGC1ADJ STV090x_Px_AGC1ADJ(2)
954#define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD 0
955#define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD 7
956
957#define STV090x_Px_AGC2Iy(__x, __y) (0xF437 - (__x - 1) * 0x200 - __y * 0x1)
958#define STV090x_P1_AGC2I0 STV090x_Px_AGC2Iy(1, 0)
959#define STV090x_P1_AGC2I1 STV090x_Px_AGC2Iy(1, 1)
960#define STV090x_P2_AGC2I0 STV090x_Px_AGC2Iy(2, 0)
961#define STV090x_P2_AGC2I1 STV090x_Px_AGC2Iy(2, 1)
962#define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0
963#define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8
964
965#define STV090x_Px_CARCFG(__x) (0xF438 - (__x - 1) * 0x200)
966#define STV090x_P1_CARCFG STV090x_Px_CARCFG(1)
967#define STV090x_P2_CARCFG STV090x_Px_CARCFG(2)
968#define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD 5
969#define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD 1
970#define STV090x_OFFST_Px_ROTATON_FIELD 2
971#define STV090x_WIDTH_Px_ROTATON_FIELD 1
972#define STV090x_OFFST_Px_PH_DET_ALGO_FIELD 0
973#define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD 2
974
975#define STV090x_Px_ACLC(__x) (0xF439 - (__x - 1) * 0x200)
976#define STV090x_P1_ACLC STV090x_Px_ACLC(1)
977#define STV090x_P2_ACLC STV090x_Px_ACLC(2)
978#define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD 4
979#define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD 2
980#define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD 0
981#define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD 4
982
983#define STV090x_Px_BCLC(__x) (0xF43A - (__x - 1) * 0x200)
984#define STV090x_P1_BCLC STV090x_Px_BCLC(1)
985#define STV090x_P2_BCLC STV090x_Px_BCLC(2)
986#define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD 4
987#define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD 2
988#define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD 0
989#define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD 4
990
991#define STV090x_Px_CARFREQ(__x) (0xF43D - (__x - 1) * 0x200)
992#define STV090x_P1_CARFREQ STV090x_Px_CARFREQ(1)
993#define STV090x_P2_CARFREQ STV090x_Px_CARFREQ(2)
994#define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD 4
995#define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD 4
996#define STV090x_OFFST_Px_BETA_FREQ_FIELD 0
997#define STV090x_WIDTH_Px_BETA_FREQ_FIELD 4
998
999#define STV090x_Px_CARHDR(__x) (0xF43E - (__x - 1) * 0x200)
1000#define STV090x_P1_CARHDR STV090x_Px_CARHDR(1)
1001#define STV090x_P2_CARHDR STV090x_Px_CARHDR(2)
1002#define STV090x_OFFST_Px_FREQ_HDR_FIELD 0
1003#define STV090x_WIDTH_Px_FREQ_HDR_FIELD 8
1004
1005#define STV090x_Px_LDT(__x) (0xF43F - (__x - 1) * 0x200)
1006#define STV090x_P1_LDT STV090x_Px_LDT(1)
1007#define STV090x_P2_LDT STV090x_Px_LDT(2)
1008#define STV090x_OFFST_Px_CARLOCK_THRES_FIELD 0
1009#define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD 8
1010
1011#define STV090x_Px_LDT2(__x) (0xF440 - (__x - 1) * 0x200)
1012#define STV090x_P1_LDT2 STV090x_Px_LDT2(1)
1013#define STV090x_P2_LDT2 STV090x_Px_LDT2(2)
1014#define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD 0
1015#define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD 8
1016
1017#define STV090x_Px_CFRICFG(__x) (0xF441 - (__x - 1) * 0x200)
1018#define STV090x_P1_CFRICFG STV090x_Px_CFRICFG(1)
1019#define STV090x_P2_CFRICFG STV090x_Px_CFRICFG(2)
1020#define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD 0
1021#define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD 1
1022
1023#define STV090x_Pn_CFRUPy(__x, __y) (0xF443 - (__x - 1) * 0x200 - __y * 0x1)
1024#define STV090x_P1_CFRUP0 STV090x_Pn_CFRUPy(1, 0)
1025#define STV090x_P1_CFRUP1 STV090x_Pn_CFRUPy(1, 1)
1026#define STV090x_P2_CFRUP0 STV090x_Pn_CFRUPy(2, 0)
1027#define STV090x_P2_CFRUP1 STV090x_Pn_CFRUPy(2, 1)
1028#define STV090x_OFFST_Px_CFR_UP_FIELD 0
1029#define STV090x_WIDTH_Px_CFR_UP_FIELD 8
1030
1031#define STV090x_Pn_CFRLOWy(__x, __y) (0xF447 - (__x - 1) * 0x200 - __y * 0x1)
1032#define STV090x_P1_CFRLOW0 STV090x_Pn_CFRLOWy(1, 0)
1033#define STV090x_P1_CFRLOW1 STV090x_Pn_CFRLOWy(1, 1)
1034#define STV090x_P2_CFRLOW0 STV090x_Pn_CFRLOWy(2, 0)
1035#define STV090x_P2_CFRLOW1 STV090x_Pn_CFRLOWy(2, 1)
1036#define STV090x_OFFST_Px_CFR_LOW_FIELD 0
1037#define STV090x_WIDTH_Px_CFR_LOW_FIELD 8
1038
1039#define STV090x_Pn_CFRINITy(__x, __y) (0xF449 - (__x - 1) * 0x200 - __y * 0x1)
1040#define STV090x_P1_CFRINIT0 STV090x_Pn_CFRINITy(1, 0)
1041#define STV090x_P1_CFRINIT1 STV090x_Pn_CFRINITy(1, 1)
1042#define STV090x_P2_CFRINIT0 STV090x_Pn_CFRINITy(2, 0)
1043#define STV090x_P2_CFRINIT1 STV090x_Pn_CFRINITy(2, 1)
1044#define STV090x_OFFST_Px_CFR_INIT_FIELD 0
1045#define STV090x_WIDTH_Px_CFR_INIT_FIELD 8
1046
1047#define STV090x_Px_CFRINC1(__x) (0xF44A - (__x - 1) * 0x200)
1048#define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1)
1049#define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2)
1050#define STV090x_OFFST_Px_CFR_INC1_FIELD 0
1051#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7
1052
1053#define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200)
1054#define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1)
1055#define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2)
1056#define STV090x_OFFST_Px_CFR_INC0_FIELD 4
1057#define STV090x_WIDTH_Px_CFR_INC0_FIELD 4
1058
1059#define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1)
1060#define STV090x_P1_CFR0 STV090x_Pn_CFRy(1, 0)
1061#define STV090x_P1_CFR1 STV090x_Pn_CFRy(1, 1)
1062#define STV090x_P1_CFR2 STV090x_Pn_CFRy(1, 2)
1063#define STV090x_P2_CFR0 STV090x_Pn_CFRy(2, 0)
1064#define STV090x_P2_CFR1 STV090x_Pn_CFRy(2, 1)
1065#define STV090x_P2_CFR2 STV090x_Pn_CFRy(2, 2)
1066#define STV090x_OFFST_Px_CAR_FREQ_FIELD 0
1067#define STV090x_WIDTH_Px_CAR_FREQ_FIELD 8
1068
1069#define STV090x_Px_LDI(__x) (0xF44F - (__x - 1) * 0x200)
1070#define STV090x_P1_LDI STV090x_Px_LDI(1)
1071#define STV090x_P2_LDI STV090x_Px_LDI(2)
1072#define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0
1073#define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8
1074
1075#define STV090x_Px_TMGCFG(__x) (0xF450 - (__x - 1) * 0x200)
1076#define STV090x_P1_TMGCFG STV090x_Px_TMGCFG(1)
1077#define STV090x_P2_TMGCFG STV090x_Px_TMGCFG(2)
1078#define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD 6
1079#define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD 2
1080#define STV090x_OFFST_Px_DO_TIMING_FIELD 4
1081#define STV090x_WIDTH_Px_DO_TIMING_FIELD 1
1082#define STV090x_OFFST_Px_TMG_MINFREQ_FIELD 0
1083#define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD 2
1084
1085#define STV090x_Px_RTC(__x) (0xF451 - (__x - 1) * 0x200)
1086#define STV090x_P1_RTC STV090x_Px_RTC(1)
1087#define STV090x_P2_RTC STV090x_Px_RTC(2)
1088#define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD 4
1089#define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD 4
1090#define STV090x_OFFST_Px_TMGBETA_EXP_FIELD 0
1091#define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD 4
1092
1093#define STV090x_Px_RTCS2(__x) (0xF452 - (__x - 1) * 0x200)
1094#define STV090x_P1_RTCS2 STV090x_Px_RTCS2(1)
1095#define STV090x_P2_RTCS2 STV090x_Px_RTCS2(2)
1096#define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD 4
1097#define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD 4
1098#define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD 0
1099#define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD 4
1100
1101#define STV090x_Px_TMGTHRISE(__x) (0xF453 - (__x - 1) * 0x200)
1102#define STV090x_P1_TMGTHRISE STV090x_Px_TMGTHRISE(1)
1103#define STV090x_P2_TMGTHRISE STV090x_Px_TMGTHRISE(2)
1104#define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD 0
1105#define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD 8
1106
1107#define STV090x_Px_TMGTHFALL(__x) (0xF454 - (__x - 1) * 0x200)
1108#define STV090x_P1_TMGTHFALL STV090x_Px_TMGTHFALL(1)
1109#define STV090x_P2_TMGTHFALL STV090x_Px_TMGTHFALL(2)
1110#define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD 0
1111#define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD 8
1112
1113#define STV090x_Px_SFRUPRATIO(__x) (0xF455 - (__x - 1) * 0x200)
1114#define STV090x_P1_SFRUPRATIO STV090x_Px_SFRUPRATIO(1)
1115#define STV090x_P2_SFRUPRATIO STV090x_Px_SFRUPRATIO(2)
1116#define STV090x_OFFST_Px_SFR_UPRATIO_FIELD 0
1117#define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD 8
1118
1119#define STV090x_Px_SFRLOWRATIO(__x) (0xF456 - (__x - 1) * 0x200)
1120#define STV090x_P1_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(1)
1121#define STV090x_P2_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(2)
1122#define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD 0
1123#define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD 8
1124
1125#define STV090x_Px_KREFTMG(__x) (0xF458 - (__x - 1) * 0x200)
1126#define STV090x_P1_KREFTMG STV090x_Px_KREFTMG(1)
1127#define STV090x_P2_KREFTMG STV090x_Px_KREFTMG(2)
1128#define STV090x_OFFST_Px_KREF_TMG_FIELD 0
1129#define STV090x_WIDTH_Px_KREF_TMG_FIELD 8
1130
1131#define STV090x_Px_SFRSTEP(__x) (0xF459 - (__x - 1) * 0x200)
1132#define STV090x_P1_SFRSTEP STV090x_Px_SFRSTEP(1)
1133#define STV090x_P2_SFRSTEP STV090x_Px_SFRSTEP(2)
1134#define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD 4
1135#define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD 4
1136#define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD 0
1137#define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD 4
1138
1139#define STV090x_Px_TMGCFG2(__x) (0xF45A - (__x - 1) * 0x200)
1140#define STV090x_P1_TMGCFG2 STV090x_Px_TMGCFG2(1)
1141#define STV090x_P2_TMGCFG2 STV090x_Px_TMGCFG2(2)
1142#define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD 0
1143#define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD 1
1144
1145#define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200)
1146#define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1)
1147#define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2)
1148#define STV090x_OFFST_Px_SFR_INIT_FIELD 0
1149#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8
1150
1151#define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200)
1152#define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1)
1153#define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2)
1154#define STV090x_OFFST_Px_SFR_INIT_FIELD 0
1155#define STV090x_WIDTH_Px_SFR_INIT_FIELD 8
1156
1157#define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200)
1158#define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1)
1159#define STV090x_P2_SFRUP1 STV090x_Px_SFRUP1(2)
1160#define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD 0
1161#define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD 7
1162
1163#define STV090x_Px_SFRUP0(__x) (0xF461 - (__x - 1) * 0x200)
1164#define STV090x_P1_SFRUP0 STV090x_Px_SFRUP0(1)
1165#define STV090x_P2_SFRUP0 STV090x_Px_SFRUP0(2)
1166#define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD 0
1167#define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD 8
1168
1169#define STV090x_Px_SFRLOW1(__x) (0xF462 - (__x - 1) * 0x200)
1170#define STV090x_P1_SFRLOW1 STV090x_Px_SFRLOW1(1)
1171#define STV090x_P2_SFRLOW1 STV090x_Px_SFRLOW1(2)
1172#define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD 0
1173#define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD 7
1174
1175#define STV090x_Px_SFRLOW0(__x) (0xF463 - (__x - 1) * 0x200)
1176#define STV090x_P1_SFRLOW0 STV090x_Px_SFRLOW0(1)
1177#define STV090x_P2_SFRLOW0 STV090x_Px_SFRLOW0(2)
1178#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0
1179#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8
1180
1181#define STV090x_Px_SFRy(__x, __y) (0xF464 - (__x-1) * 0x200 + (3 - __y))
1182#define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0)
1183#define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1)
1184#define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2)
1185#define STV090x_P1_SFR3 STV090x_Px_SFRy(1, 3)
1186#define STV090x_P2_SFR0 STV090x_Px_SFRy(2, 0)
1187#define STV090x_P2_SFR1 STV090x_Px_SFRy(2, 1)
1188#define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2)
1189#define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3)
1190#define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0
1191#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 32
1192
1193#define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200)
1194#define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1)
1195#define STV090x_P2_TMGREG2 STV090x_Px_TMGREG2(2)
1196#define STV090x_OFFST_Px_TMGREG_FIELD 0
1197#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1198
1199#define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200)
1200#define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1)
1201#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2)
1202#define STV090x_OFFST_Px_TMGREG_FIELD 0
1203#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1204
1205#define STV090x_Px_TMGREG0(__x) (0xF46A - (__x - 1) * 0x200)
1206#define STV090x_P1_TMGREG0 STV090x_Px_TMGREG0(1)
1207#define STV090x_P2_TMGREG0 STV090x_Px_TMGREG0(2)
1208#define STV090x_OFFST_Px_TMGREG_FIELD 0
1209#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1210
1211#define STV090x_Px_TMGLOCKy(__x, __y) (0xF46C - (__x - 1) * 0x200 - __y * 0x1)
1212#define STV090x_P1_TMGLOCK0 STV090x_Px_TMGLOCKy(1, 0)
1213#define STV090x_P1_TMGLOCK1 STV090x_Px_TMGLOCKy(1, 1)
1214#define STV090x_P2_TMGLOCK0 STV090x_Px_TMGLOCKy(2, 0)
1215#define STV090x_P2_TMGLOCK1 STV090x_Px_TMGLOCKy(2, 1)
1216#define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD 0
1217#define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD 8
1218
1219#define STV090x_Px_TMGOBS(__x) (0xF46D - (__x - 1) * 0x200)
1220#define STV090x_P1_TMGOBS STV090x_Px_TMGOBS(1)
1221#define STV090x_P2_TMGOBS STV090x_Px_TMGOBS(2)
1222#define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD 6
1223#define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD 2
1224
1225#define STV090x_Px_EQUALCFG(__x) (0xF46F - (__x - 1) * 0x200)
1226#define STV090x_P1_EQUALCFG STV090x_Px_EQUALCFG(1)
1227#define STV090x_P2_EQUALCFG STV090x_Px_EQUALCFG(2)
1228#define STV090x_OFFST_Px_EQUAL_ON_FIELD 6
1229#define STV090x_WIDTH_Px_EQUAL_ON_FIELD 1
1230#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0
1231#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3
1232
1233#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x - 1) * 0x200 + (__y - 1))
1234#define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1)
1235#define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2)
1236#define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3)
1237#define STV090x_P1_EQUAI4 STV090x_Px_EQUAIy(1, 4)
1238#define STV090x_P1_EQUAI5 STV090x_Px_EQUAIy(1, 5)
1239#define STV090x_P1_EQUAI6 STV090x_Px_EQUAIy(1, 6)
1240#define STV090x_P1_EQUAI7 STV090x_Px_EQUAIy(1, 7)
1241#define STV090x_P1_EQUAI8 STV090x_Px_EQUAIy(1, 8)
1242
1243#define STV090x_P2_EQUAI1 STV090x_Px_EQUAIy(2, 1)
1244#define STV090x_P2_EQUAI2 STV090x_Px_EQUAIy(2, 2)
1245#define STV090x_P2_EQUAI3 STV090x_Px_EQUAIy(2, 3)
1246#define STV090x_P2_EQUAI4 STV090x_Px_EQUAIy(2, 4)
1247#define STV090x_P2_EQUAI5 STV090x_Px_EQUAIy(2, 5)
1248#define STV090x_P2_EQUAI6 STV090x_Px_EQUAIy(2, 6)
1249#define STV090x_P2_EQUAI7 STV090x_Px_EQUAIy(2, 7)
1250#define STV090x_P2_EQUAI8 STV090x_Px_EQUAIy(2, 8)
1251#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0
1252#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8
1253
1254#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x - 1) * 0x200 + (__y - 1))
1255#define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1)
1256#define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2)
1257#define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3)
1258#define STV090x_P1_EQUAQ4 STV090x_Px_EQUAQy(1, 4)
1259#define STV090x_P1_EQUAQ5 STV090x_Px_EQUAQy(1, 5)
1260#define STV090x_P1_EQUAQ6 STV090x_Px_EQUAQy(1, 6)
1261#define STV090x_P1_EQUAQ7 STV090x_Px_EQUAQy(1, 7)
1262#define STV090x_P1_EQUAQ8 STV090x_Px_EQUAQy(1, 8)
1263
1264#define STV090x_P2_EQUAQ1 STV090x_Px_EQUAQy(2, 1)
1265#define STV090x_P2_EQUAQ2 STV090x_Px_EQUAQy(2, 2)
1266#define STV090x_P2_EQUAQ3 STV090x_Px_EQUAQy(2, 3)
1267#define STV090x_P2_EQUAQ4 STV090x_Px_EQUAQy(2, 4)
1268#define STV090x_P2_EQUAQ5 STV090x_Px_EQUAQy(2, 5)
1269#define STV090x_P2_EQUAQ6 STV090x_Px_EQUAQy(2, 6)
1270#define STV090x_P2_EQUAQ7 STV090x_Px_EQUAQy(2, 7)
1271#define STV090x_P2_EQUAQ8 STV090x_Px_EQUAQy(2, 8)
1272#define STV090x_OFFST_Px_EQUA_ACCQy_FIELD 0
1273#define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD 8
1274
1275#define STV090x_Px_NNOSDATATy(__x, __y) (0xf481 - (__x - 1) * 0x200 - __y * 0x1)
1276#define STV090x_P1_NNOSDATAT0 STV090x_Px_NNOSDATATy(1, 0)
1277#define STV090x_P1_NNOSDATAT1 STV090x_Px_NNOSDATATy(1, 1)
1278#define STV090x_P2_NNOSDATAT0 STV090x_Px_NNOSDATATy(2, 0)
1279#define STV090x_P2_NNOSDATAT1 STV090x_Px_NNOSDATATy(2, 1)
1280#define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0
1281#define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8
1282
1283#define STV090x_Px_NNOSDATAy(__x, __y) (0xf483 - (__x - 1) * 0x200 - __y * 0x1)
1284#define STV090x_P1_NNOSDATA0 STV090x_Px_NNOSDATAy(1, 0)
1285#define STV090x_P1_NNOSDATA1 STV090x_Px_NNOSDATAy(1, 1)
1286#define STV090x_P2_NNOSDATA0 STV090x_Px_NNOSDATAy(2, 0)
1287#define STV090x_P2_NNOSDATA1 STV090x_Px_NNOSDATAy(2, 1)
1288#define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD 0
1289#define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD 8
1290
1291#define STV090x_Px_NNOSPLHTy(__x, __y) (0xf485 - (__x - 1) * 0x200 - __y * 0x1)
1292#define STV090x_P1_NNOSPLHT0 STV090x_Px_NNOSPLHTy(1, 0)
1293#define STV090x_P1_NNOSPLHT1 STV090x_Px_NNOSPLHTy(1, 1)
1294#define STV090x_P2_NNOSPLHT0 STV090x_Px_NNOSPLHTy(2, 0)
1295#define STV090x_P2_NNOSPLHT1 STV090x_Px_NNOSPLHTy(2, 1)
1296#define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD 0
1297#define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD 8
1298
1299#define STV090x_Px_NNOSPLHy(__x, __y) (0xf487 - (__x - 1) * 0x200 - __y * 0x1)
1300#define STV090x_P1_NNOSPLH0 STV090x_Px_NNOSPLHy(1, 0)
1301#define STV090x_P1_NNOSPLH1 STV090x_Px_NNOSPLHy(1, 1)
1302#define STV090x_P2_NNOSPLH0 STV090x_Px_NNOSPLHy(2, 0)
1303#define STV090x_P2_NNOSPLH1 STV090x_Px_NNOSPLHy(2, 1)
1304#define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD 0
1305#define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD 8
1306
1307#define STV090x_Px_NOSDATATy(__x, __y) (0xf489 - (__x - 1) * 0x200 - __y * 0x1)
1308#define STV090x_P1_NOSDATAT0 STV090x_Px_NOSDATATy(1, 0)
1309#define STV090x_P1_NOSDATAT1 STV090x_Px_NOSDATATy(1, 1)
1310#define STV090x_P2_NOSDATAT0 STV090x_Px_NOSDATATy(2, 0)
1311#define STV090x_P2_NOSDATAT1 STV090x_Px_NOSDATATy(2, 1)
1312#define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD 0
1313#define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD 8
1314
1315#define STV090x_Px_NOSDATAy(__x, __y) (0xf48b - (__x - 1) * 0x200 - __y * 0x1)
1316#define STV090x_P1_NOSDATA0 STV090x_Px_NOSDATAy(1, 0)
1317#define STV090x_P1_NOSDATA1 STV090x_Px_NOSDATAy(1, 1)
1318#define STV090x_P2_NOSDATA0 STV090x_Px_NOSDATAy(2, 0)
1319#define STV090x_P2_NOSDATA1 STV090x_Px_NOSDATAy(2, 1)
1320#define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD 0
1321#define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD 8
1322
1323#define STV090x_Px_NOSPLHTy(__x, __y) (0xf48d - (__x - 1) * 0x200 - __y * 0x1)
1324#define STV090x_P1_NOSPLHT0 STV090x_Px_NOSPLHTy(1, 0)
1325#define STV090x_P1_NOSPLHT1 STV090x_Px_NOSPLHTy(1, 1)
1326#define STV090x_P2_NOSPLHT0 STV090x_Px_NOSPLHTy(2, 0)
1327#define STV090x_P2_NOSPLHT1 STV090x_Px_NOSPLHTy(2, 1)
1328#define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD 0
1329#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8
1330
1331#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
1332#define STv090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0)
1333#define STv090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1)
1334#define STv090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0)
1335#define STv090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1)
1336#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
1337#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
1338
1339#define STV090x_Px_CAR2CFG(__x) (0xf490 - (__x - 1) * 0x200)
1340#define STV090x_P1_CAR2CFG STV090x_Px_CAR2CFG(1)
1341#define STV090x_P2_CAR2CFG STV090x_Px_CAR2CFG(2)
1342#define STV090x_OFFST_Px_PN4_SELECT_FIELD 6
1343#define STV090x_WIDTH_Px_PN4_SELECT_FIELD 1
1344#define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD 5
1345#define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD 1
1346#define STV090x_OFFST_Px_ROTA2ON_FIELD 2
1347#define STV090x_WIDTH_Px_ROTA2ON_FIELD 1
1348#define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD 0
1349#define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD 2
1350
1351#define STV090x_Px_ACLC2(__x) (0xf491 - (__x - 1) * 0x200)
1352#define STV090x_P1_ACLC2 STV090x_Px_ACLC2(1)
1353#define STV090x_P2_ACLC2 STV090x_Px_ACLC2(2)
1354#define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4
1355#define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2
1356#define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD 0
1357#define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD 4
1358
1359#define STV090x_Px_BCLC2(__x) (0xf492 - (__x - 1) * 0x200)
1360#define STV090x_P1_BCLC2 STV090x_Px_BCLC2(1)
1361#define STV090x_P2_BCLC2 STV090x_Px_BCLC2(2)
1362#define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD 4
1363#define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD 2
1364#define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD 0
1365#define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD 4
1366
1367#define STV090x_Px_ACLC2S2Q(__x) (0xf497 - (__x - 1) * 0x200)
1368#define STV090x_P1_ACLC2S2Q STV090x_Px_ACLC2S2Q(1)
1369#define STV090x_P2_ACLC2S2Q STV090x_Px_ACLC2S2Q(2)
1370#define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD 7
1371#define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD 1
1372#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4
1373#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2
1374#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0
1375#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4
1376
1377#define STV090x_Px_ACLC2S28(__x) (0xf498 - (__x - 1) * 0x200)
1378#define STV090x_P1_ACLC2S28 STV090x_Px_ACLC2S28(1)
1379#define STV090x_P2_ACLC2S28 STV090x_Px_ACLC2S28(2)
1380#define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4
1381#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2
1382#define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0
1383#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4
1384
1385#define STV090x_Px_ACLC2S216A(__x) (0xf499 - (__x - 1) * 0x200)
1386#define STV090x_P1_ACLC2S216A STV090x_Px_ACLC2S216A(1)
1387#define STV090x_P2_ACLC2S216A STV090x_Px_ACLC2S216A(2)
1388#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD 4
1389#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD 2
1390#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0
1391#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4
1392
1393#define STV090x_Px_ACLC2S232A(__x) (0xf499 - (__x - 1) * 0x200)
1394#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1)
1395#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2)
1396#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4
1397#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD 2
1398#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD 0
1399#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD 4
1400
1401#define STV090x_Px_BCLC2S2Q(__x) (0xf49c - (__x - 1) * 0x200)
1402#define STV090x_P1_BCLC2S2Q STV090x_Px_BCLC2S2Q(1)
1403#define STV090x_P2_BCLC2S2Q STV090x_Px_BCLC2S2Q(2)
1404#define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4
1405#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2
1406#define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0
1407#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4
1408
1409#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200)
1410#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1)
1411#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(1)
1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
1413#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
1414#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
1415#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4
1416
1417#define STV090x_Px_BCLC2S216A(__x) (0xf49d - (__x - 1) * 0x200)
1418#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1419#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4
1421#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2
1422#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0
1423#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4
1424
1425#define STV090x_Px_BCLC2S232A(__x) (0xf49d - (__x - 1) * 0x200)
1426#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1427#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4
1429#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2
1430#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0
1431#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD 4
1432
1433#define STV090x_Px_PLROOT2(__x) (0xf4ac - (__x - 1) * 0x200)
1434#define STV090x_P1_PLROOT2 STV090x_Px_PLROOT2(1)
1435#define STV090x_P2_PLROOT2 STV090x_Px_PLROOT2(2)
1436#define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD 2
1437#define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD 2
1438#define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD 0
1439#define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD 2
1440
1441#define STV090x_Px_PLROOT1(__x) (0xf4ad - (__x - 1) * 0x200)
1442#define STV090x_P1_PLROOT1 STV090x_Px_PLROOT1(1)
1443#define STV090x_P2_PLROOT1 STV090x_Px_PLROOT1(2)
1444#define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD 0
1445#define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD 8
1446
1447#define STV090x_Px_PLROOT0(__x) (0xf4ae - (__x - 1) * 0x200)
1448#define STV090x_P1_PLROOT0 STV090x_Px_PLROOT0(1)
1449#define STV090x_P2_PLROOT0 STV090x_Px_PLROOT0(2)
1450#define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD 0
1451#define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD 8
1452
1453#define STV090x_Px_MODCODLST0(__x) (0xf4b0 - (__x - 1) * 0x200) /* check */
1454#define STV090x_P1_MODCODLST0 STV090x_Px_MODCODLST0(1)
1455#define STV090x_P2_MODCODLST0 STV090x_Px_MODCODLST0(2)
1456
1457#define STV090x_Px_MODCODLST1(__x) (0xf4b1 - (__x - 1) * 0x200)
1458#define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1)
1459#define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2)
1460#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4
1461#define STV090x_WIDTH_Px_DIS_MODCOD29T_FIELD 4
1462#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0
1463#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4
1464
1465#define STV090x_Px_MODCODLST2(__x) (0xf4b2 - (__x - 1) * 0x200)
1466#define STV090x_P1_MODCODLST2 STV090x_Px_MODCODLST2(1)
1467#define STV090x_P2_MODCODLST2 STV090x_Px_MODCODLST2(2)
1468#define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD 4
1469#define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD 4
1470#define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD 0
1471#define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD 4
1472
1473#define STV090x_Px_MODCODLST3(__x) (0xf4b3 - (__x - 1) * 0x200)
1474#define STV090x_P1_MODCODLST3 STV090x_Px_MODCODLST3(1)
1475#define STV090x_P2_MODCODLST3 STV090x_Px_MODCODLST3(2)
1476#define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD 4
1477#define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD 4
1478#define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD 0
1479#define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD 4
1480
1481#define STV090x_Px_MODCODLST4(__x) (0xf4b4 - (__x - 1) * 0x200)
1482#define STV090x_P1_MODCODLST4 STV090x_Px_MODCODLST4(1)
1483#define STV090x_P2_MODCODLST4 STV090x_Px_MODCODLST4(2)
1484#define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD 4
1485#define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD 4
1486#define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD 0
1487#define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD 4
1488
1489#define STV090x_Px_MODCODLST5(__x) (0xf4b5 - (__x - 1) * 0x200)
1490#define STV090x_P1_MODCODLST5 STV090x_Px_MODCODLST5(1)
1491#define STV090x_P2_MODCODLST5 STV090x_Px_MODCODLST5(2)
1492#define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD 4
1493#define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD 4
1494#define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD 0
1495#define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD 4
1496
1497#define STV090x_Px_MODCODLST6(__x) (0xf4b6 - (__x - 1) * 0x200)
1498#define STV090x_P1_MODCODLST6 STV090x_Px_MODCODLST6(1)
1499#define STV090x_P2_MODCODLST6 STV090x_Px_MODCODLST6(2)
1500#define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD 4
1501#define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD 4
1502#define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD 0
1503#define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD 4
1504
1505#define STV090x_Px_MODCODLST7(__x) (0xf4b7 - (__x - 1) * 0x200)
1506#define STV090x_P1_MODCODLST7 STV090x_Px_MODCODLST7(1)
1507#define STV090x_P2_MODCODLST7 STV090x_Px_MODCODLST7(2)
1508#define STV090x_OFFST_Px_DIS_8P_9_10_FIELD 4
1509#define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD 4
1510#define STV090x_OFFST_Px_DIS_8P_8_9_FIELD 0
1511#define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD 4
1512
1513#define STV090x_Px_MODCODLST8(__x) (0xf4b8 - (__x - 1) * 0x200)
1514#define STV090x_P1_MODCODLST8 STV090x_Px_MODCODLST8(1)
1515#define STV090x_P2_MODCODLST8 STV090x_Px_MODCODLST8(2)
1516#define STV090x_OFFST_Px_DIS_8P_5_6_FIELD 4
1517#define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD 4
1518#define STV090x_OFFST_Px_DIS_8P_3_4_FIELD 0
1519#define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD 4
1520
1521#define STV090x_Px_MODCODLST9(__x) (0xf4b9 - (__x - 1) * 0x200)
1522#define STV090x_P1_MODCODLST9 STV090x_Px_MODCODLST9(1)
1523#define STV090x_P2_MODCODLST9 STV090x_Px_MODCODLST9(2)
1524#define STV090x_OFFST_Px_DIS_8P_2_3_FIELD 4
1525#define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD 4
1526#define STV090x_OFFST_Px_DIS_8P_3_5_FIELD 0
1527#define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD 4
1528
1529#define STV090x_Px_MODCODLSTA(__x) (0xf4ba - (__x - 1) * 0x200)
1530#define STV090x_P1_MODCODLSTA STV090x_Px_MODCODLSTA(1)
1531#define STV090x_P2_MODCODLSTA STV090x_Px_MODCODLSTA(2)
1532#define STV090x_OFFST_Px_DIS_QP_9_10_FIELD 4
1533#define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD 4
1534#define STV090x_OFFST_Px_DIS_QP_8_9_FIELD 0
1535#define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD 4
1536
1537#define STV090x_Px_MODCODLSTB(__x) (0xf4bb - (__x - 1) * 0x200)
1538#define STV090x_P1_MODCODLSTB STV090x_Px_MODCODLSTB(1)
1539#define STV090x_P2_MODCODLSTB STV090x_Px_MODCODLSTB(2)
1540#define STV090x_OFFST_Px_DIS_QP_5_6_FIELD 4
1541#define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD 4
1542#define STV090x_OFFST_Px_DIS_QP_4_5_FIELD 0
1543#define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD 4
1544
1545#define STV090x_Px_MODCODLSTC(__x) (0xf4bc - (__x - 1) * 0x200)
1546#define STV090x_P1_MODCODLSTC STV090x_Px_MODCODLSTC(1)
1547#define STV090x_P2_MODCODLSTC STV090x_Px_MODCODLSTC(2)
1548#define STV090x_OFFST_Px_DIS_QP_3_4_FIELD 4
1549#define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD 4
1550#define STV090x_OFFST_Px_DIS_QP_2_3_FIELD 0
1551#define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD 4
1552
1553#define STV090x_Px_MODCODLSTD(__x) (0xf4bd - (__x - 1) * 0x200)
1554#define STV090x_P1_MODCODLSTD STV090x_Px_MODCODLSTD(1)
1555#define STV090x_P2_MODCODLSTD STV090x_Px_MODCODLSTD(2)
1556#define STV090x_OFFST_Px_DIS_QP_3_5_FIELD 4
1557#define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD 4
1558#define STV090x_OFFST_Px_DIS_QP_1_2_FIELD 0
1559#define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD 4
1560
1561#define STV090x_Px_MODCODLSTE(__x) (0xf4be - (__x - 1) * 0x200)
1562#define STV090x_P1_MODCODLSTE STV090x_Px_MODCODLSTE(1)
1563#define STV090x_P2_MODCODLSTE STV090x_Px_MODCODLSTE(2)
1564#define STV090x_OFFST_Px_DIS_QP_2_5_FIELD 4
1565#define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD 4
1566#define STV090x_OFFST_Px_DIS_QP_1_3_FIELD 0
1567#define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD 4
1568
1569#define STV090x_Px_MODCODLSTF(__x) (0xf4bf - (__x - 1) * 0x200)
1570#define STV090x_P1_MODCODLSTF STV090x_Px_MODCODLSTF(1)
1571#define STV090x_P2_MODCODLSTF STV090x_Px_MODCODLSTF(2)
1572#define STV090x_OFFST_Px_DIS_QP_1_4_FIELD 4
1573#define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD 4
1574
1575#define STV090x_Px_GAUSSR0(__x) (0xf4c0 - (__x - 1) * 0x200)
1576#define STV090x_P1_GAUSSR0 STV090x_Px_GAUSSR0(1)
1577#define STV090x_P2_GAUSSR0 STV090x_Px_GAUSSR0(2)
1578#define STV090x_OFFST_Px_EN_CCIMODE_FIELD 7
1579#define STV090x_WIDTH_Px_EN_CCIMODE_FIELD 1
1580#define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD 0
1581#define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD 7
1582
1583#define STV090x_Px_CCIR0(__x) (0xf4c1 - (__x - 1) * 0x200)
1584#define STV090x_P1_CCIR0 STV090x_Px_CCIR0(1)
1585#define STV090x_P2_CCIR0 STV090x_Px_CCIR0(2)
1586#define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD 7
1587#define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD 1
1588#define STV090x_OFFST_Px_R0_CCI_FIELD 0
1589#define STV090x_WIDTH_Px_R0_CCI_FIELD 7
1590
1591#define STV090x_Px_CCIQUANT(__x) (0xf4c2 - (__x - 1) * 0x200)
1592#define STV090x_P1_CCIQUANT STV090x_Px_CCIQUANT(1)
1593#define STV090x_P2_CCIQUANT STV090x_Px_CCIQUANT(2)
1594#define STV090x_OFFST_Px_CCI_BETA_FIELD 5
1595#define STV090x_WIDTH_Px_CCI_BETA_FIELD 3
1596#define STV090x_OFFST_Px_CCI_QUANT_FIELD 0
1597#define STV090x_WIDTH_Px_CCI_QUANT_FIELD 5
1598
1599#define STV090x_Px_CCITHRESH(__x) (0xf4c3 - (__x - 1) * 0x200)
1600#define STV090x_P1_CCITHRESH STV090x_Px_CCITHRESH(1)
1601#define STV090x_P2_CCITHRESH STV090x_Px_CCITHRESH(2)
1602#define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD 0
1603#define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD 8
1604
1605#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200)
1606#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1)
1607#define STV090x_P2_CCIACC STV090x_Px_CCIACC(1)
1608#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0
1609#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8
1610
1611#define STV090x_Px_DMDRESCFG(__x) (0xF4C6 - (__x - 1) * 0x200)
1612#define STV090x_P1_DMDRESCFG STV090x_Px_DMDRESCFG(1)
1613#define STV090x_P2_DMDRESCFG STV090x_Px_DMDRESCFG(2)
1614#define STV090x_OFFST_Px_DMDRES_RESET_FIELD 7
1615#define STV090x_WIDTH_Px_DMDRES_RESET_FIELD 1
1616
1617#define STV090x_Px_DMDRESADR(__x) (0xF4C7 - (__x - 1) * 0x200)
1618#define STV090x_P1_DMDRESADR STV090x_Px_DMDRESADR(1)
1619#define STV090x_P2_DMDRESADR STV090x_Px_DMDRESADR(2)
1620#define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD 0
1621#define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD 4
1622
1623#define STV090x_Px_DMDRESDATAy(__x, __y) (0xF4C8 - (__x - 1) * 0x200 + (7 - __y))
1624#define STV090x_P1_DMDRESDATA0 STV090x_Px_DMDRESDATAy(1, 0)
1625#define STV090x_P1_DMDRESDATA1 STV090x_Px_DMDRESDATAy(1, 1)
1626#define STV090x_P1_DMDRESDATA2 STV090x_Px_DMDRESDATAy(1, 2)
1627#define STV090x_P1_DMDRESDATA3 STV090x_Px_DMDRESDATAy(1, 3)
1628#define STV090x_P1_DMDRESDATA4 STV090x_Px_DMDRESDATAy(1, 4)
1629#define STV090x_P1_DMDRESDATA5 STV090x_Px_DMDRESDATAy(1, 5)
1630#define STV090x_P1_DMDRESDATA6 STV090x_Px_DMDRESDATAy(1, 6)
1631#define STV090x_P1_DMDRESDATA7 STV090x_Px_DMDRESDATAy(1, 7)
1632#define STV090x_P2_DMDRESDATA0 STV090x_Px_DMDRESDATAy(2, 0)
1633#define STV090x_P2_DMDRESDATA1 STV090x_Px_DMDRESDATAy(2, 1)
1634#define STV090x_P2_DMDRESDATA2 STV090x_Px_DMDRESDATAy(2, 2)
1635#define STV090x_P2_DMDRESDATA3 STV090x_Px_DMDRESDATAy(2, 3)
1636#define STV090x_P2_DMDRESDATA4 STV090x_Px_DMDRESDATAy(2, 4)
1637#define STV090x_P2_DMDRESDATA5 STV090x_Px_DMDRESDATAy(2, 5)
1638#define STV090x_P2_DMDRESDATA6 STV090x_Px_DMDRESDATAy(2, 6)
1639#define STV090x_P2_DMDRESDATA7 STV090x_Px_DMDRESDATAy(2, 7)
1640#define STV090x_OFFST_Px_DMDRES_DATA_FIELD 0
1641#define STV090x_WIDTH_Px_DMDRES_DATA_FIELD 8
1642
1643#define STV090x_Px_FFEIy(__x, __y) (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
1644#define STV090x_P1_FFEI1 STV090x_Px_FFEIy(1, 1)
1645#define STV090x_P1_FFEI2 STV090x_Px_FFEIy(1, 2)
1646#define STV090x_P1_FFEI3 STV090x_Px_FFEIy(1, 3)
1647#define STV090x_P1_FFEI4 STV090x_Px_FFEIy(1, 4)
1648#define STV090x_P2_FFEI1 STV090x_Px_FFEIy(2, 1)
1649#define STV090x_P2_FFEI2 STV090x_Px_FFEIy(2, 2)
1650#define STV090x_P2_FFEI3 STV090x_Px_FFEIy(2, 3)
1651#define STV090x_P2_FFEI4 STV090x_Px_FFEIy(2, 4)
1652#define STV090x_OFFST_Px_FFE_ACCIy_FIELD 0
1653#define STV090x_WIDTH_Px_FFE_ACCIy_FIELD 8
1654
1655#define STV090x_Px_FFEQy(__x, __y) (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
1656#define STV090x_P1_FFEQ1 STV090x_Px_FFEQy(1, 1)
1657#define STV090x_P1_FFEQ2 STV090x_Px_FFEQy(1, 2)
1658#define STV090x_P1_FFEQ3 STV090x_Px_FFEQy(1, 3)
1659#define STV090x_P1_FFEQ4 STV090x_Px_FFEQy(1, 4)
1660#define STV090x_P2_FFEQ1 STV090x_Px_FFEQy(2, 1)
1661#define STV090x_P2_FFEQ2 STV090x_Px_FFEQy(2, 2)
1662#define STV090x_P2_FFEQ3 STV090x_Px_FFEQy(2, 3)
1663#define STV090x_P2_FFEQ4 STV090x_Px_FFEQy(2, 4)
1664#define STV090x_OFFST_Px_FFE_ACCQy_FIELD 0
1665#define STV090x_WIDTH_Px_FFE_ACCQy_FIELD 8
1666
1667#define STV090x_Px_FFECFG(__x) (0xf4d8 - (__x - 1) * 0x200)
1668#define STV090x_P1_FFECFG STV090x_Px_FFECFG(1)
1669#define STV090x_P2_FFECFG STV090x_Px_FFECFG(2)
1670#define STV090x_OFFST_Px_EQUALFFE_ON_FIELD 6
1671#define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD 1
1672
1673#define STV090x_Px_SMAPCOEF7(__x) (0xf500 - (__x - 1) * 0x200)
1674#define STV090x_P1_SMAPCOEF7 STV090x_Px_SMAPCOEF7(1)
1675#define STV090x_P2_SMAPCOEF7 STV090x_Px_SMAPCOEF7(2)
1676#define STV090x_OFFST_Px_DIS_QSCALE_FIELD 7
1677#define STV090x_WIDTH_Px_DIS_QSCALE_FIELD 1
1678#define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD 0
1679#define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD 7
1680
1681#define STV090x_Px_SMAPCOEF6(__x) (0xf501 - (__x - 1) * 0x200)
1682#define STV090x_P1_SMAPCOEF6 STV090x_Px_SMAPCOEF6(1)
1683#define STV090x_P2_SMAPCOEF6 STV090x_Px_SMAPCOEF6(2)
1684#define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD 2
1685#define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD 1
1686#define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD 1
1687#define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD 1
1688#define STV090x_OFFST_Px_DIS_AB8PSK_FIELD 0
1689#define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD 1
1690
1691#define STV090x_Px_SMAPCOEF5(__x) (0xf502 - (__x - 1) * 0x200)
1692#define STV090x_P1_SMAPCOEF5 STV090x_Px_SMAPCOEF5(1)
1693#define STV090x_P2_SMAPCOEF5 STV090x_Px_SMAPCOEF5(2)
1694#define STV090x_OFFST_Px_DIS_8SCALE_FIELD 7
1695#define STV090x_WIDTH_Px_DIS_8SCALE_FIELD 1
1696#define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD 0
1697#define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD 7
1698
1699#define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200)
1700#define STV090x_P1_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(1)
1701#define STV090x_P2_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(2)
1702#define STV090x_OFFST_Px_PLH_STATISTIC_FIELD 0
1703#define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD 8
1704
1705#define STV090x_Px_LOCKTIMEy(__x, __y) (0xF525 - (__x - 1) * 0x200 - __y * 0x1)
1706#define STV090x_P1_LOCKTIME0 STV090x_Px_LOCKTIMEy(1, 0)
1707#define STV090x_P1_LOCKTIME1 STV090x_Px_LOCKTIMEy(1, 1)
1708#define STV090x_P1_LOCKTIME2 STV090x_Px_LOCKTIMEy(1, 2)
1709#define STV090x_P1_LOCKTIME3 STV090x_Px_LOCKTIMEy(1, 3)
1710#define STV090x_P2_LOCKTIME0 STV090x_Px_LOCKTIMEy(2, 0)
1711#define STV090x_P2_LOCKTIME1 STV090x_Px_LOCKTIMEy(2, 1)
1712#define STV090x_P2_LOCKTIME2 STV090x_Px_LOCKTIMEy(2, 2)
1713#define STV090x_P2_LOCKTIME3 STV090x_Px_LOCKTIMEy(2, 3)
1714#define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD 0
1715#define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD 8
1716
1717#define STV090x_Px_TNRCFG(__x) (0xf4e0 - (__x - 1) * 0x200) /* check */
1718#define STV090x_P1_TNRCFG STV090x_Px_TNRCFG(1)
1719#define STV090x_P2_TNRCFG STV090x_Px_TNRCFG(2)
1720
1721#define STV090x_Px_TNRCFG2(__x) (0xf4e1 - (__x - 1) * 0x200)
1722#define STV090x_P1_TNRCFG2 STV090x_Px_TNRCFG2(1)
1723#define STV090x_P2_TNRCFG2 STV090x_Px_TNRCFG2(2)
1724#define STV090x_OFFST_Px_TUN_IQSWAP_FIELD 7
1725#define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD 1
1726
1727#define STV090x_Px_VITSCALE(__x) (0xf532 - (__x - 1) * 0x200)
1728#define STV090x_P1_VITSCALE STV090x_Px_VITSCALE(1)
1729#define STV090x_P2_VITSCALE STV090x_Px_VITSCALE(2)
1730#define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD 7
1731#define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD 1
1732#define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD 6
1733#define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD 1
1734#define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD 3
1735#define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD 1
1736#define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD 1
1737#define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD 1
1738
1739#define STV090x_Px_FECM(__x) (0xf533 - (__x - 1) * 0x200)
1740#define STV090x_P1_FECM STV090x_Px_FECM(1)
1741#define STV090x_P2_FECM STV090x_Px_FECM(2)
1742#define STV090x_OFFST_Px_DSS_DVB_FIELD 7
1743#define STV090x_WIDTH_Px_DSS_DVB_FIELD 1
1744#define STV090x_OFFST_Px_DSS_SRCH_FIELD 4
1745#define STV090x_WIDTH_Px_DSS_SRCH_FIELD 1
1746#define STV090x_OFFST_Px_SYNCVIT_FIELD 1
1747#define STV090x_WIDTH_Px_SYNCVIT_FIELD 1
1748#define STV090x_OFFST_Px_IQINV_FIELD 0
1749#define STV090x_WIDTH_Px_IQINV_FIELD 1
1750
1751#define STV090x_Px_VTH12(__x) (0xf534 - (__x - 1) * 0x200)
1752#define STV090x_P1_VTH12 STV090x_Px_VTH12(1)
1753#define STV090x_P2_VTH12 STV090x_Px_VTH12(2)
1754#define STV090x_OFFST_Px_VTH12_FIELD 0
1755#define STV090x_WIDTH_Px_VTH12_FIELD 8
1756
1757#define STV090x_Px_VTH23(__x) (0xf535 - (__x - 1) * 0x200)
1758#define STV090x_P1_VTH23 STV090x_Px_VTH23(1)
1759#define STV090x_P2_VTH23 STV090x_Px_VTH23(2)
1760#define STV090x_OFFST_Px_VTH23_FIELD 0
1761#define STV090x_WIDTH_Px_VTH23_FIELD 8
1762
1763#define STV090x_Px_VTH34(__x) (0xf536 - (__x - 1) * 0x200)
1764#define STV090x_P1_VTH34 STV090x_Px_VTH34(1)
1765#define STV090x_P2_VTH34 STV090x_Px_VTH34(2)
1766#define STV090x_OFFST_Px_VTH34_FIELD 0
1767#define STV090x_WIDTH_Px_VTH34_FIELD 8
1768
1769#define STV090x_Px_VTH56(__x) (0xf537 - (__x - 1) * 0x200)
1770#define STV090x_P1_VTH56 STV090x_Px_VTH56(1)
1771#define STV090x_P2_VTH56 STV090x_Px_VTH56(2)
1772#define STV090x_OFFST_Px_VTH56_FIELD 0
1773#define STV090x_WIDTH_Px_VTH56_FIELD 8
1774
1775#define STV090x_Px_VTH67(__x) (0xf538 - (__x - 1) * 0x200)
1776#define STV090x_P1_VTH67 STV090x_Px_VTH67(1)
1777#define STV090x_P2_VTH67 STV090x_Px_VTH67(2)
1778#define STV090x_OFFST_Px_VTH67_FIELD 0
1779#define STV090x_WIDTH_Px_VTH67_FIELD 8
1780
1781#define STV090x_Px_VTH78(__x) (0xf539 - (__x - 1) * 0x200)
1782#define STV090x_P1_VTH78 STV090x_Px_VTH78(1)
1783#define STV090x_P2_VTH78 STV090x_Px_VTH78(2)
1784#define STV090x_OFFST_Px_VTH78_FIELD 0
1785#define STV090x_WIDTH_Px_VTH78_FIELD 8
1786
1787#define STV090x_Px_VITCURPUN(__x) (0xf53a - (__x - 1) * 0x200)
1788#define STV090x_P1_VITCURPUN STV090x_Px_VITCURPUN(1)
1789#define STV090x_P2_VITCURPUN STV090x_Px_VITCURPUN(2)
1790#define STV090x_OFFST_Px_VIT_CURPUN_FIELD 0
1791#define STV090x_WIDTH_Px_VIT_CURPUN_FIELD 5
1792
1793#define STV090x_Px_VERROR(__x) (0xf53b - (__x - 1) * 0x200)
1794#define STV090x_P1_VERROR STV090x_Px_VERROR(1)
1795#define STV090x_P2_VERROR STV090x_Px_VERROR(2)
1796#define STV090x_OFFST_Px_REGERR_VIT_FIELD 0
1797#define STV090x_WIDTH_Px_REGERR_VIT_FIELD 8
1798
1799#define STV090x_Px_PRVIT(__x) (0xf53c - (__x - 1) * 0x200)
1800#define STV090x_P1_PRVIT STV090x_Px_PRVIT(1)
1801#define STV090x_P2_PRVIT STV090x_Px_PRVIT(2)
1802#define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD 6
1803#define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD 1
1804#define STV090x_OFFST_Px_E7_8VIT_FIELD 5
1805#define STV090x_WIDTH_Px_E7_8VIT_FIELD 1
1806#define STV090x_OFFST_Px_E6_7VIT_FIELD 4
1807#define STV090x_WIDTH_Px_E6_7VIT_FIELD 1
1808#define STV090x_OFFST_Px_E5_6VIT_FIELD 3
1809#define STV090x_WIDTH_Px_E5_6VIT_FIELD 1
1810#define STV090x_OFFST_Px_E3_4VIT_FIELD 2
1811#define STV090x_WIDTH_Px_E3_4VIT_FIELD 1
1812#define STV090x_OFFST_Px_E2_3VIT_FIELD 1
1813#define STV090x_WIDTH_Px_E2_3VIT_FIELD 1
1814#define STV090x_OFFST_Px_E1_2VIT_FIELD 0
1815#define STV090x_WIDTH_Px_E1_2VIT_FIELD 1
1816
1817#define STV090x_Px_VAVSRVIT(__x) (0xf53d - (__x - 1) * 0x200)
1818#define STV090x_P1_VAVSRVIT STV090x_Px_VAVSRVIT(1)
1819#define STV090x_P2_VAVSRVIT STV090x_Px_VAVSRVIT(2)
1820#define STV090x_OFFST_Px_SNVIT_FIELD 4
1821#define STV090x_WIDTH_Px_SNVIT_FIELD 2
1822#define STV090x_OFFST_Px_TOVVIT_FIELD 2
1823#define STV090x_WIDTH_Px_TOVVIT_FIELD 2
1824#define STV090x_OFFST_Px_HYPVIT_FIELD 0
1825#define STV090x_WIDTH_Px_HYPVIT_FIELD 2
1826
1827#define STV090x_Px_VSTATUSVIT(__x) (0xf53e - (__x - 1) * 0x200)
1828#define STV090x_P1_VSTATUSVIT STV090x_Px_VSTATUSVIT(1)
1829#define STV090x_P2_VSTATUSVIT STV090x_Px_VSTATUSVIT(2)
1830#define STV090x_OFFST_Px_PRFVIT_FIELD 4
1831#define STV090x_WIDTH_Px_PRFVIT_FIELD 1
1832#define STV090x_OFFST_Px_LOCKEDVIT_FIELD 3
1833#define STV090x_WIDTH_Px_LOCKEDVIT_FIELD 1
1834
1835#define STV090x_Px_VTHINUSE(__x) (0xf53f - (__x - 1) * 0x200)
1836#define STV090x_P1_VTHINUSE STV090x_Px_VTHINUSE(1)
1837#define STV090x_P2_VTHINUSE STV090x_Px_VTHINUSE(2)
1838#define STV090x_OFFST_Px_VIT_INUSE_FIELD 0
1839#define STV090x_WIDTH_Px_VIT_INUSE_FIELD 8
1840
1841#define STV090x_Px_KDIV12(__x) (0xf540 - (__x - 1) * 0x200)
1842#define STV090x_P1_KDIV12 STV090x_Px_KDIV12(1)
1843#define STV090x_P2_KDIV12 STV090x_Px_KDIV12(2)
1844#define STV090x_OFFST_Px_K_DIVIDER_12_FIELD 0
1845#define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD 7
1846
1847#define STV090x_Px_KDIV23(__x) (0xf541 - (__x - 1) * 0x200)
1848#define STV090x_P1_KDIV23 STV090x_Px_KDIV23(1)
1849#define STV090x_P2_KDIV23 STV090x_Px_KDIV23(2)
1850#define STV090x_OFFST_Px_K_DIVIDER_23_FIELD 0
1851#define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD 7
1852
1853#define STV090x_Px_KDIV34(__x) (0xf542 - (__x - 1) * 0x200)
1854#define STV090x_P1_KDIV34 STV090x_Px_KDIV34(1)
1855#define STV090x_P2_KDIV34 STV090x_Px_KDIV34(2)
1856#define STV090x_OFFST_Px_K_DIVIDER_34_FIELD 0
1857#define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD 7
1858
1859#define STV090x_Px_KDIV56(__x) (0xf543 - (__x - 1) * 0x200)
1860#define STV090x_P1_KDIV56 STV090x_Px_KDIV56(1)
1861#define STV090x_P2_KDIV56 STV090x_Px_KDIV56(2)
1862#define STV090x_OFFST_Px_K_DIVIDER_56_FIELD 0
1863#define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD 7
1864
1865#define STV090x_Px_KDIV67(__x) (0xf544 - (__x - 1) * 0x200)
1866#define STV090x_P1_KDIV67 STV090x_Px_KDIV67(1)
1867#define STV090x_P2_KDIV67 STV090x_Px_KDIV67(2)
1868#define STV090x_OFFST_Px_K_DIVIDER_67_FIELD 0
1869#define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD 7
1870
1871#define STV090x_Px_KDIV78(__x) (0xf545 - (__x - 1) * 0x200)
1872#define STV090x_P1_KDIV78 STV090x_Px_KDIV78(1)
1873#define STV090x_P2_KDIV78 STV090x_Px_KDIV78(2)
1874#define STV090x_OFFST_Px_K_DIVIDER_78_FIELD 0
1875#define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD 7
1876
1877#define STV090x_Px_PDELCTRL1(__x) (0xf550 - (__x - 1) * 0x200)
1878#define STV090x_P1_PDELCTRL1 STV090x_Px_PDELCTRL1(1)
1879#define STV090x_P2_PDELCTRL1 STV090x_Px_PDELCTRL1(2)
1880#define STV090x_OFFST_Px_INV_MISMASK_FIELD 7
1881#define STV090x_WIDTH_Px_INV_MISMASK_FIELD 1
1882#define STV090x_OFFST_Px_FILTER_EN_FIELD 5
1883#define STV090x_WIDTH_Px_FILTER_EN_FIELD 1
1884#define STV090x_OFFST_Px_EN_MIS00_FIELD 1
1885#define STV090x_WIDTH_Px_EN_MIS00_FIELD 1
1886#define STV090x_OFFST_Px_ALGOSWRST_FIELD 0
1887#define STV090x_WIDTH_Px_ALGOSWRST_FIELD 1
1888
1889#define STV090x_Px_PDELCTRL2(__x) (0xf551 - (__x - 1) * 0x200)
1890#define STV090x_P1_PDELCTRL2 STV090x_Px_PDELCTRL2(1)
1891#define STV090x_P2_PDELCTRL2 STV090x_Px_PDELCTRL2(2)
1892#define STV090x_OFFST_Px_FORCE_CONTINUOUS 7
1893#define STV090x_WIDTH_Px_FORCE_CONTINUOUS 1
1894#define STV090x_OFFST_Px_RESET_UPKO_COUNT 6
1895#define STV090x_WIDTH_Px_RESET_UPKO_COUNT 1
1896#define STV090x_OFFST_Px_USER_PKTDELIN_NB 5
1897#define STV090x_WIDTH_Px_USER_PKTDELIN_NB 1
1898#define STV090x_OFFST_Px_FORCE_LOCKED 4
1899#define STV090x_WIDTH_Px_FORCE_LOCKED 1
1900#define STV090x_OFFST_Px_DATA_UNBBSCRAM 3
1901#define STV090x_WIDTH_Px_DATA_UNBBSCRAM 1
1902#define STV090x_OFFST_Px_FORCE_LONGPACKET 2
1903#define STV090x_WIDTH_Px_FORCE_LONGPACKET 1
1904#define STV090x_OFFST_Px_FRAME_MODE_FIELD 1
1905#define STV090x_WIDTH_Px_FRAME_MODE_FIELD 1
1906
1907#define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200)
1908#define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1)
1909#define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2)
1910#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4
1911#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4
1912#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0
1913#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4
1914
1915#define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200)
1916#define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1)
1917#define STV090x_P2_ISIENTRY STV090x_Px_ISIENTRY(2)
1918#define STV090x_OFFST_Px_ISI_ENTRY_FIELD 0
1919#define STV090x_WIDTH_Px_ISI_ENTRY_FIELD 8
1920
1921#define STV090x_Px_ISIBITENA(__x) (0xf55f - (__x - 1) * 0x200)
1922#define STV090x_P1_ISIBITENA STV090x_Px_ISIBITENA(1)
1923#define STV090x_P2_ISIBITENA STV090x_Px_ISIBITENA(2)
1924#define STV090x_OFFST_Px_ISI_BIT_EN_FIELD 0
1925#define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD 8
1926
1927#define STV090x_Px_MATSTRy(__x, __y) (0xf561 - (__x - 1) * 0x200 - __y * 0x1)
1928#define STV090x_P1_MATSTR0 STV090x_Px_MATSTRy(1, 0)
1929#define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1)
1930#define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0)
1931#define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1)
1932#define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0
1933#define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8
1934
1935#define STV090x_Px_UPLSTRy(__x, __y) (0xf563 - (__x - 1) * 0x200 - __y * 0x1)
1936#define STV090x_P1_UPLSTR0 STV090x_Px_UPLSTRy(1, 0)
1937#define STV090x_P1_UPLSTR1 STV090x_Px_UPLSTRy(1, 1)
1938#define STV090x_P2_UPLSTR0 STV090x_Px_UPLSTRy(2, 0)
1939#define STV090x_P2_UPLSTR1 STV090x_Px_UPLSTRy(2, 1)
1940#define STV090x_OFFST_Px_UPL_CURRENT_FIELD 0
1941#define STV090x_WIDTH_Px_UPL_CURRENT_FIELD 8
1942
1943#define STV090x_Px_DFLSTRy(__x, __y) (0xf565 - (__x - 1) * 0x200 - __y * 0x1)
1944#define STV090x_P1_DFLSTR0 STV090x_Px_DFLSTRy(1, 0)
1945#define STV090x_P1_DFLSTR1 STV090x_Px_DFLSTRy(1, 1)
1946#define STV090x_P2_DFLSTR0 STV090x_Px_DFLSTRy(2, 0)
1947#define STV090x_P2_DFLSTR1 STV090x_Px_DFLSTRy(2, 1)
1948#define STV090x_OFFST_Px_DFL_CURRENT_FIELD 0
1949#define STV090x_WIDTH_Px_DFL_CURRENT_FIELD 8
1950
1951#define STV090x_Px_SYNCSTR(__x) (0xf566 - (__x - 1) * 0x200)
1952#define STV090x_P1_SYNCSTR STV090x_Px_SYNCSTR(1)
1953#define STV090x_P2_SYNCSTR STV090x_Px_SYNCSTR(2)
1954#define STV090x_OFFST_Px_SYNC_CURRENT_FIELD 0
1955#define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD 8
1956
1957#define STV090x_Px_SYNCDSTRy(__x, __y) (0xf568 - (__x - 1) * 0x200 - __y * 0x1)
1958#define STV090x_P1_SYNCDSTR0 STV090x_Px_SYNCDSTRy(1, 0)
1959#define STV090x_P1_SYNCDSTR1 STV090x_Px_SYNCDSTRy(1, 1)
1960#define STV090x_P2_SYNCDSTR0 STV090x_Px_SYNCDSTRy(2, 0)
1961#define STV090x_P2_SYNCDSTR1 STV090x_Px_SYNCDSTRy(2, 1)
1962#define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD 0
1963#define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD 8
1964
1965#define STV090x_Px_PDELSTATUS1(__x) (0xf569 - (__x - 1) * 0x200)
1966#define STV090x_P1_PDELSTATUS1 STV090x_Px_PDELSTATUS1(1)
1967#define STV090x_P2_PDELSTATUS1 STV090x_Px_PDELSTATUS1(2)
1968#define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD 1
1969#define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD 1
1970#define STV090x_OFFST_Px_FIRST_LOCK_FIELD 0
1971#define STV090x_WIDTH_Px_FIRST_LOCK_FIELD 1
1972
1973#define STV090x_Px_PDELSTATUS2(__x) (0xf56a - (__x - 1) * 0x200)
1974#define STV090x_P1_PDELSTATUS2 STV090x_Px_PDELSTATUS2(1)
1975#define STV090x_P2_PDELSTATUS2 STV090x_Px_PDELSTATUS2(2)
1976#define STV090x_OFFST_Px_FRAME_MODCOD_FIELD 2
1977#define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD 5
1978#define STV090x_OFFST_Px_FRAME_TYPE_FIELD 0
1979#define STV090x_WIDTH_Px_FRAME_TYPE_FIELD 2
1980
1981#define STV090x_Px_BBFCRCKO1(__x) (0xf56b - (__x - 1) * 0x200)
1982#define STV090x_P1_BBFCRCKO1 STV090x_Px_BBFCRCKO1(1)
1983#define STV090x_P2_BBFCRCKO1 STV090x_Px_BBFCRCKO1(2)
1984#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0
1985#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8
1986
1987#define STV090x_Px_BBFCRCKO0(__x) (0xf56c - (__x - 1) * 0x200)
1988#define STV090x_P1_BBFCRCKO0 STV090x_Px_BBFCRCKO0(1)
1989#define STV090x_P2_BBFCRCKO0 STV090x_Px_BBFCRCKO0(2)
1990#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0
1991#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8
1992
1993#define STV090x_Px_UPCRCKO1(__x) (0xf56d - (__x - 1) * 0x200)
1994#define STV090x_P1_UPCRCKO1 STV090x_Px_UPCRCKO1(1)
1995#define STV090x_P2_UPCRCKO1 STV090x_Px_UPCRCKO1(2)
1996#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0
1997#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8
1998
1999#define STV090x_Px_UPCRCKO0(__x) (0xf56e - (__x - 1) * 0x200)
2000#define STV090x_P1_UPCRCKO0 STV090x_Px_UPCRCKO0(1)
2001#define STV090x_P2_UPCRCKO0 STV090x_Px_UPCRCKO0(2)
2002#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0
2003#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8
2004
2005#define STV090x_NBITER_NFx(__x) (0xFA03 + (__x - 4) * 0x1)
2006#define STV090x_NBITER_NF4 STV090x_NBITER_NFx(4)
2007#define STV090x_NBITER_NF5 STV090x_NBITER_NFx(5)
2008#define STV090x_NBITER_NF6 STV090x_NBITER_NFx(6)
2009#define STV090x_NBITER_NF7 STV090x_NBITER_NFx(7)
2010#define STV090x_NBITER_NF8 STV090x_NBITER_NFx(8)
2011#define STV090x_NBITER_NF9 STV090x_NBITER_NFx(9)
2012#define STV090x_NBITER_NF10 STV090x_NBITER_NFx(10)
2013#define STV090x_NBITER_NF11 STV090x_NBITER_NFx(11)
2014#define STV090x_NBITER_NF12 STV090x_NBITER_NFx(12)
2015#define STV090x_NBITER_NF13 STV090x_NBITER_NFx(13)
2016#define STV090x_NBITER_NF14 STV090x_NBITER_NFx(14)
2017#define STV090x_NBITER_NF15 STV090x_NBITER_NFx(15)
2018#define STV090x_NBITER_NF16 STV090x_NBITER_NFx(16)
2019#define STV090x_NBITER_NF17 STV090x_NBITER_NFx(17)
2020
2021#define STV090x_NBITERNOERR 0xFA3F
2022#define STV090x_OFFST_NBITER_STOP_CRIT_FIELD 0
2023#define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD 4
2024
2025#define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1)
2026#define STV090x_GAINLLR_NF4 STV090x_GAINLLR_NFx(4)
2027#define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD 0
2028#define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD 7
2029
2030#define STV090x_GAINLLR_NF5 STV090x_GAINLLR_NFx(5)
2031#define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD 0
2032#define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD 7
2033
2034#define STV090x_GAINLLR_NF6 STV090x_GAINLLR_NFx(6)
2035#define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD 0
2036#define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD 7
2037
2038#define STV090x_GAINLLR_NF7 STV090x_GAINLLR_NFx(7)
2039#define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD 0
2040#define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD 7
2041
2042#define STV090x_GAINLLR_NF8 STV090x_GAINLLR_NFx(8)
2043#define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD 0
2044#define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD 7
2045
2046#define STV090x_GAINLLR_NF9 STV090x_GAINLLR_NFx(9)
2047#define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD 0
2048#define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD 7
2049
2050#define STV090x_GAINLLR_NF10 STV090x_GAINLLR_NFx(10)
2051#define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD 0
2052#define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD 7
2053
2054#define STV090x_GAINLLR_NF11 STV090x_GAINLLR_NFx(11)
2055#define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD 0
2056#define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD 7
2057
2058#define STV090x_GAINLLR_NF12 STV090x_GAINLLR_NFx(12)
2059#define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD 0
2060#define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD 7
2061
2062#define STV090x_GAINLLR_NF13 STV090x_GAINLLR_NFx(13)
2063#define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD 0
2064#define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD 7
2065
2066#define STV090x_GAINLLR_NF14 STV090x_GAINLLR_NFx(14)
2067#define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD 0
2068#define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD 7
2069
2070#define STV090x_GAINLLR_NF15 STV090x_GAINLLR_NFx(15)
2071#define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD 0
2072#define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD 7
2073
2074#define STV090x_GAINLLR_NF16 STV090x_GAINLLR_NFx(16)
2075#define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD 0
2076#define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD 7
2077
2078#define STV090x_GAINLLR_NF17 STV090x_GAINLLR_NFx(17)
2079#define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD 0
2080#define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD 7
2081
2082#define STV090x_GENCFG 0xFA86
2083#define STV090x_OFFST_BROADCAST_FIELD 4
2084#define STV090x_WIDTH_BROADCAST_FIELD 1
2085#define STV090x_OFFST_PRIORITY_FIELD 1
2086#define STV090x_WIDTH_PRIORITY_FIELD 1
2087#define STV090x_OFFST_DDEMOD_FIELD 0
2088#define STV090x_WIDTH_DDEMOD_FIELD 1
2089
2090#define STV090x_LDPCERRx(__x) (0xFA97 - (__x * 0x1))
2091#define STV090x_LDPCERR0 STV090x_LDPCERRx(0)
2092#define STV090x_LDPCERR1 STV090x_LDPCERRx(1)
2093#define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD 0
2094#define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD 8
2095
2096#define STV090x_BCHERR 0xFA98
2097#define STV090x_OFFST_Px_ERRORFLAG_FIELD 4
2098#define STV090x_WIDTH_Px_ERRORFLAG_FIELD 1
2099#define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD 0
2100#define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD 4
2101
2102#define STV090x_Px_TSSTATEM(__x) (0xF570 - (__x - 1) * 0x200)
2103#define STV090x_P1_TSSTATEM STV090x_Px_TSSTATEM(1)
2104#define STV090x_P2_TSSTATEM STV090x_Px_TSSTATEM(2)
2105#define STV090x_OFFST_Px_TSDIL_ON_FIELD 7
2106#define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1
2107#define STV090x_OFFST_Px_TSRS_ON_FIELD 5
2108#define STV090x_WIDTH_Px_TSRS_ON_FIELD 1
2109
2110#define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200)
2111#define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1)
2112#define STV090x_P2_TSCFGH STV090x_Px_TSCFGH(2)
2113#define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD 7
2114#define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD 1
2115#define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD 6
2116#define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD 1
2117#define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD 5
2118#define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD 1
2119#define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD 4
2120#define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD 1
2121#define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD 3
2122#define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD 1
2123#define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD 1
2124#define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD 2
2125#define STV090x_OFFST_Px_RST_HWARE_FIELD 0
2126#define STV090x_WIDTH_Px_RST_HWARE_FIELD 1
2127
2128#define STV090x_Px_TSCFGM(__x) (0xF573 - (__x - 1) * 0x200)
2129#define STV090x_P1_TSCFGM STV090x_Px_TSCFGM(1)
2130#define STV090x_P2_TSCFGM STV090x_Px_TSCFGM(2)
2131#define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD 6
2132#define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD 2
2133#define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD 5
2134#define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD 1
2135#define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD 0
2136#define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD 1
2137
2138#define STV090x_Px_TSCFGL(__x) (0xF574 - (__x - 1) * 0x200)
2139#define STV090x_P1_TSCFGL STV090x_Px_TSCFGL(1)
2140#define STV090x_P2_TSCFGL STV090x_Px_TSCFGL(2)
2141#define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD 6
2142#define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD 2
2143#define STV090x_OFFST_Px_BCHERROR_MODE_FIELD 4
2144#define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD 2
2145#define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD 3
2146#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD 1
2147#define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD 2
2148#define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD 1
2149#define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1
2150#define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1
2151
2152#define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200)
2153#define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1)
2154#define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2)
2155#define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD 7
2156#define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD 1
2157#define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD 6
2158#define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD 1
2159
2160#define STV090x_Px_TSSPEED(__x) (0xF580 - (__x - 1) * 0x200)
2161#define STV090x_P1_TSSPEED STV090x_Px_TSSPEED(1)
2162#define STV090x_P2_TSSPEED STV090x_Px_TSSPEED(2)
2163#define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD 0
2164#define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD 8
2165
2166#define STV090x_Px_TSSTATUS(__x) (0xF581 - (__x - 1) * 0x200)
2167#define STV090x_P1_TSSTATUS STV090x_Px_TSSTATUS(1)
2168#define STV090x_P2_TSSTATUS STV090x_Px_TSSTATUS(2)
2169#define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD 7
2170#define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD 1
2171#define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD 6
2172#define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD 1
2173
2174#define STV090x_Px_TSSTATUS2(__x) (0xF582 - (__x - 1) * 0x200)
2175#define STV090x_P1_TSSTATUS2 STV090x_Px_TSSTATUS2(1)
2176#define STV090x_P2_TSSTATUS2 STV090x_Px_TSSTATUS2(2)
2177#define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD 7
2178#define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD 1
2179#define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD 6
2180#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1
2181#define STV090x_OFFST_Px_DILXX_RESET_FIELD 5
2182#define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1
2183#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 5
2184#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1
2185#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1
2186#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1
2187
2188#define STV090x_Px_TSBITRATEy(__x, __y) (0xF584 - (__x - 1) * 0x200 - __y * 0x1)
2189#define STV090x_P1_TSBITRATE0 STV090x_Px_TSBITRATEy(1, 0)
2190#define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1)
2191#define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0)
2192#define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1)
2193#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 7
2194#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8
2195
2196#define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200)
2197#define STV090x_P1_ERRCTRL1 STV090x_Px_ERRCTRL1(1)
2198#define STV090x_P2_ERRCTRL1 STV090x_Px_ERRCTRL1(2)
2199#define STV090x_OFFST_Px_ERR_SOURCE_FIELD 4
2200#define STV090x_WIDTH_Px_ERR_SOURCE_FIELD 4
2201#define STV090x_OFFST_Px_NUM_EVENT_FIELD 0
2202#define STV090x_WIDTH_Px_NUM_EVENT_FIELD 3
2203
2204#define STV090x_Px_ERRCNT12(__x) (0xF599 - (__x - 1) * 0x200)
2205#define STV090x_P1_ERRCNT12 STV090x_Px_ERRCNT12(1)
2206#define STV090x_P2_ERRCNT12 STV090x_Px_ERRCNT12(2)
2207#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD 7
2208#define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD 1
2209#define STV090x_OFFST_Px_ERR_CNT12_FIELD 0
2210#define STV090x_WIDTH_Px_ERR_CNT12_FIELD 7
2211
2212#define STV090x_Px_ERRCNT11(__x) (0xF59A - (__x - 1) * 0x200)
2213#define STV090x_P1_ERRCNT11 STV090x_Px_ERRCNT11(1)
2214#define STV090x_P2_ERRCNT11 STV090x_Px_ERRCNT11(2)
2215#define STV090x_OFFST_Px_ERR_CNT11_FIELD 0
2216#define STV090x_WIDTH_Px_ERR_CNT11_FIELD 8
2217
2218#define STV090x_Px_ERRCNT10(__x) (0xF59B - (__x - 1) * 0x200)
2219#define STV090x_P1_ERRCNT10 STV090x_Px_ERRCNT10(1)
2220#define STV090x_P2_ERRCNT10 STV090x_Px_ERRCNT10(2)
2221#define STV090x_OFFST_Px_ERR_CNT10_FIELD 0
2222#define STV090x_WIDTH_Px_ERR_CNT10_FIELD 8
2223
2224#define STV090x_Px_ERRCTRL2(__x) (0xF59C - (__x - 1) * 0x200)
2225#define STV090x_P1_ERRCTRL2 STV090x_Px_ERRCTRL2(1)
2226#define STV090x_P2_ERRCTRL2 STV090x_Px_ERRCTRL2(2)
2227#define STV090x_OFFST_Px_ERR_SOURCE2_FIELD 4
2228#define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD 4
2229#define STV090x_OFFST_Px_NUM_EVENT2_FIELD 0
2230#define STV090x_WIDTH_Px_NUM_EVENT2_FIELD 3
2231
2232#define STV090x_Px_ERRCNT22(__x) (0xF59D - (__x - 1) * 0x200)
2233#define STV090x_P1_ERRCNT22 STV090x_Px_ERRCNT22(1)
2234#define STV090x_P2_ERRCNT22 STV090x_Px_ERRCNT22(2)
2235#define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD 7
2236#define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD 1
2237#define STV090x_OFFST_Px_ERR_CNT2_FIELD 0
2238#define STV090x_WIDTH_Px_ERR_CNT2_FIELD 7
2239
2240#define STV090x_Px_ERRCNT21(__x) (0xF59E - (__x - 1) * 0x200)
2241#define STV090x_P1_ERRCNT21 STV090x_Px_ERRCNT21(1)
2242#define STV090x_P2_ERRCNT21 STV090x_Px_ERRCNT21(2)
2243#define STV090x_OFFST_Px_ERR_CNT21_FIELD 0
2244#define STV090x_WIDTH_Px_ERR_CNT21_FIELD 8
2245
2246#define STV090x_Px_ERRCNT20(__x) (0xF59F - (__x - 1) * 0x200)
2247#define STV090x_P1_ERRCNT20 STV090x_Px_ERRCNT20(1)
2248#define STV090x_P2_ERRCNT20 STV090x_Px_ERRCNT20(2)
2249#define STV090x_OFFST_Px_ERR_CNT20_FIELD 0
2250#define STV090x_WIDTH_Px_ERR_CNT20_FIELD 8
2251
2252#define STV090x_Px_FECSPY(__x) (0xF5A0 - (__x - 1) * 0x200)
2253#define STV090x_P1_FECSPY STV090x_Px_FECSPY(1)
2254#define STV090x_P2_FECSPY STV090x_Px_FECSPY(2)
2255#define STV090x_OFFST_Px_SPY_ENABLE_FIELD 7
2256#define STV090x_WIDTH_Px_SPY_ENABLE_FIELD 1
2257#define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD 2
2258#define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD 2
2259
2260#define STV090x_Px_FSPYCFG(__x) (0xF5A1 - (__x - 1) * 0x200)
2261#define STV090x_P1_FSPYCFG STV090x_Px_FSPYCFG(1)
2262#define STV090x_P2_FSPYCFG STV090x_Px_FSPYCFG(2)
2263#define STV090x_OFFST_Px_RST_ON_ERROR_FIELD 5
2264#define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD 1
2265#define STV090x_OFFST_Px_ONE_SHOT_FIELD 4
2266#define STV090x_WIDTH_Px_ONE_SHOT_FIELD 1
2267#define STV090x_OFFST_Px_I2C_MODE_FIELD 2
2268#define STV090x_WIDTH_Px_I2C_MODE_FIELD 2
2269
2270#define STV090x_Px_FSPYDATA(__x) (0xF5A2 - (__x - 1) * 0x200)
2271#define STV090x_P1_FSPYDATA STV090x_Px_FSPYDATA(1)
2272#define STV090x_P2_FSPYDATA STV090x_Px_FSPYDATA(2)
2273#define STV090x_OFFST_Px_SPY_STUFFING_FIELD 7
2274#define STV090x_WIDTH_Px_SPY_STUFFING_FIELD 1
2275#define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD 5
2276#define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD 1
2277#define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD 0
2278#define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD 5
2279
2280#define STV090x_Px_FSPYOUT(__x) (0xF5A3 - (__x - 1) * 0x200)
2281#define STV090x_P1_FSPYOUT STV090x_Px_FSPYOUT(1)
2282#define STV090x_P2_FSPYOUT STV090x_Px_FSPYOUT(2)
2283#define STV090x_OFFST_Px_FSPY_DIRECT_FIELD 7
2284#define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD 1
2285#define STV090x_OFFST_Px_STUFF_MODE_FIELD 0
2286#define STV090x_WIDTH_Px_STUFF_MODE_FIELD 3
2287
2288#define STV090x_Px_FSTATUS(__x) (0xF5A4 - (__x - 1) * 0x200)
2289#define STV090x_P1_FSTATUS STV090x_Px_FSTATUS(1)
2290#define STV090x_P2_FSTATUS STV090x_Px_FSTATUS(2)
2291#define STV090x_OFFST_Px_SPY_ENDSIM_FIELD 7
2292#define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD 1
2293#define STV090x_OFFST_Px_VALID_SIM_FIELD 6
2294#define STV090x_WIDTH_Px_VALID_SIM_FIELD 1
2295#define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD 5
2296#define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD 1
2297#define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD 4
2298#define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD 1
2299#define STV090x_OFFST_Px_RESULT_STATE_FIELD 0
2300#define STV090x_WIDTH_Px_RESULT_STATE_FIELD 4
2301
2302#define STV090x_Px_FBERCPT4(__x) (0xF5A8 - (__x - 1) * 0x200)
2303#define STV090x_P1_FBERCPT4 STV090x_Px_FBERCPT4(1)
2304#define STV090x_P2_FBERCPT4 STV090x_Px_FBERCPT4(2)
2305#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2306#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2307
2308#define STV090x_Px_FBERCPT3(__x) (0xF5A9 - (__x - 1) * 0x200)
2309#define STV090x_P1_FBERCPT3 STV090x_Px_FBERCPT3(1)
2310#define STV090x_P2_FBERCPT3 STV090x_Px_FBERCPT3(2)
2311#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2312#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2313
2314#define STV090x_Px_FBERCPT2(__x) (0xF5AA - (__x - 1) * 0x200)
2315#define STV090x_P1_FBERCPT2 STV090x_Px_FBERCPT2(1)
2316#define STV090x_P2_FBERCPT2 STV090x_Px_FBERCPT2(2)
2317#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2318#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2319
2320#define STV090x_Px_FBERCPT1(__x) (0xF5AB - (__x - 1) * 0x200)
2321#define STV090x_P1_FBERCPT1 STV090x_Px_FBERCPT1(1)
2322#define STV090x_P2_FBERCPT1 STV090x_Px_FBERCPT1(2)
2323#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2324#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2325
2326#define STV090x_Px_FBERCPT0(__x) (0xF5AC - (__x - 1) * 0x200)
2327#define STV090x_P1_FBERCPT0 STV090x_Px_FBERCPT0(1)
2328#define STV090x_P2_FBERCPT0 STV090x_Px_FBERCPT0(2)
2329#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2330#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2331
2332#define STV090x_Px_FBERERRy(__x, __y) (0xF5AF - (__x - 1) * 0x200 - __y * 0x1)
2333#define STV090x_P1_FBERERR0 STV090x_Px_FBERERRy(1, 0)
2334#define STV090x_P1_FBERERR1 STV090x_Px_FBERERRy(1, 1)
2335#define STV090x_P1_FBERERR2 STV090x_Px_FBERERRy(1, 2)
2336#define STV090x_P2_FBERERR0 STV090x_Px_FBERERRy(2, 0)
2337#define STV090x_P2_FBERERR1 STV090x_Px_FBERERRy(2, 1)
2338#define STV090x_P2_FBERERR2 STV090x_Px_FBERERRy(2, 2)
2339#define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD 0
2340#define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD 8
2341
2342#define STV090x_Px_FSPYBER(__x) (0xF5B2 - (__x - 1) * 0x200)
2343#define STV090x_P1_FSPYBER STV090x_Px_FSPYBER(1)
2344#define STV090x_P2_FSPYBER STV090x_Px_FSPYBER(2)
2345#define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD 4
2346#define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD 1
2347#define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD 3
2348#define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD 1
2349#define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD 0
2350#define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD 3
2351
2352#define STV090x_RCCFGH 0xf600
2353
2354#define STV090x_TSGENERAL 0xF630
2355#define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD 3
2356#define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD 1
2357#define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD 1
2358#define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD 2
2359
2360#define STV090x_TSGENERAL1X 0xf670
2361#define STV090x_CFGEXT 0xfa80
2362
2363#define STV090x_TSTRES0 0xFF11
2364#define STV090x_OFFST_FRESFEC_FIELD 7
2365#define STV090x_WIDTH_FRESFEC_FIELD 1
2366
2367#define STV090x_Px_TSTDISRX(__x) (0xFF67 - (__x - 1) * 0x2)
2368#define STV090x_P1_TSTDISRX STV090x_Px_TSTDISRX(1)
2369#define STV090x_P2_TSTDISRX STV090x_Px_TSTDISRX(2)
2370#define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD 3
2371#define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD 1
2372
2373#endif /* __STV090x_REG_H */
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
new file mode 100644
index 000000000000..3d8a2e01c9c4
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -0,0 +1,373 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/string.h>
27
28#include "dvb_frontend.h"
29
30#include "stv6110x_reg.h"
31#include "stv6110x.h"
32#include "stv6110x_priv.h"
33
34static unsigned int verbose;
35module_param(verbose, int, 0644);
36MODULE_PARM_DESC(verbose, "Set Verbosity level");
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)
41{
42 int ret;
43 const struct stv6110x_config *config = stv6110x->config;
44 u8 b0[] = { reg };
45 u8 b1[] = { 0 };
46 struct i2c_msg msg[] = {
47 { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 },
48 { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
49 };
50
51 ret = i2c_transfer(stv6110x->i2c, msg, 2);
52 if (ret != 2) {
53 dprintk(FE_ERROR, 1, "I/O Error");
54 return -EREMOTEIO;
55 }
56 *data = b1[0];
57
58 return 0;
59}
60
61static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
62{
63 int ret;
64 const struct stv6110x_config *config = stv6110x->config;
65 u8 buf[] = { reg, data };
66 struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 };
67
68 ret = i2c_transfer(stv6110x->i2c, &msg, 1);
69 if (ret != 1) {
70 dprintk(FE_ERROR, 1, "I/O Error");
71 return -EREMOTEIO;
72 }
73
74 return 0;
75}
76
77static int stv6110x_init(struct dvb_frontend *fe)
78{
79 struct stv6110x_state *stv6110x = fe->tuner_priv;
80 int ret;
81 u8 i;
82
83 for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) {
84 ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]);
85 if (ret < 0) {
86 dprintk(FE_ERROR, 1, "Initialization failed");
87 return -1;
88 }
89 }
90
91 return 0;
92}
93
94static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
95{
96 struct stv6110x_state *stv6110x = fe->tuner_priv;
97 u32 rDiv, divider;
98 s32 pVal, pCalc, rDivOpt = 0;
99 u8 i;
100
101 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
102
103 if (frequency <= 1023000) {
104 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
105 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
106 pVal = 40;
107 } else if (frequency <= 1300000) {
108 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
109 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
110 pVal = 40;
111 } else if (frequency <= 2046000) {
112 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
113 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
114 pVal = 20;
115 } else {
116 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
117 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
118 pVal = 20;
119 }
120
121 for (rDiv = 0; rDiv <= 3; rDiv++) {
122 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
123
124 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(1000 - pVal))))
125 rDivOpt = rDiv;
126 }
127
128 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
129 divider = (divider + 5) / 10;
130
131 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
132 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
133 STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
134
135 /* VCO Auto calibration */
136 STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
137
138 stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]);
139 stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]);
140 stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]);
141 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]);
142
143 for (i = 0; i < TRIALS; i++) {
144 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
145 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1]))
146 break;
147 msleep(1);
148 }
149
150 return 0;
151}
152
153static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
154{
155 struct stv6110x_state *stv6110x = fe->tuner_priv;
156
157 stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]);
158 stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]);
159
160 *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]),
161 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
162
163 *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) +
164 STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1])));
165
166 *frequency >>= 2;
167
168 return 0;
169}
170
171static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
172{
173 struct stv6110x_state *stv6110x = fe->tuner_priv;
174 u32 halfbw;
175 u8 i;
176
177 halfbw = bandwidth >> 1;
178
179 if (halfbw > 36000000)
180 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
181 else if (halfbw < 5000000)
182 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
183 else
184 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
185
186
187 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
188 STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
189
190 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]);
191 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]);
192
193 for (i = 0; i < TRIALS; i++) {
194 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
195 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1]))
196 break;
197 msleep(1);
198 }
199 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
200 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]);
201
202 return 0;
203}
204
205static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
206{
207 struct stv6110x_state *stv6110x = fe->tuner_priv;
208
209 stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]);
210 *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000;
211
212 return 0;
213}
214
215static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
216{
217 struct stv6110x_state *stv6110x = fe->tuner_priv;
218
219 /* setup divider */
220 switch (refclock) {
221 default:
222 case 1:
223 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
224 break;
225 case 2:
226 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
227 break;
228 case 4:
229 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
230 break;
231 case 8:
232 case 0:
233 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
234 break;
235 }
236 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]);
237
238 return 0;
239}
240
241static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
242{
243 struct stv6110x_state *stv6110x = fe->tuner_priv;
244
245 stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]);
246 *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]);
247
248 return 0;
249}
250
251static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
252{
253 struct stv6110x_state *stv6110x = fe->tuner_priv;
254
255 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
256 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]);
257
258 return 0;
259}
260
261static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
262{
263 struct stv6110x_state *stv6110x = fe->tuner_priv;
264 int ret;
265
266 switch (mode) {
267 case TUNER_SLEEP:
268 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0);
269 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0);
270 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0);
271 break;
272
273 case TUNER_WAKE:
274 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1);
275 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1);
276 STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1);
277 break;
278 }
279
280 ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]);
281 if (ret < 0) {
282 dprintk(FE_ERROR, 1, "I/O Error");
283 return -EIO;
284 }
285
286 return 0;
287}
288
289static int stv6110x_sleep(struct dvb_frontend *fe)
290{
291 return stv6110x_set_mode(fe, TUNER_SLEEP);
292}
293
294static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
295{
296 struct stv6110x_state *stv6110x = fe->tuner_priv;
297
298 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]);
299
300 if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1]))
301 *status = TUNER_PHASELOCKED;
302 else
303 *status = 0;
304
305 return 0;
306}
307
308
309static int stv6110x_release(struct dvb_frontend *fe)
310{
311 struct stv6110x_state *stv6110x = fe->tuner_priv;
312
313 fe->tuner_priv = NULL;
314 kfree(stv6110x);
315
316 return 0;
317}
318
319static struct dvb_tuner_ops stv6110x_ops = {
320 .info = {
321 .name = "STV6110(A) Silicon Tuner",
322 .frequency_min = 950000,
323 .frequency_max = 2150000,
324 .frequency_step = 0,
325 },
326
327 .init = stv6110x_init,
328 .sleep = stv6110x_sleep,
329 .release = stv6110x_release
330};
331
332static struct stv6110x_devctl stv6110x_ctl = {
333 .tuner_init = stv6110x_init,
334 .tuner_set_mode = stv6110x_set_mode,
335 .tuner_set_frequency = stv6110x_set_frequency,
336 .tuner_get_frequency = stv6110x_get_frequency,
337 .tuner_set_bandwidth = stv6110x_set_bandwidth,
338 .tuner_get_bandwidth = stv6110x_get_bandwidth,
339 .tuner_set_bbgain = stv6110x_set_bbgain,
340 .tuner_get_bbgain = stv6110x_get_bbgain,
341 .tuner_set_refclk = stv6110x_set_refclock,
342 .tuner_get_status = stv6110x_get_status,
343};
344
345struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
346 const struct stv6110x_config *config,
347 struct i2c_adapter *i2c)
348{
349 struct stv6110x_state *stv6110x;
350
351 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
352 if (stv6110x == NULL)
353 goto error;
354
355 stv6110x->i2c = i2c;
356 stv6110x->config = config;
357 stv6110x->devctl = &stv6110x_ctl;
358
359 fe->tuner_priv = stv6110x;
360 fe->ops.tuner_ops = stv6110x_ops;
361
362 printk("%s: Attaching STV6110x \n", __func__);
363 return stv6110x->devctl;
364
365error:
366 kfree(stv6110x);
367 return NULL;
368}
369EXPORT_SYMBOL(stv6110x_attach);
370
371MODULE_AUTHOR("Manu Abraham");
372MODULE_DESCRIPTION("STV6110x Silicon tuner");
373MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
new file mode 100644
index 000000000000..a38257080e01
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x.h
@@ -0,0 +1,71 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#ifndef __STV6110x_H
24#define __STV6110x_H
25
26struct stv6110x_config {
27 u8 addr;
28 u32 refclk;
29};
30
31enum tuner_mode {
32 TUNER_SLEEP = 1,
33 TUNER_WAKE,
34};
35
36enum tuner_status {
37 TUNER_PHASELOCKED = 1,
38};
39
40struct stv6110x_devctl {
41 int (*tuner_init) (struct dvb_frontend *fe);
42 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
43 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
44 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
45 int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
46 int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
47 int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
48 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
49 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
50 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
51};
52
53
54#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE))
55
56extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
57 const struct stv6110x_config *config,
58 struct i2c_adapter *i2c);
59
60#else
61static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
62 const struct stv6110x_config *config,
63 struct i2c_adapter *i2c)
64{
65 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
66 return NULL;
67}
68
69#endif /* CONFIG_DVB_STV6110x */
70
71#endif /* __STV6110x_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h
new file mode 100644
index 000000000000..7260da633d49
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x_priv.h
@@ -0,0 +1,75 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#ifndef __STV6110x_PRIV_H
24#define __STV6110x_PRIV_H
25
26#define FE_ERROR 0
27#define FE_NOTICE 1
28#define FE_INFO 2
29#define FE_DEBUG 3
30#define FE_DEBUGREG 4
31
32#define dprintk(__y, __z, format, arg...) do { \
33 if (__z) { \
34 if ((verbose > FE_ERROR) && (verbose > __y)) \
35 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
36 else if ((verbose > FE_NOTICE) && (verbose > __y)) \
37 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
38 else if ((verbose > FE_INFO) && (verbose > __y)) \
39 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
40 else if ((verbose > FE_DEBUG) && (verbose > __y)) \
41 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
42 } else { \
43 if (verbose > __y) \
44 printk(format, ##arg); \
45 } \
46} while (0)
47
48
49#define STV6110x_SETFIELD(mask, bitf, val) \
50 (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \
51 STV6110x_OFFST_##bitf))) | \
52 (val << STV6110x_OFFST_##bitf))
53
54#define STV6110x_GETFIELD(bitf, val) \
55 ((val >> STV6110x_OFFST_##bitf) & \
56 ((1 << STV6110x_WIDTH_##bitf) - 1))
57
58#define MAKEWORD16(a, b) (((a) << 8) | (b))
59
60#define LSB(x) ((x & 0xff))
61#define MSB(y) ((y >> 8) & 0xff)
62
63#define TRIALS 10
64#define R_DIV(__div) (1 << (__div + 1))
65#define REFCLOCK_kHz (stv6110x->config->refclk / 1000)
66#define REFCLOCK_MHz (stv6110x->config->refclk / 1000000)
67
68struct stv6110x_state {
69 struct i2c_adapter *i2c;
70 const struct stv6110x_config *config;
71
72 struct stv6110x_devctl *devctl;
73};
74
75#endif /* __STV6110x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb/frontends/stv6110x_reg.h
new file mode 100644
index 000000000000..93e5c70e5fd8
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x_reg.h
@@ -0,0 +1,82 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#ifndef __STV6110x_REG_H
24#define __STV6110x_REG_H
25
26#define STV6110x_CTRL1 0x00
27#define STV6110x_OFFST_CTRL1_K 3
28#define STV6110x_WIDTH_CTRL1_K 5
29#define STV6110x_OFFST_CTRL1_LPT 2
30#define STV6110x_WIDTH_CTRL1_LPT 1
31#define STV6110x_OFFST_CTRL1_RX 1
32#define STV6110x_WIDTH_CTRL1_RX 1
33#define STV6110x_OFFST_CTRL1_SYN 0
34#define STV6110x_WIDTH_CTRL1_SYN 1
35
36#define STV6110x_CTRL2 0x01
37#define STV6110x_OFFST_CTRL2_CO_DIV 6
38#define STV6110x_WIDTH_CTRL2_CO_DIV 2
39#define STV6110x_OFFST_CTRL2_RSVD 5
40#define STV6110x_WIDTH_CTRL2_RSVD 1
41#define STV6110x_OFFST_CTRL2_REFOUT_SEL 4
42#define STV6110x_WIDTH_CTRL2_REFOUT_SEL 1
43#define STV6110x_OFFST_CTRL2_BBGAIN 0
44#define STV6110x_WIDTH_CTRL2_BBGAIN 4
45
46#define STV6110x_TNG0 0x02
47#define STV6110x_OFFST_TNG0_N_DIV_7_0 0
48#define STV6110x_WIDTH_TNG0_N_DIV_7_0 8
49
50#define STV6110x_TNG1 0x03
51#define STV6110x_OFFST_TNG1_R_DIV 6
52#define STV6110x_WIDTH_TNG1_R_DIV 2
53#define STV6110x_OFFST_TNG1_PRESC32_ON 5
54#define STV6110x_WIDTH_TNG1_PRESC32_ON 1
55#define STV6110x_OFFST_TNG1_DIV4SEL 4
56#define STV6110x_WIDTH_TNG1_DIV4SEL 1
57#define STV6110x_OFFST_TNG1_N_DIV_11_8 0
58#define STV6110x_WIDTH_TNG1_N_DIV_11_8 4
59
60
61#define STV6110x_CTRL3 0x04
62#define STV6110x_OFFST_CTRL3_DCLOOP_OFF 7
63#define STV6110x_WIDTH_CTRL3_DCLOOP_OFF 1
64#define STV6110x_OFFST_CTRL3_RCCLK_OFF 6
65#define STV6110x_WIDTH_CTRL3_RCCLK_OFF 1
66#define STV6110x_OFFST_CTRL3_ICP 5
67#define STV6110x_WIDTH_CTRL3_ICP 1
68#define STV6110x_OFFST_CTRL3_CF 0
69#define STV6110x_WIDTH_CTRL3_CF 5
70
71#define STV6110x_STAT1 0x05
72#define STV6110x_OFFST_STAT1_CALVCO_STRT 2
73#define STV6110x_WIDTH_STAT1_CALVCO_STRT 1
74#define STV6110x_OFFST_STAT1_CALRC_STRT 1
75#define STV6110x_WIDTH_STAT1_CALRC_STRT 1
76#define STV6110x_OFFST_STAT1_LOCK 0
77#define STV6110x_WIDTH_STAT1_LOCK 1
78
79#define STV6110x_STAT2 0x06
80#define STV6110x_STAT3 0x07
81
82#endif /* __STV6110x_REG_H */
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
index 2a8bbcd44cd0..4302c563a6b8 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -1,7 +1,7 @@
1/* 1/*
2 NXP TDA10048HN DVB OFDM demodulator driver 2 NXP TDA10048HN DVB OFDM demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> 4 Copyright (C) 2009 Steven Toth <stoth@kernellabs.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <asm/div64.h>
28#include "dvb_frontend.h" 29#include "dvb_frontend.h"
29#include "dvb_math.h" 30#include "dvb_math.h"
30#include "tda10048.h" 31#include "tda10048.h"
@@ -138,11 +139,20 @@ struct tda10048_state {
138 139
139 struct i2c_adapter *i2c; 140 struct i2c_adapter *i2c;
140 141
141 /* configuration settings */ 142 /* We'll cache and update the attach config settings */
142 const struct tda10048_config *config; 143 struct tda10048_config config;
143 struct dvb_frontend frontend; 144 struct dvb_frontend frontend;
144 145
145 int fwloaded; 146 int fwloaded;
147
148 u32 freq_if_hz;
149 u32 xtal_hz;
150 u32 pll_mfactor;
151 u32 pll_nfactor;
152 u32 pll_pfactor;
153 u32 sample_freq;
154
155 enum fe_bandwidth bandwidth;
146}; 156};
147 157
148static struct init_tab { 158static struct init_tab {
@@ -192,12 +202,26 @@ static struct init_tab {
192 { TDA10048_CONF_C4_2, 0x04 }, 202 { TDA10048_CONF_C4_2, 0x04 },
193}; 203};
194 204
205static struct pll_tab {
206 u32 clk_freq_khz;
207 u32 if_freq_khz;
208 u8 m, n, p;
209} pll_tab[] = {
210 { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 },
211 { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 },
212 { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 },
213 { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 },
214 { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 },
215 { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 },
216};
217
195static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) 218static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
196{ 219{
220 struct tda10048_config *config = &state->config;
197 int ret; 221 int ret;
198 u8 buf[] = { reg, data }; 222 u8 buf[] = { reg, data };
199 struct i2c_msg msg = { 223 struct i2c_msg msg = {
200 .addr = state->config->demod_address, 224 .addr = config->demod_address,
201 .flags = 0, .buf = buf, .len = 2 }; 225 .flags = 0, .buf = buf, .len = 2 };
202 226
203 dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); 227 dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data);
@@ -212,13 +236,14 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
212 236
213static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) 237static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
214{ 238{
239 struct tda10048_config *config = &state->config;
215 int ret; 240 int ret;
216 u8 b0[] = { reg }; 241 u8 b0[] = { reg };
217 u8 b1[] = { 0 }; 242 u8 b1[] = { 0 };
218 struct i2c_msg msg[] = { 243 struct i2c_msg msg[] = {
219 { .addr = state->config->demod_address, 244 { .addr = config->demod_address,
220 .flags = 0, .buf = b0, .len = 1 }, 245 .flags = 0, .buf = b0, .len = 1 },
221 { .addr = state->config->demod_address, 246 { .addr = config->demod_address,
222 .flags = I2C_M_RD, .buf = b1, .len = 1 } }; 247 .flags = I2C_M_RD, .buf = b1, .len = 1 } };
223 248
224 dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); 249 dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg);
@@ -235,6 +260,7 @@ static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
235static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, 260static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
236 const u8 *data, u16 len) 261 const u8 *data, u16 len)
237{ 262{
263 struct tda10048_config *config = &state->config;
238 int ret = -EREMOTEIO; 264 int ret = -EREMOTEIO;
239 struct i2c_msg msg; 265 struct i2c_msg msg;
240 u8 *buf; 266 u8 *buf;
@@ -250,7 +276,7 @@ static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
250 *buf = reg; 276 *buf = reg;
251 memcpy(buf + 1, data, len); 277 memcpy(buf + 1, data, len);
252 278
253 msg.addr = state->config->demod_address; 279 msg.addr = config->demod_address;
254 msg.flags = 0; 280 msg.flags = 0;
255 msg.buf = buf; 281 msg.buf = buf;
256 msg.len = len + 1; 282 msg.len = len + 1;
@@ -271,14 +297,206 @@ error:
271 return ret; 297 return ret;
272} 298}
273 299
300static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz,
301 u32 if_hz)
302{
303 struct tda10048_state *state = fe->demodulator_priv;
304 u64 t;
305
306 dprintk(1, "%s()\n", __func__);
307
308 if (sample_freq_hz == 0)
309 return -EINVAL;
310
311 if (if_hz < (sample_freq_hz / 2)) {
312 /* PHY2 = (if2/fs) * 2^15 */
313 t = if_hz;
314 t *= 10;
315 t *= 32768;
316 do_div(t, sample_freq_hz);
317 t += 5;
318 do_div(t, 10);
319 } else {
320 /* PHY2 = ((IF1-fs)/fs) * 2^15 */
321 t = sample_freq_hz - if_hz;
322 t *= 10;
323 t *= 32768;
324 do_div(t, sample_freq_hz);
325 t += 5;
326 do_div(t, 10);
327 t = ~t + 1;
328 }
329
330 tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t);
331 tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8));
332
333 return 0;
334}
335
336static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz,
337 u32 bw)
338{
339 struct tda10048_state *state = fe->demodulator_priv;
340 u64 t, z;
341 u32 b = 8000000;
342
343 dprintk(1, "%s()\n", __func__);
344
345 if (sample_freq_hz == 0)
346 return -EINVAL;
347
348 if (bw == BANDWIDTH_6_MHZ)
349 b = 6000000;
350 else
351 if (bw == BANDWIDTH_7_MHZ)
352 b = 7000000;
353
354 /* WREF = (B / (7 * fs)) * 2^31 */
355 t = b * 10;
356 /* avoid warning: this decimal constant is unsigned only in ISO C90 */
357 /* t *= 2147483648 on 32bit platforms */
358 t *= (2048 * 1024);
359 t *= 1024;
360 z = 7 * sample_freq_hz;
361 do_div(t, z);
362 t += 5;
363 do_div(t, 10);
364
365 tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t);
366 tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8));
367 tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16));
368 tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24));
369
370 return 0;
371}
372
373static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz,
374 u32 bw)
375{
376 struct tda10048_state *state = fe->demodulator_priv;
377 u64 t;
378 u32 b = 8000000;
379
380 dprintk(1, "%s()\n", __func__);
381
382 if (sample_freq_hz == 0)
383 return -EINVAL;
384
385 if (bw == BANDWIDTH_6_MHZ)
386 b = 6000000;
387 else
388 if (bw == BANDWIDTH_7_MHZ)
389 b = 7000000;
390
391 /* INVWREF = ((7 * fs) / B) * 2^5 */
392 t = sample_freq_hz;
393 t *= 7;
394 t *= 32;
395 t *= 10;
396 do_div(t, b);
397 t += 5;
398 do_div(t, 10);
399
400 tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t);
401 tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8));
402
403 return 0;
404}
405
406static int tda10048_set_bandwidth(struct dvb_frontend *fe,
407 enum fe_bandwidth bw)
408{
409 struct tda10048_state *state = fe->demodulator_priv;
410 dprintk(1, "%s(bw=%d)\n", __func__, bw);
411
412 /* Bandwidth setting may need to be adjusted */
413 switch (bw) {
414 case BANDWIDTH_6_MHZ:
415 case BANDWIDTH_7_MHZ:
416 case BANDWIDTH_8_MHZ:
417 tda10048_set_wref(fe, state->sample_freq, bw);
418 tda10048_set_invwref(fe, state->sample_freq, bw);
419 break;
420 default:
421 printk(KERN_ERR "%s() invalid bandwidth\n", __func__);
422 return -EINVAL;
423 }
424
425 state->bandwidth = bw;
426
427 return 0;
428}
429
430static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw)
431{
432 struct tda10048_state *state = fe->demodulator_priv;
433 struct tda10048_config *config = &state->config;
434 int i;
435 u32 if_freq_khz;
436
437 dprintk(1, "%s(bw = %d)\n", __func__, bw);
438
439 /* based on target bandwidth and clk we calculate pll factors */
440 switch (bw) {
441 case BANDWIDTH_6_MHZ:
442 if_freq_khz = config->dtv6_if_freq_khz;
443 break;
444 case BANDWIDTH_7_MHZ:
445 if_freq_khz = config->dtv7_if_freq_khz;
446 break;
447 case BANDWIDTH_8_MHZ:
448 if_freq_khz = config->dtv8_if_freq_khz;
449 break;
450 default:
451 printk(KERN_ERR "%s() no default\n", __func__);
452 return -EINVAL;
453 }
454
455 for (i = 0; i < ARRAY_SIZE(pll_tab); i++) {
456 if ((pll_tab[i].clk_freq_khz == config->clk_freq_khz) &&
457 (pll_tab[i].if_freq_khz == if_freq_khz)) {
458
459 state->freq_if_hz = pll_tab[i].if_freq_khz * 1000;
460 state->xtal_hz = pll_tab[i].clk_freq_khz * 1000;
461 state->pll_mfactor = pll_tab[i].m;
462 state->pll_nfactor = pll_tab[i].n;
463 state->pll_pfactor = pll_tab[i].p;
464 break;
465 }
466 }
467 if (i == ARRAY_SIZE(pll_tab)) {
468 printk(KERN_ERR "%s() Incorrect attach settings\n",
469 __func__);
470 return -EINVAL;
471 }
472
473 dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz);
474 dprintk(1, "- xtal_hz = %d\n", state->xtal_hz);
475 dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor);
476 dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor);
477 dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
478
479 /* Calculate the sample frequency */
480 state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
481 state->sample_freq /= (state->pll_nfactor + 1);
482 state->sample_freq /= (state->pll_pfactor + 4);
483 dprintk(1, "- sample_freq = %d\n", state->sample_freq);
484
485 /* Update the I/F */
486 tda10048_set_phy2(fe, state->sample_freq, state->freq_if_hz);
487
488 return 0;
489}
490
274static int tda10048_firmware_upload(struct dvb_frontend *fe) 491static int tda10048_firmware_upload(struct dvb_frontend *fe)
275{ 492{
276 struct tda10048_state *state = fe->demodulator_priv; 493 struct tda10048_state *state = fe->demodulator_priv;
494 struct tda10048_config *config = &state->config;
277 const struct firmware *fw; 495 const struct firmware *fw;
278 int ret; 496 int ret;
279 int pos = 0; 497 int pos = 0;
280 int cnt; 498 int cnt;
281 u8 wlen = state->config->fwbulkwritelen; 499 u8 wlen = config->fwbulkwritelen;
282 500
283 if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) 501 if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50))
284 wlen = TDA10048_BULKWRITE_200; 502 wlen = TDA10048_BULKWRITE_200;
@@ -289,7 +507,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe)
289 TDA10048_DEFAULT_FIRMWARE); 507 TDA10048_DEFAULT_FIRMWARE);
290 508
291 ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, 509 ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE,
292 &state->i2c->dev); 510 state->i2c->dev.parent);
293 if (ret) { 511 if (ret) {
294 printk(KERN_ERR "%s: Upload failed. (file not found?)\n", 512 printk(KERN_ERR "%s: Upload failed. (file not found?)\n",
295 __func__); 513 __func__);
@@ -484,8 +702,12 @@ static int tda10048_get_tps(struct tda10048_state *state,
484static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 702static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
485{ 703{
486 struct tda10048_state *state = fe->demodulator_priv; 704 struct tda10048_state *state = fe->demodulator_priv;
705 struct tda10048_config *config = &state->config;
487 dprintk(1, "%s(%d)\n", __func__, enable); 706 dprintk(1, "%s(%d)\n", __func__, enable);
488 707
708 if (config->disable_gate_access)
709 return 0;
710
489 if (enable) 711 if (enable)
490 return tda10048_writereg(state, TDA10048_CONF_C4_1, 712 return tda10048_writereg(state, TDA10048_CONF_C4_1,
491 tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); 713 tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
@@ -523,6 +745,12 @@ static int tda10048_set_frontend(struct dvb_frontend *fe,
523 745
524 dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); 746 dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);
525 747
748 /* Update the I/F pll's if the bandwidth changes */
749 if (p->u.ofdm.bandwidth != state->bandwidth) {
750 tda10048_set_if(fe, p->u.ofdm.bandwidth);
751 tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth);
752 }
753
526 if (fe->ops.tuner_ops.set_params) { 754 if (fe->ops.tuner_ops.set_params) {
527 755
528 if (fe->ops.i2c_gate_ctrl) 756 if (fe->ops.i2c_gate_ctrl)
@@ -544,6 +772,7 @@ static int tda10048_set_frontend(struct dvb_frontend *fe,
544static int tda10048_init(struct dvb_frontend *fe) 772static int tda10048_init(struct dvb_frontend *fe)
545{ 773{
546 struct tda10048_state *state = fe->demodulator_priv; 774 struct tda10048_state *state = fe->demodulator_priv;
775 struct tda10048_config *config = &state->config;
547 int ret = 0, i; 776 int ret = 0, i;
548 777
549 dprintk(1, "%s()\n", __func__); 778 dprintk(1, "%s()\n", __func__);
@@ -556,10 +785,14 @@ static int tda10048_init(struct dvb_frontend *fe)
556 ret = tda10048_firmware_upload(fe); 785 ret = tda10048_firmware_upload(fe);
557 786
558 /* Set either serial or parallel */ 787 /* Set either serial or parallel */
559 tda10048_output_mode(fe, state->config->output_mode); 788 tda10048_output_mode(fe, config->output_mode);
789
790 /* Set inversion */
791 tda10048_set_inversion(fe, config->inversion);
560 792
561 /* set inversion */ 793 /* Establish default RF values */
562 tda10048_set_inversion(fe, state->config->inversion); 794 tda10048_set_if(fe, BANDWIDTH_8_MHZ);
795 tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ);
563 796
564 /* Ensure we leave the gate closed */ 797 /* Ensure we leave the gate closed */
565 tda10048_i2c_gate_ctrl(fe, 0); 798 tda10048_i2c_gate_ctrl(fe, 0);
@@ -812,6 +1045,45 @@ static void tda10048_release(struct dvb_frontend *fe)
812 kfree(state); 1045 kfree(state);
813} 1046}
814 1047
1048static void tda10048_establish_defaults(struct dvb_frontend *fe)
1049{
1050 struct tda10048_state *state = fe->demodulator_priv;
1051 struct tda10048_config *config = &state->config;
1052
1053 /* Validate/default the config */
1054 if (config->dtv6_if_freq_khz == 0) {
1055 config->dtv6_if_freq_khz = TDA10048_IF_4300;
1056 printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz "
1057 "is not set (defaulting to %d)\n",
1058 __func__,
1059 config->dtv6_if_freq_khz);
1060 }
1061
1062 if (config->dtv7_if_freq_khz == 0) {
1063 config->dtv7_if_freq_khz = TDA10048_IF_4300;
1064 printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz "
1065 "is not set (defaulting to %d)\n",
1066 __func__,
1067 config->dtv7_if_freq_khz);
1068 }
1069
1070 if (config->dtv8_if_freq_khz == 0) {
1071 config->dtv8_if_freq_khz = TDA10048_IF_4300;
1072 printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz "
1073 "is not set (defaulting to %d)\n",
1074 __func__,
1075 config->dtv8_if_freq_khz);
1076 }
1077
1078 if (config->clk_freq_khz == 0) {
1079 config->clk_freq_khz = TDA10048_CLK_16000;
1080 printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz "
1081 "is not set (defaulting to %d)\n",
1082 __func__,
1083 config->clk_freq_khz);
1084 }
1085}
1086
815static struct dvb_frontend_ops tda10048_ops; 1087static struct dvb_frontend_ops tda10048_ops;
816 1088
817struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, 1089struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
@@ -826,10 +1098,11 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
826 if (state == NULL) 1098 if (state == NULL)
827 goto error; 1099 goto error;
828 1100
829 /* setup the state */ 1101 /* setup the state and clone the config */
830 state->config = config; 1102 memcpy(&state->config, config, sizeof(*config));
831 state->i2c = i2c; 1103 state->i2c = i2c;
832 state->fwloaded = 0; 1104 state->fwloaded = 0;
1105 state->bandwidth = BANDWIDTH_8_MHZ;
833 1106
834 /* check if the demod is present */ 1107 /* check if the demod is present */
835 if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) 1108 if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)
@@ -840,6 +1113,17 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
840 sizeof(struct dvb_frontend_ops)); 1113 sizeof(struct dvb_frontend_ops));
841 state->frontend.demodulator_priv = state; 1114 state->frontend.demodulator_priv = state;
842 1115
1116 /* Establish any defaults the the user didn't pass */
1117 tda10048_establish_defaults(&state->frontend);
1118
1119 /* Set the xtal and freq defaults */
1120 if (tda10048_set_if(&state->frontend, BANDWIDTH_8_MHZ) != 0)
1121 goto error;
1122
1123 /* Default bandwidth */
1124 if (tda10048_set_bandwidth(&state->frontend, BANDWIDTH_8_MHZ) != 0)
1125 goto error;
1126
843 /* Leave the gate closed */ 1127 /* Leave the gate closed */
844 tda10048_i2c_gate_ctrl(&state->frontend, 0); 1128 tda10048_i2c_gate_ctrl(&state->frontend, 0);
845 1129
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h
index 0457b24601fa..8828ceaf74bb 100644
--- a/drivers/media/dvb/frontends/tda10048.h
+++ b/drivers/media/dvb/frontends/tda10048.h
@@ -1,7 +1,7 @@
1/* 1/*
2 NXP TDA10048HN DVB OFDM demodulator driver 2 NXP TDA10048HN DVB OFDM demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> 4 Copyright (C) 2009 Steven Toth <stoth@kernellabs.com>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -43,6 +43,25 @@ struct tda10048_config {
43#define TDA10048_INVERSION_OFF 0 43#define TDA10048_INVERSION_OFF 0
44#define TDA10048_INVERSION_ON 1 44#define TDA10048_INVERSION_ON 1
45 u8 inversion; 45 u8 inversion;
46
47#define TDA10048_IF_3300 3300
48#define TDA10048_IF_3500 3500
49#define TDA10048_IF_3800 3800
50#define TDA10048_IF_4000 4000
51#define TDA10048_IF_4300 4300
52#define TDA10048_IF_4500 4500
53#define TDA10048_IF_4750 4750
54#define TDA10048_IF_36130 36130
55 u16 dtv6_if_freq_khz;
56 u16 dtv7_if_freq_khz;
57 u16 dtv8_if_freq_khz;
58
59#define TDA10048_CLK_4000 4000
60#define TDA10048_CLK_16000 16000
61 u16 clk_freq_khz;
62
63 /* Disable I2C gate access */
64 u8 disable_gate_access;
46}; 65};
47 66
48#if defined(CONFIG_DVB_TDA10048) || \ 67#if defined(CONFIG_DVB_TDA10048) || \
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
index bcf93f4828b2..c6644d909433 100644
--- a/drivers/media/dvb/siano/Makefile
+++ b/drivers/media/dvb/siano/Makefile
@@ -1,4 +1,4 @@
1sms1xxx-objs := smscoreapi.o sms-cards.o 1sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
2 2
3obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o 3obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
4obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o 4obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 63e4d0ec6583..d8b15d583bde 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "sms-cards.h" 20#include "sms-cards.h"
21#include "smsir.h"
21 22
22static int sms_dbg; 23static int sms_dbg;
23module_param_named(cards_dbg, sms_dbg, int, 0644); 24module_param_named(cards_dbg, sms_dbg, int, 0644);
@@ -30,17 +31,14 @@ static struct sms_board sms_boards[] = {
30 [SMS1XXX_BOARD_SIANO_STELLAR] = { 31 [SMS1XXX_BOARD_SIANO_STELLAR] = {
31 .name = "Siano Stellar Digital Receiver", 32 .name = "Siano Stellar Digital Receiver",
32 .type = SMS_STELLAR, 33 .type = SMS_STELLAR,
33 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
34 }, 34 },
35 [SMS1XXX_BOARD_SIANO_NOVA_A] = { 35 [SMS1XXX_BOARD_SIANO_NOVA_A] = {
36 .name = "Siano Nova A Digital Receiver", 36 .name = "Siano Nova A Digital Receiver",
37 .type = SMS_NOVA_A0, 37 .type = SMS_NOVA_A0,
38 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
39 }, 38 },
40 [SMS1XXX_BOARD_SIANO_NOVA_B] = { 39 [SMS1XXX_BOARD_SIANO_NOVA_B] = {
41 .name = "Siano Nova B Digital Receiver", 40 .name = "Siano Nova B Digital Receiver",
42 .type = SMS_NOVA_B0, 41 .type = SMS_NOVA_B0,
43 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
44 }, 42 },
45 [SMS1XXX_BOARD_SIANO_VEGA] = { 43 [SMS1XXX_BOARD_SIANO_VEGA] = {
46 .name = "Siano Vega Digital Receiver", 44 .name = "Siano Vega Digital Receiver",
@@ -65,6 +63,9 @@ static struct sms_board sms_boards[] = {
65 .name = "Hauppauge WinTV MiniStick", 63 .name = "Hauppauge WinTV MiniStick",
66 .type = SMS_NOVA_B0, 64 .type = SMS_NOVA_B0,
67 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 65 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
66 .board_cfg.leds_power = 26,
67 .board_cfg.led0 = 27,
68 .board_cfg.led1 = 28,
68 .led_power = 26, 69 .led_power = 26,
69 .led_lo = 27, 70 .led_lo = 27,
70 .led_hi = 28, 71 .led_hi = 28,
@@ -74,7 +75,9 @@ static struct sms_board sms_boards[] = {
74 .type = SMS_NOVA_B0, 75 .type = SMS_NOVA_B0,
75 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 76 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
76 .lna_ctrl = 29, 77 .lna_ctrl = 29,
78 .board_cfg.foreign_lna0_ctrl = 29,
77 .rf_switch = 17, 79 .rf_switch = 17,
80 .board_cfg.rf_switch_uhf = 17,
78 }, 81 },
79 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { 82 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
80 .name = "Hauppauge WinTV MiniCard", 83 .name = "Hauppauge WinTV MiniCard",
@@ -82,6 +85,16 @@ static struct sms_board sms_boards[] = {
82 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 85 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
83 .lna_ctrl = -1, 86 .lna_ctrl = -1,
84 }, 87 },
88 [SMS1XXX_BOARD_SIANO_NICE] = {
89 /* 11 */
90 .name = "Siano Nice Digital Receiver",
91 .type = SMS_NOVA_B0,
92 },
93 [SMS1XXX_BOARD_SIANO_VENICE] = {
94 /* 12 */
95 .name = "Siano Venice Digital Receiver",
96 .type = SMS_VEGA,
97 },
85}; 98};
86 99
87struct sms_board *sms_get_board(int id) 100struct sms_board *sms_get_board(int id)
@@ -91,12 +104,179 @@ struct sms_board *sms_get_board(int id)
91 return &sms_boards[id]; 104 return &sms_boards[id];
92} 105}
93EXPORT_SYMBOL_GPL(sms_get_board); 106EXPORT_SYMBOL_GPL(sms_get_board);
107static inline void sms_gpio_assign_11xx_default_led_config(
108 struct smscore_gpio_config *pGpioConfig) {
109 pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
110 pGpioConfig->InputCharacteristics =
111 SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
112 pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
113 pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
114 pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
115}
116
117int sms_board_event(struct smscore_device_t *coredev,
118 enum SMS_BOARD_EVENTS gevent) {
119 int board_id = smscore_get_board_id(coredev);
120 struct sms_board *board = sms_get_board(board_id);
121 struct smscore_gpio_config MyGpioConfig;
122
123 sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
124
125 switch (gevent) {
126 case BOARD_EVENT_POWER_INIT: /* including hotplug */
127 switch (board_id) {
128 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
129 /* set I/O and turn off all LEDs */
130 smscore_gpio_configure(coredev,
131 board->board_cfg.leds_power,
132 &MyGpioConfig);
133 smscore_gpio_set_level(coredev,
134 board->board_cfg.leds_power, 0);
135 smscore_gpio_configure(coredev, board->board_cfg.led0,
136 &MyGpioConfig);
137 smscore_gpio_set_level(coredev,
138 board->board_cfg.led0, 0);
139 smscore_gpio_configure(coredev, board->board_cfg.led1,
140 &MyGpioConfig);
141 smscore_gpio_set_level(coredev,
142 board->board_cfg.led1, 0);
143 break;
144 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
145 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
146 /* set I/O and turn off LNA */
147 smscore_gpio_configure(coredev,
148 board->board_cfg.foreign_lna0_ctrl,
149 &MyGpioConfig);
150 smscore_gpio_set_level(coredev,
151 board->board_cfg.foreign_lna0_ctrl,
152 0);
153 break;
154 }
155 break; /* BOARD_EVENT_BIND */
156
157 case BOARD_EVENT_POWER_SUSPEND:
158 switch (board_id) {
159 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
160 smscore_gpio_set_level(coredev,
161 board->board_cfg.leds_power, 0);
162 smscore_gpio_set_level(coredev,
163 board->board_cfg.led0, 0);
164 smscore_gpio_set_level(coredev,
165 board->board_cfg.led1, 0);
166 break;
167 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
168 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
169 smscore_gpio_set_level(coredev,
170 board->board_cfg.foreign_lna0_ctrl,
171 0);
172 break;
173 }
174 break; /* BOARD_EVENT_POWER_SUSPEND */
175
176 case BOARD_EVENT_POWER_RESUME:
177 switch (board_id) {
178 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
179 smscore_gpio_set_level(coredev,
180 board->board_cfg.leds_power, 1);
181 smscore_gpio_set_level(coredev,
182 board->board_cfg.led0, 1);
183 smscore_gpio_set_level(coredev,
184 board->board_cfg.led1, 0);
185 break;
186 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
187 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
188 smscore_gpio_set_level(coredev,
189 board->board_cfg.foreign_lna0_ctrl,
190 1);
191 break;
192 }
193 break; /* BOARD_EVENT_POWER_RESUME */
194
195 case BOARD_EVENT_BIND:
196 switch (board_id) {
197 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
198 smscore_gpio_set_level(coredev,
199 board->board_cfg.leds_power, 1);
200 smscore_gpio_set_level(coredev,
201 board->board_cfg.led0, 1);
202 smscore_gpio_set_level(coredev,
203 board->board_cfg.led1, 0);
204 break;
205 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
206 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
207 smscore_gpio_set_level(coredev,
208 board->board_cfg.foreign_lna0_ctrl,
209 1);
210 break;
211 }
212 break; /* BOARD_EVENT_BIND */
213
214 case BOARD_EVENT_SCAN_PROG:
215 break; /* BOARD_EVENT_SCAN_PROG */
216 case BOARD_EVENT_SCAN_COMP:
217 break; /* BOARD_EVENT_SCAN_COMP */
218 case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
219 break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
220 case BOARD_EVENT_FE_LOCK:
221 switch (board_id) {
222 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
223 smscore_gpio_set_level(coredev,
224 board->board_cfg.led1, 1);
225 break;
226 }
227 break; /* BOARD_EVENT_FE_LOCK */
228 case BOARD_EVENT_FE_UNLOCK:
229 switch (board_id) {
230 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
231 smscore_gpio_set_level(coredev,
232 board->board_cfg.led1, 0);
233 break;
234 }
235 break; /* BOARD_EVENT_FE_UNLOCK */
236 case BOARD_EVENT_DEMOD_LOCK:
237 break; /* BOARD_EVENT_DEMOD_LOCK */
238 case BOARD_EVENT_DEMOD_UNLOCK:
239 break; /* BOARD_EVENT_DEMOD_UNLOCK */
240 case BOARD_EVENT_RECEPTION_MAX_4:
241 break; /* BOARD_EVENT_RECEPTION_MAX_4 */
242 case BOARD_EVENT_RECEPTION_3:
243 break; /* BOARD_EVENT_RECEPTION_3 */
244 case BOARD_EVENT_RECEPTION_2:
245 break; /* BOARD_EVENT_RECEPTION_2 */
246 case BOARD_EVENT_RECEPTION_1:
247 break; /* BOARD_EVENT_RECEPTION_1 */
248 case BOARD_EVENT_RECEPTION_LOST_0:
249 break; /* BOARD_EVENT_RECEPTION_LOST_0 */
250 case BOARD_EVENT_MULTIPLEX_OK:
251 switch (board_id) {
252 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
253 smscore_gpio_set_level(coredev,
254 board->board_cfg.led1, 1);
255 break;
256 }
257 break; /* BOARD_EVENT_MULTIPLEX_OK */
258 case BOARD_EVENT_MULTIPLEX_ERRORS:
259 switch (board_id) {
260 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
261 smscore_gpio_set_level(coredev,
262 board->board_cfg.led1, 0);
263 break;
264 }
265 break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
266
267 default:
268 sms_err("Unknown SMS board event");
269 break;
270 }
271 return 0;
272}
273EXPORT_SYMBOL_GPL(sms_board_event);
94 274
95static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) 275static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
96{ 276{
97 int lvl, ret; 277 int lvl, ret;
98 u32 gpio; 278 u32 gpio;
99 struct smscore_gpio_config gpioconfig = { 279 struct smscore_config_gpio gpioconfig = {
100 .direction = SMS_GPIO_DIRECTION_OUTPUT, 280 .direction = SMS_GPIO_DIRECTION_OUTPUT,
101 .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, 281 .pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
102 .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, 282 .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 64d74c59c33f..38f062f6ad68 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -22,6 +22,7 @@
22 22
23#include <linux/usb.h> 23#include <linux/usb.h>
24#include "smscoreapi.h" 24#include "smscoreapi.h"
25#include "smsir.h"
25 26
26#define SMS_BOARD_UNKNOWN 0 27#define SMS_BOARD_UNKNOWN 0
27#define SMS1XXX_BOARD_SIANO_STELLAR 1 28#define SMS1XXX_BOARD_SIANO_STELLAR 1
@@ -34,10 +35,47 @@
34#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 35#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
35#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 36#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
36#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 37#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
38#define SMS1XXX_BOARD_SIANO_NICE 11
39#define SMS1XXX_BOARD_SIANO_VENICE 12
40
41struct sms_board_gpio_cfg {
42 int lna_vhf_exist;
43 int lna_vhf_ctrl;
44 int lna_uhf_exist;
45 int lna_uhf_ctrl;
46 int lna_uhf_d_ctrl;
47 int lna_sband_exist;
48 int lna_sband_ctrl;
49 int lna_sband_d_ctrl;
50 int foreign_lna0_ctrl;
51 int foreign_lna1_ctrl;
52 int foreign_lna2_ctrl;
53 int rf_switch_vhf;
54 int rf_switch_uhf;
55 int rf_switch_sband;
56 int leds_power;
57 int led0;
58 int led1;
59 int led2;
60 int led3;
61 int led4;
62 int ir;
63 int eeprom_wp;
64 int mrc_sense;
65 int mrc_pdn_resetn;
66 int mrc_gp0; /* mrcs spi int */
67 int mrc_gp1;
68 int mrc_gp2;
69 int mrc_gp3;
70 int mrc_gp4;
71 int host_spi_gsp_ts_int;
72};
37 73
38struct sms_board { 74struct sms_board {
39 enum sms_device_type_st type; 75 enum sms_device_type_st type;
40 char *name, *fw[DEVICE_MODE_MAX]; 76 char *name, *fw[DEVICE_MODE_MAX];
77 struct sms_board_gpio_cfg board_cfg;
78 enum ir_kb_type ir_kb_type;
41 79
42 /* gpios */ 80 /* gpios */
43 int led_power, led_hi, led_lo, lna_ctrl, rf_switch; 81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
@@ -45,6 +83,32 @@ struct sms_board {
45 83
46struct sms_board *sms_get_board(int id); 84struct sms_board *sms_get_board(int id);
47 85
86extern struct smscore_device_t *coredev;
87
88enum SMS_BOARD_EVENTS {
89 BOARD_EVENT_POWER_INIT,
90 BOARD_EVENT_POWER_SUSPEND,
91 BOARD_EVENT_POWER_RESUME,
92 BOARD_EVENT_BIND,
93 BOARD_EVENT_SCAN_PROG,
94 BOARD_EVENT_SCAN_COMP,
95 BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
96 BOARD_EVENT_FE_LOCK,
97 BOARD_EVENT_FE_UNLOCK,
98 BOARD_EVENT_DEMOD_LOCK,
99 BOARD_EVENT_DEMOD_UNLOCK,
100 BOARD_EVENT_RECEPTION_MAX_4,
101 BOARD_EVENT_RECEPTION_3,
102 BOARD_EVENT_RECEPTION_2,
103 BOARD_EVENT_RECEPTION_1,
104 BOARD_EVENT_RECEPTION_LOST_0,
105 BOARD_EVENT_MULTIPLEX_OK,
106 BOARD_EVENT_MULTIPLEX_ERRORS
107};
108
109int sms_board_event(struct smscore_device_t *coredev,
110 enum SMS_BOARD_EVENTS gevent);
111
48int sms_board_setup(struct smscore_device_t *coredev); 112int sms_board_setup(struct smscore_device_t *coredev);
49 113
50#define SMS_LED_OFF 0 114#define SMS_LED_OFF 0
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 7bd4d1dee2b3..32be382f0e97 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -30,9 +30,13 @@
30#include <linux/io.h> 30#include <linux/io.h>
31 31
32#include <linux/firmware.h> 32#include <linux/firmware.h>
33#include <linux/wait.h>
34#include <asm/byteorder.h>
33 35
34#include "smscoreapi.h" 36#include "smscoreapi.h"
35#include "sms-cards.h" 37#include "sms-cards.h"
38#include "smsir.h"
39#include "smsendian.h"
36 40
37static int sms_dbg; 41static int sms_dbg;
38module_param_named(debug, sms_dbg, int, 0644); 42module_param_named(debug, sms_dbg, int, 0644);
@@ -58,42 +62,6 @@ struct smscore_client_t {
58 onremove_t onremove_handler; 62 onremove_t onremove_handler;
59}; 63};
60 64
61struct smscore_device_t {
62 struct list_head entry;
63
64 struct list_head clients;
65 struct list_head subclients;
66 spinlock_t clientslock;
67
68 struct list_head buffers;
69 spinlock_t bufferslock;
70 int num_buffers;
71
72 void *common_buffer;
73 int common_buffer_size;
74 dma_addr_t common_buffer_phys;
75
76 void *context;
77 struct device *device;
78
79 char devpath[32];
80 unsigned long device_flags;
81
82 setmode_t setmode_handler;
83 detectmode_t detectmode_handler;
84 sendrequest_t sendrequest_handler;
85 preload_t preload_handler;
86 postload_t postload_handler;
87
88 int mode, modes_supported;
89
90 struct completion version_ex_done, data_download_done, trigger_done;
91 struct completion init_device_done, reload_start_done, resume_done;
92
93 int board_id;
94 int led_state;
95};
96
97void smscore_set_board_id(struct smscore_device_t *core, int id) 65void smscore_set_board_id(struct smscore_device_t *core, int id)
98{ 66{
99 core->board_id = id; 67 core->board_id = id;
@@ -384,6 +352,13 @@ int smscore_register_device(struct smsdevice_params_t *params,
384 init_completion(&dev->init_device_done); 352 init_completion(&dev->init_device_done);
385 init_completion(&dev->reload_start_done); 353 init_completion(&dev->reload_start_done);
386 init_completion(&dev->resume_done); 354 init_completion(&dev->resume_done);
355 init_completion(&dev->gpio_configuration_done);
356 init_completion(&dev->gpio_set_level_done);
357 init_completion(&dev->gpio_get_level_done);
358 init_completion(&dev->ir_init_done);
359
360 /* Buffer management */
361 init_waitqueue_head(&dev->buffer_mng_waitq);
387 362
388 /* alloc common buffer */ 363 /* alloc common buffer */
389 dev->common_buffer_size = params->buffer_size * params->num_buffers; 364 dev->common_buffer_size = params->buffer_size * params->num_buffers;
@@ -439,6 +414,71 @@ int smscore_register_device(struct smsdevice_params_t *params,
439} 414}
440EXPORT_SYMBOL_GPL(smscore_register_device); 415EXPORT_SYMBOL_GPL(smscore_register_device);
441 416
417
418static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
419 void *buffer, size_t size, struct completion *completion) {
420 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
421 if (rc < 0) {
422 sms_info("sendrequest returned error %d", rc);
423 return rc;
424 }
425
426 return wait_for_completion_timeout(completion,
427 msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
428 0 : -ETIME;
429}
430
431/**
432 * Starts & enables IR operations
433 *
434 * @return 0 on success, < 0 on error.
435 */
436static int smscore_init_ir(struct smscore_device_t *coredev)
437{
438 int ir_io;
439 int rc;
440 void *buffer;
441
442 coredev->ir.input_dev = NULL;
443 ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
444 if (ir_io) {/* only if IR port exist we use IR sub-module */
445 sms_info("IR loading");
446 rc = sms_ir_init(coredev);
447
448 if (rc != 0)
449 sms_err("Error initialization DTV IR sub-module");
450 else {
451 buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
452 SMS_DMA_ALIGNMENT,
453 GFP_KERNEL | GFP_DMA);
454 if (buffer) {
455 struct SmsMsgData_ST2 *msg =
456 (struct SmsMsgData_ST2 *)
457 SMS_ALIGN_ADDRESS(buffer);
458
459 SMS_INIT_MSG(&msg->xMsgHeader,
460 MSG_SMS_START_IR_REQ,
461 sizeof(struct SmsMsgData_ST2));
462 msg->msgData[0] = coredev->ir.controller;
463 msg->msgData[1] = coredev->ir.timeout;
464
465 smsendian_handle_tx_message(
466 (struct SmsMsgHdr_ST2 *)msg);
467 rc = smscore_sendrequest_and_wait(coredev, msg,
468 msg->xMsgHeader. msgLength,
469 &coredev->ir_init_done);
470
471 kfree(buffer);
472 } else
473 sms_err
474 ("Sending IR initialization message failed");
475 }
476 } else
477 sms_info("IR port has not been detected");
478
479 return 0;
480}
481
442/** 482/**
443 * sets initial device mode and notifies client hotplugs that device is ready 483 * sets initial device mode and notifies client hotplugs that device is ready
444 * 484 *
@@ -459,6 +499,7 @@ int smscore_start_device(struct smscore_device_t *coredev)
459 kmutex_lock(&g_smscore_deviceslock); 499 kmutex_lock(&g_smscore_deviceslock);
460 500
461 rc = smscore_notify_callbacks(coredev, coredev->device, 1); 501 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
502 smscore_init_ir(coredev);
462 503
463 sms_info("device %p started, rc %d", coredev, rc); 504 sms_info("device %p started, rc %d", coredev, rc);
464 505
@@ -468,29 +509,19 @@ int smscore_start_device(struct smscore_device_t *coredev)
468} 509}
469EXPORT_SYMBOL_GPL(smscore_start_device); 510EXPORT_SYMBOL_GPL(smscore_start_device);
470 511
471static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
472 void *buffer, size_t size,
473 struct completion *completion)
474{
475 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
476 if (rc < 0) {
477 sms_info("sendrequest returned error %d", rc);
478 return rc;
479 }
480
481 return wait_for_completion_timeout(completion,
482 msecs_to_jiffies(10000)) ?
483 0 : -ETIME;
484}
485 512
486static int smscore_load_firmware_family2(struct smscore_device_t *coredev, 513static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
487 void *buffer, size_t size) 514 void *buffer, size_t size)
488{ 515{
489 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; 516 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
490 struct SmsMsgHdr_ST *msg; 517 struct SmsMsgHdr_ST *msg;
491 u32 mem_address = firmware->StartAddress; 518 u32 mem_address;
492 u8 *payload = firmware->Payload; 519 u8 *payload = firmware->Payload;
493 int rc = 0; 520 int rc = 0;
521 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
522 firmware->Length = le32_to_cpu(firmware->Length);
523
524 mem_address = firmware->StartAddress;
494 525
495 sms_info("loading FW to addr 0x%x size %d", 526 sms_info("loading FW to addr 0x%x size %d",
496 mem_address, firmware->Length); 527 mem_address, firmware->Length);
@@ -657,6 +688,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
657 688
658 kmutex_lock(&g_smscore_deviceslock); 689 kmutex_lock(&g_smscore_deviceslock);
659 690
691 /* Release input device (IR) resources */
692 sms_ir_exit(coredev);
693
660 smscore_notify_clients(coredev); 694 smscore_notify_clients(coredev);
661 smscore_notify_callbacks(coredev, NULL, 0); 695 smscore_notify_callbacks(coredev, NULL, 0);
662 696
@@ -664,7 +698,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
664 * onresponse must no longer be called */ 698 * onresponse must no longer be called */
665 699
666 while (1) { 700 while (1) {
667 while ((cb = smscore_getbuffer(coredev))) { 701 while (!list_empty(&coredev->buffers)) {
702 cb = (struct smscore_buffer_t *) coredev->buffers.next;
703 list_del(&cb->entry);
668 kfree(cb); 704 kfree(cb);
669 num_buffers++; 705 num_buffers++;
670 } 706 }
@@ -685,8 +721,10 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
685 721
686 if (coredev->common_buffer) 722 if (coredev->common_buffer)
687 dma_free_coherent(NULL, coredev->common_buffer_size, 723 dma_free_coherent(NULL, coredev->common_buffer_size,
688 coredev->common_buffer, 724 coredev->common_buffer, coredev->common_buffer_phys);
689 coredev->common_buffer_phys); 725
726 if (coredev->fw_buf != NULL)
727 kfree(coredev->fw_buf);
690 728
691 list_del(&coredev->entry); 729 list_del(&coredev->entry);
692 kfree(coredev); 730 kfree(coredev);
@@ -746,7 +784,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
746 /*BDA*/ 784 /*BDA*/
747 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 785 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
748 /*ISDBT*/ 786 /*ISDBT*/
749 {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, 787 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
750 /*ISDBTBDA*/ 788 /*ISDBTBDA*/
751 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, 789 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
752 /*CMMB*/ 790 /*CMMB*/
@@ -870,7 +908,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
870 coredev->device_flags &= ~SMS_DEVICE_NOT_READY; 908 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
871 } 909 }
872 910
873 if (rc != 0) 911 if (rc < 0)
874 sms_err("return error code %d.", rc); 912 sms_err("return error code %d.", rc);
875 return rc; 913 return rc;
876} 914}
@@ -940,14 +978,11 @@ smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
940 * 978 *
941 */ 979 */
942void smscore_onresponse(struct smscore_device_t *coredev, 980void smscore_onresponse(struct smscore_device_t *coredev,
943 struct smscore_buffer_t *cb) 981 struct smscore_buffer_t *cb) {
944{ 982 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
945 struct SmsMsgHdr_ST *phdr = 983 + cb->offset);
946 (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); 984 struct smscore_client_t *client;
947 struct smscore_client_t *client =
948 smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
949 int rc = -EBUSY; 985 int rc = -EBUSY;
950
951 static unsigned long last_sample_time; /* = 0; */ 986 static unsigned long last_sample_time; /* = 0; */
952 static int data_total; /* = 0; */ 987 static int data_total; /* = 0; */
953 unsigned long time_now = jiffies_to_msecs(jiffies); 988 unsigned long time_now = jiffies_to_msecs(jiffies);
@@ -965,6 +1000,16 @@ void smscore_onresponse(struct smscore_device_t *coredev,
965 } 1000 }
966 1001
967 data_total += cb->size; 1002 data_total += cb->size;
1003 /* Do we need to re-route? */
1004 if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
1005 (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
1006 if (coredev->mode == DEVICE_MODE_DVBT_BDA)
1007 phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
1008 }
1009
1010
1011 client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
1012
968 /* If no client registered for type & id, 1013 /* If no client registered for type & id,
969 * check for control client where type is not registered */ 1014 * check for control client where type is not registered */
970 if (client) 1015 if (client)
@@ -1009,6 +1054,35 @@ void smscore_onresponse(struct smscore_device_t *coredev,
1009 case MSG_SMS_SLEEP_RESUME_COMP_IND: 1054 case MSG_SMS_SLEEP_RESUME_COMP_IND:
1010 complete(&coredev->resume_done); 1055 complete(&coredev->resume_done);
1011 break; 1056 break;
1057 case MSG_SMS_GPIO_CONFIG_EX_RES:
1058 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
1059 complete(&coredev->gpio_configuration_done);
1060 break;
1061 case MSG_SMS_GPIO_SET_LEVEL_RES:
1062 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
1063 complete(&coredev->gpio_set_level_done);
1064 break;
1065 case MSG_SMS_GPIO_GET_LEVEL_RES:
1066 {
1067 u32 *msgdata = (u32 *) phdr;
1068 coredev->gpio_get_res = msgdata[1];
1069 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
1070 coredev->gpio_get_res);
1071 complete(&coredev->gpio_get_level_done);
1072 break;
1073 }
1074 case MSG_SMS_START_IR_RES:
1075 complete(&coredev->ir_init_done);
1076 break;
1077 case MSG_SMS_IR_SAMPLES_IND:
1078 sms_ir_event(coredev,
1079 (const char *)
1080 ((char *)phdr
1081 + sizeof(struct SmsMsgHdr_ST)),
1082 (int)phdr->msgLength
1083 - sizeof(struct SmsMsgHdr_ST));
1084 break;
1085
1012 default: 1086 default:
1013 break; 1087 break;
1014 } 1088 }
@@ -1030,12 +1104,24 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1030 struct smscore_buffer_t *cb = NULL; 1104 struct smscore_buffer_t *cb = NULL;
1031 unsigned long flags; 1105 unsigned long flags;
1032 1106
1107 DEFINE_WAIT(wait);
1108
1033 spin_lock_irqsave(&coredev->bufferslock, flags); 1109 spin_lock_irqsave(&coredev->bufferslock, flags);
1034 1110
1035 if (!list_empty(&coredev->buffers)) { 1111 /* This function must return a valid buffer, since the buffer list is
1036 cb = (struct smscore_buffer_t *) coredev->buffers.next; 1112 * finite, we check that there is an available buffer, if not, we wait
1037 list_del(&cb->entry); 1113 * until such buffer become available.
1038 } 1114 */
1115
1116 prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
1117
1118 if (list_empty(&coredev->buffers))
1119 schedule();
1120
1121 finish_wait(&coredev->buffer_mng_waitq, &wait);
1122
1123 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1124 list_del(&cb->entry);
1039 1125
1040 spin_unlock_irqrestore(&coredev->bufferslock, flags); 1126 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1041 1127
@@ -1052,8 +1138,8 @@ EXPORT_SYMBOL_GPL(smscore_getbuffer);
1052 * 1138 *
1053 */ 1139 */
1054void smscore_putbuffer(struct smscore_device_t *coredev, 1140void smscore_putbuffer(struct smscore_device_t *coredev,
1055 struct smscore_buffer_t *cb) 1141 struct smscore_buffer_t *cb) {
1056{ 1142 wake_up_interruptible(&coredev->buffer_mng_waitq);
1057 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); 1143 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1058} 1144}
1059EXPORT_SYMBOL_GPL(smscore_putbuffer); 1145EXPORT_SYMBOL_GPL(smscore_putbuffer);
@@ -1210,8 +1296,9 @@ int smsclient_sendrequest(struct smscore_client_t *client,
1210EXPORT_SYMBOL_GPL(smsclient_sendrequest); 1296EXPORT_SYMBOL_GPL(smsclient_sendrequest);
1211 1297
1212 1298
1299/* old GPIO managments implementation */
1213int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, 1300int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
1214 struct smscore_gpio_config *pinconfig) 1301 struct smscore_config_gpio *pinconfig)
1215{ 1302{
1216 struct { 1303 struct {
1217 struct SmsMsgHdr_ST hdr; 1304 struct SmsMsgHdr_ST hdr;
@@ -1280,35 +1367,254 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
1280 &msg, sizeof(msg)); 1367 &msg, sizeof(msg));
1281} 1368}
1282 1369
1283static int __init smscore_module_init(void) 1370/* new GPIO managment implementation */
1284{ 1371static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1285 int rc = 0; 1372 u32 *pGroupNum, u32 *pGroupCfg) {
1373
1374 *pGroupCfg = 1;
1375
1376 if (PinNum >= 0 && PinNum <= 1) {
1377 *pTranslatedPinNum = 0;
1378 *pGroupNum = 9;
1379 *pGroupCfg = 2;
1380 } else if (PinNum >= 2 && PinNum <= 6) {
1381 *pTranslatedPinNum = 2;
1382 *pGroupNum = 0;
1383 *pGroupCfg = 2;
1384 } else if (PinNum >= 7 && PinNum <= 11) {
1385 *pTranslatedPinNum = 7;
1386 *pGroupNum = 1;
1387 } else if (PinNum >= 12 && PinNum <= 15) {
1388 *pTranslatedPinNum = 12;
1389 *pGroupNum = 2;
1390 *pGroupCfg = 3;
1391 } else if (PinNum == 16) {
1392 *pTranslatedPinNum = 16;
1393 *pGroupNum = 23;
1394 } else if (PinNum >= 17 && PinNum <= 24) {
1395 *pTranslatedPinNum = 17;
1396 *pGroupNum = 3;
1397 } else if (PinNum == 25) {
1398 *pTranslatedPinNum = 25;
1399 *pGroupNum = 6;
1400 } else if (PinNum >= 26 && PinNum <= 28) {
1401 *pTranslatedPinNum = 26;
1402 *pGroupNum = 4;
1403 } else if (PinNum == 29) {
1404 *pTranslatedPinNum = 29;
1405 *pGroupNum = 5;
1406 *pGroupCfg = 2;
1407 } else if (PinNum == 30) {
1408 *pTranslatedPinNum = 30;
1409 *pGroupNum = 8;
1410 } else if (PinNum == 31) {
1411 *pTranslatedPinNum = 31;
1412 *pGroupNum = 17;
1413 } else
1414 return -1;
1286 1415
1287 INIT_LIST_HEAD(&g_smscore_notifyees); 1416 *pGroupCfg <<= 24;
1288 INIT_LIST_HEAD(&g_smscore_devices);
1289 kmutex_init(&g_smscore_deviceslock);
1290 1417
1291 INIT_LIST_HEAD(&g_smscore_registry); 1418 return 0;
1292 kmutex_init(&g_smscore_registrylock); 1419}
1420
1421int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1422 struct smscore_gpio_config *pGpioConfig) {
1423
1424 u32 totalLen;
1425 u32 TranslatedPinNum;
1426 u32 GroupNum;
1427 u32 ElectricChar;
1428 u32 groupCfg;
1429 void *buffer;
1430 int rc;
1431
1432 struct SetGpioMsg {
1433 struct SmsMsgHdr_ST xMsgHeader;
1434 u32 msgData[6];
1435 } *pMsg;
1436
1437
1438 if (PinNum > MAX_GPIO_PIN_NUMBER)
1439 return -EINVAL;
1440
1441 if (pGpioConfig == NULL)
1442 return -EINVAL;
1443
1444 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
1445
1446 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1447 GFP_KERNEL | GFP_DMA);
1448 if (!buffer)
1449 return -ENOMEM;
1450
1451 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1452
1453 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1454 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1455 pMsg->xMsgHeader.msgFlags = 0;
1456 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1457 pMsg->msgData[0] = PinNum;
1458
1459 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1460 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1461 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1462 &groupCfg) != 0)
1463 return -EINVAL;
1464
1465 pMsg->msgData[1] = TranslatedPinNum;
1466 pMsg->msgData[2] = GroupNum;
1467 ElectricChar = (pGpioConfig->PullUpDown)
1468 | (pGpioConfig->InputCharacteristics << 2)
1469 | (pGpioConfig->OutputSlewRate << 3)
1470 | (pGpioConfig->OutputDriving << 4);
1471 pMsg->msgData[3] = ElectricChar;
1472 pMsg->msgData[4] = pGpioConfig->Direction;
1473 pMsg->msgData[5] = groupCfg;
1474 } else {
1475 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1476 pMsg->msgData[1] = pGpioConfig->PullUpDown;
1477 pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
1478 pMsg->msgData[3] = pGpioConfig->OutputDriving;
1479 pMsg->msgData[4] = pGpioConfig->Direction;
1480 pMsg->msgData[5] = 0;
1481 }
1482
1483 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1484 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1485 &coredev->gpio_configuration_done);
1486
1487 if (rc != 0) {
1488 if (rc == -ETIME)
1489 sms_err("smscore_gpio_configure timeout");
1490 else
1491 sms_err("smscore_gpio_configure error");
1492 }
1493 kfree(buffer);
1494
1495 return rc;
1496}
1497
1498int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
1499 u8 NewLevel) {
1500
1501 u32 totalLen;
1502 int rc;
1503 void *buffer;
1504
1505 struct SetGpioMsg {
1506 struct SmsMsgHdr_ST xMsgHeader;
1507 u32 msgData[3]; /* keep it 3 ! */
1508 } *pMsg;
1509
1510 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
1511 (PinNum > MAX_GPIO_PIN_NUMBER))
1512 return -EINVAL;
1293 1513
1514 totalLen = sizeof(struct SmsMsgHdr_ST) +
1515 (3 * sizeof(u32)); /* keep it 3 ! */
1294 1516
1517 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1518 GFP_KERNEL | GFP_DMA);
1519 if (!buffer)
1520 return -ENOMEM;
1295 1521
1522 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1296 1523
1524 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1525 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1526 pMsg->xMsgHeader.msgFlags = 0;
1527 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1528 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1529 pMsg->msgData[0] = PinNum;
1530 pMsg->msgData[1] = NewLevel;
1297 1531
1532 /* Send message to SMS */
1533 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1534 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1535 &coredev->gpio_set_level_done);
1536
1537 if (rc != 0) {
1538 if (rc == -ETIME)
1539 sms_err("smscore_gpio_set_level timeout");
1540 else
1541 sms_err("smscore_gpio_set_level error");
1542 }
1543 kfree(buffer);
1298 1544
1299 return rc; 1545 return rc;
1300 sms_debug("rc %d", rc); 1546}
1547
1548int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
1549 u8 *level) {
1550
1551 u32 totalLen;
1552 int rc;
1553 void *buffer;
1554
1555 struct SetGpioMsg {
1556 struct SmsMsgHdr_ST xMsgHeader;
1557 u32 msgData[2];
1558 } *pMsg;
1559
1560
1561 if (PinNum > MAX_GPIO_PIN_NUMBER)
1562 return -EINVAL;
1563
1564 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
1565
1566 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1567 GFP_KERNEL | GFP_DMA);
1568 if (!buffer)
1569 return -ENOMEM;
1570
1571 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1572
1573 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1574 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1575 pMsg->xMsgHeader.msgFlags = 0;
1576 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
1577 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1578 pMsg->msgData[0] = PinNum;
1579 pMsg->msgData[1] = 0;
1580
1581 /* Send message to SMS */
1582 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1583 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1584 &coredev->gpio_get_level_done);
1585
1586 if (rc != 0) {
1587 if (rc == -ETIME)
1588 sms_err("smscore_gpio_get_level timeout");
1589 else
1590 sms_err("smscore_gpio_get_level error");
1591 }
1592 kfree(buffer);
1593
1594 /* Its a race between other gpio_get_level() and the copy of the single
1595 * global 'coredev->gpio_get_res' to the function's variable 'level'
1596 */
1597 *level = coredev->gpio_get_res;
1301 1598
1302 return rc; 1599 return rc;
1303} 1600}
1304 1601
1305static void __exit smscore_module_exit(void) 1602static int __init smscore_module_init(void)
1306{ 1603{
1604 int rc = 0;
1307 1605
1606 INIT_LIST_HEAD(&g_smscore_notifyees);
1607 INIT_LIST_HEAD(&g_smscore_devices);
1608 kmutex_init(&g_smscore_deviceslock);
1308 1609
1610 INIT_LIST_HEAD(&g_smscore_registry);
1611 kmutex_init(&g_smscore_registrylock);
1309 1612
1613 return rc;
1614}
1310 1615
1311 1616static void __exit smscore_module_exit(void)
1617{
1312 kmutex_lock(&g_smscore_deviceslock); 1618 kmutex_lock(&g_smscore_deviceslock);
1313 while (!list_empty(&g_smscore_notifyees)) { 1619 while (!list_empty(&g_smscore_notifyees)) {
1314 struct smscore_device_notifyee_t *notifyee = 1620 struct smscore_device_notifyee_t *notifyee =
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index 548de9056e8b..f1108c64e895 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -1,26 +1,26 @@
1/* 1/****************************************************************
2 * Driver for the Siano SMS1xxx USB dongle 2
3 * 3Siano Mobile Silicon, Inc.
4 * author: Anatoly Greenblat 4MDTV receiver kernel modules.
5 * 5Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 6
7 * 7This program is free software: you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License version 2 as 9the Free Software Foundation, either version 2 of the License, or
10 * published by the Free Software Foundation; 10(at your option) any later version.
11 * 11
12 * Software distributed under the License is distributed on an "AS IS" 12 This program is distributed in the hope that it will be useful,
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 13but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * See the GNU General Public License for more details. 15GNU General Public License for more details.
16 * 16
17 * You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19
20 */ 20****************************************************************/
21 21
22#ifndef __smscoreapi_h__ 22#ifndef __SMS_CORE_API_H__
23#define __smscoreapi_h__ 23#define __SMS_CORE_API_H__
24 24
25#include <linux/version.h> 25#include <linux/version.h>
26#include <linux/device.h> 26#include <linux/device.h>
@@ -28,14 +28,13 @@
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/scatterlist.h> 29#include <linux/scatterlist.h>
30#include <linux/types.h> 30#include <linux/types.h>
31#include <asm/page.h>
32#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/wait.h>
33#include <linux/timer.h>
33 34
34#include "dmxdev.h" 35#include <asm/page.h>
35#include "dvbdev.h"
36#include "dvb_demux.h"
37#include "dvb_frontend.h"
38 36
37#include "smsir.h"
39 38
40#define kmutex_init(_p_) mutex_init(_p_) 39#define kmutex_init(_p_) mutex_init(_p_)
41#define kmutex_lock(_p_) mutex_lock(_p_) 40#define kmutex_lock(_p_) mutex_lock(_p_)
@@ -46,13 +45,14 @@
46#define min(a, b) (((a) < (b)) ? (a) : (b)) 45#define min(a, b) (((a) < (b)) ? (a) : (b))
47#endif 46#endif
48 47
49#define SMS_ALLOC_ALIGNMENT 128 48#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000)
50#define SMS_DMA_ALIGNMENT 16 49#define SMS_ALLOC_ALIGNMENT 128
50#define SMS_DMA_ALIGNMENT 16
51#define SMS_ALIGN_ADDRESS(addr) \ 51#define SMS_ALIGN_ADDRESS(addr) \
52 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) 52 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
53 53
54#define SMS_DEVICE_FAMILY2 1 54#define SMS_DEVICE_FAMILY2 1
55#define SMS_ROM_NO_RESPONSE 2 55#define SMS_ROM_NO_RESPONSE 2
56#define SMS_DEVICE_NOT_READY 0x8000000 56#define SMS_DEVICE_NOT_READY 0x8000000
57 57
58enum sms_device_type_st { 58enum sms_device_type_st {
@@ -83,13 +83,13 @@ typedef void (*onremove_t)(void *context);
83struct smscore_buffer_t { 83struct smscore_buffer_t {
84 /* public members, once passed to clients can be changed freely */ 84 /* public members, once passed to clients can be changed freely */
85 struct list_head entry; 85 struct list_head entry;
86 int size; 86 int size;
87 int offset; 87 int offset;
88 88
89 /* private members, read-only for clients */ 89 /* private members, read-only for clients */
90 void *p; 90 void *p;
91 dma_addr_t phys; 91 dma_addr_t phys;
92 unsigned long offset_in_common; 92 unsigned long offset_in_common;
93}; 93};
94 94
95struct smsdevice_params_t { 95struct smsdevice_params_t {
@@ -116,10 +116,63 @@ struct smsclient_params_t {
116 int data_type; 116 int data_type;
117 onresponse_t onresponse_handler; 117 onresponse_t onresponse_handler;
118 onremove_t onremove_handler; 118 onremove_t onremove_handler;
119
120 void *context; 119 void *context;
121}; 120};
122 121
122struct smscore_device_t {
123 struct list_head entry;
124
125 struct list_head clients;
126 struct list_head subclients;
127 spinlock_t clientslock;
128
129 struct list_head buffers;
130 spinlock_t bufferslock;
131 int num_buffers;
132
133 void *common_buffer;
134 int common_buffer_size;
135 dma_addr_t common_buffer_phys;
136
137 void *context;
138 struct device *device;
139
140 char devpath[32];
141 unsigned long device_flags;
142
143 setmode_t setmode_handler;
144 detectmode_t detectmode_handler;
145 sendrequest_t sendrequest_handler;
146 preload_t preload_handler;
147 postload_t postload_handler;
148
149 int mode, modes_supported;
150
151 /* host <--> device messages */
152 struct completion version_ex_done, data_download_done, trigger_done;
153 struct completion init_device_done, reload_start_done, resume_done;
154 struct completion gpio_configuration_done, gpio_set_level_done;
155 struct completion gpio_get_level_done, ir_init_done;
156
157 /* Buffer management */
158 wait_queue_head_t buffer_mng_waitq;
159
160 /* GPIO */
161 int gpio_get_res;
162
163 /* Target hardware board */
164 int board_id;
165
166 /* Firmware */
167 u8 *fw_buf;
168 u32 fw_buf_size;
169
170 /* Infrared (IR) */
171 struct ir_t ir;
172
173 int led_state;
174};
175
123/* GPIO definitions for antenna frequency domain control (SMS8021) */ 176/* GPIO definitions for antenna frequency domain control (SMS8021) */
124#define SMS_ANTENNA_GPIO_0 1 177#define SMS_ANTENNA_GPIO_0 1
125#define SMS_ANTENNA_GPIO_1 0 178#define SMS_ANTENNA_GPIO_1 0
@@ -154,18 +207,15 @@ struct smsclient_params_t {
154#define MSG_SMS_INIT_DEVICE_RES 579 207#define MSG_SMS_INIT_DEVICE_RES 579
155#define MSG_SMS_ADD_PID_FILTER_REQ 601 208#define MSG_SMS_ADD_PID_FILTER_REQ 601
156#define MSG_SMS_ADD_PID_FILTER_RES 602 209#define MSG_SMS_ADD_PID_FILTER_RES 602
157#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 210#define MSG_SMS_REMOVE_PID_FILTER_REQ 603
158#define MSG_SMS_REMOVE_PID_FILTER_RES 604 211#define MSG_SMS_REMOVE_PID_FILTER_RES 604
159#define MSG_SMS_DAB_CHANNEL 607 212#define MSG_SMS_DAB_CHANNEL 607
160#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 213#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
161#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 214#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
162#define MSG_SMS_GET_STATISTICS_REQ 615 215#define MSG_SMS_HO_PER_SLICES_IND 630
163#define MSG_SMS_GET_STATISTICS_RES 616 216#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
164#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 217#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
165#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 218#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
166#define MSG_SMS_GET_STATISTICS_EX_REQ 653
167#define MSG_SMS_GET_STATISTICS_EX_RES 654
168#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
169#define MSG_SMS_DATA_DOWNLOAD_REQ 660 219#define MSG_SMS_DATA_DOWNLOAD_REQ 660
170#define MSG_SMS_DATA_DOWNLOAD_RES 661 220#define MSG_SMS_DATA_DOWNLOAD_RES 661
171#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 221#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
@@ -190,14 +240,31 @@ struct smsclient_params_t {
190#define MSG_SMS_GPIO_CONFIG_EX_RES 713 240#define MSG_SMS_GPIO_CONFIG_EX_RES 713
191#define MSG_SMS_ISDBT_TUNE_REQ 776 241#define MSG_SMS_ISDBT_TUNE_REQ 776
192#define MSG_SMS_ISDBT_TUNE_RES 777 242#define MSG_SMS_ISDBT_TUNE_RES 777
243#define MSG_SMS_TRANSMISSION_IND 782
244#define MSG_SMS_START_IR_REQ 800
245#define MSG_SMS_START_IR_RES 801
246#define MSG_SMS_IR_SAMPLES_IND 802
247#define MSG_SMS_SIGNAL_DETECTED_IND 827
248#define MSG_SMS_NO_SIGNAL_IND 828
193 249
194#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ 250#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
195 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ 251 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
196 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ 252 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
197} while (0) 253} while (0)
254
198#define SMS_INIT_MSG(ptr, type, len) \ 255#define SMS_INIT_MSG(ptr, type, len) \
199 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) 256 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
200 257
258enum SMS_DVB3_EVENTS {
259 DVB3_EVENT_INIT = 0,
260 DVB3_EVENT_SLEEP,
261 DVB3_EVENT_HOTPLUG,
262 DVB3_EVENT_FE_LOCK,
263 DVB3_EVENT_FE_UNLOCK,
264 DVB3_EVENT_UNC_OK,
265 DVB3_EVENT_UNC_ERR
266};
267
201enum SMS_DEVICE_MODE { 268enum SMS_DEVICE_MODE {
202 DEVICE_MODE_NONE = -1, 269 DEVICE_MODE_NONE = -1,
203 DEVICE_MODE_DVBT = 0, 270 DEVICE_MODE_DVBT = 0,
@@ -221,8 +288,13 @@ struct SmsMsgHdr_ST {
221}; 288};
222 289
223struct SmsMsgData_ST { 290struct SmsMsgData_ST {
224 struct SmsMsgHdr_ST xMsgHeader; 291 struct SmsMsgHdr_ST xMsgHeader;
225 u32 msgData[1]; 292 u32 msgData[1];
293};
294
295struct SmsMsgData_ST2 {
296 struct SmsMsgHdr_ST xMsgHeader;
297 u32 msgData[2];
226}; 298};
227 299
228struct SmsDataDownload_ST { 300struct SmsDataDownload_ST {
@@ -238,11 +310,12 @@ struct SmsVersionRes_ST {
238 u8 Step; /* 0 - Step A */ 310 u8 Step; /* 0 - Step A */
239 u8 MetalFix; /* 0 - Metal 0 */ 311 u8 MetalFix; /* 0 - Metal 0 */
240 312
241 u8 FirmwareId; /* 0xFF � ROM, otherwise the 313 /* FirmwareId 0xFF if ROM, otherwise the
242 * value indicated by 314 * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
243 * SMSHOSTLIB_DEVICE_MODES_E */ 315 u8 FirmwareId;
244 u8 SupportedProtocols; /* Bitwise OR combination of 316 /* SupportedProtocols Bitwise OR combination of
245 * supported protocols */ 317 * supported protocols */
318 u8 SupportedProtocols;
246 319
247 u8 VersionMajor; 320 u8 VersionMajor;
248 u8 VersionMinor; 321 u8 VersionMinor;
@@ -264,86 +337,219 @@ struct SmsFirmware_ST {
264 u8 Payload[1]; 337 u8 Payload[1];
265}; 338};
266 339
267struct SMSHOSTLIB_STATISTICS_ST { 340/* Statistics information returned as response for
268 u32 Reserved; /* Reserved */ 341 * SmsHostApiGetStatistics_Req */
342struct SMSHOSTLIB_STATISTICS_S {
343 u32 Reserved; /* Reserved */
269 344
270 /* Common parameters */ 345 /* Common parameters */
271 u32 IsRfLocked; /* 0 - not locked, 1 - locked */ 346 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
272 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ 347 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
273 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ 348 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
274 349
275 /* Reception quality */ 350 /* Reception quality */
276 s32 SNR; /* dB */ 351 s32 SNR; /* dB */
277 u32 BER; /* Post Viterbi BER [1E-5] */ 352 u32 BER; /* Post Viterbi BER [1E-5] */
278 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ 353 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
279 u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, 354 u32 TS_PER; /* Transport stream PER,
280 * valid only for DVB-T/H */ 355 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
281 u32 MFER; /* DVB-H frame error rate in percentage, 356 u32 MFER; /* DVB-H frame error rate in percentage,
282 * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ 357 0xFFFFFFFF indicate N/A, valid only for DVB-H */
283 s32 RSSI; /* dBm */ 358 s32 RSSI; /* dBm */
284 s32 InBandPwr; /* In band power in dBM */ 359 s32 InBandPwr; /* In band power in dBM */
285 s32 CarrierOffset; /* Carrier Offset in bin/1024 */ 360 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
286 361
287 /* Transmission parameters, valid only for DVB-T/H */ 362 /* Transmission parameters */
288 u32 Frequency; /* Frequency in Hz */ 363 u32 Frequency; /* Frequency in Hz */
289 u32 Bandwidth; /* Bandwidth in MHz */ 364 u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */
290 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, 365 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
291 * for DVB-T/H FFT mode carriers in Kilos */ 366 for DVB-T/H FFT mode carriers in Kilos */
292 u32 ModemState; /* from SMS_DvbModemState_ET */ 367 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
293 u32 GuardInterval; /* Guard Interval, 1 divided by value */ 368 valid only for DVB-T/H */
294 u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */ 369 u32 GuardInterval; /* Guard Interval from
295 u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */ 370 SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */
296 u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */ 371 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
297 u32 Constellation; /* Constellation from SMS_Constellation_ET */ 372 valid only for DVB-T/H */
373 u32 LPCodeRate; /* Low Priority Code Rate from
374 SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
375 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
376 valid only for DVB-T/H */
377 u32 Constellation; /* Constellation from
378 SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
298 379
299 /* Burst parameters, valid only for DVB-H */ 380 /* Burst parameters, valid only for DVB-H */
300 u32 BurstSize; /* Current burst size in bytes */ 381 u32 BurstSize; /* Current burst size in bytes,
301 u32 BurstDuration; /* Current burst duration in mSec */ 382 valid only for DVB-H */
302 u32 BurstCycleTime; /* Current burst cycle time in mSec */ 383 u32 BurstDuration; /* Current burst duration in mSec,
303 u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, 384 valid only for DVB-H */
304 * as calculated by demodulator */ 385 u32 BurstCycleTime; /* Current burst cycle time in mSec,
305 u32 NumOfRows; /* Number of rows in MPE table */ 386 valid only for DVB-H */
306 u32 NumOfPaddCols; /* Number of padding columns in MPE table */ 387 u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
307 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ 388 as calculated by demodulator, valid only for DVB-H */
308 /* Burst parameters */ 389 u32 NumOfRows; /* Number of rows in MPE table,
309 u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ 390 valid only for DVB-H */
310 u32 TotalTSPackets; /* Total number of transport-stream packets */ 391 u32 NumOfPaddCols; /* Number of padding columns in MPE table,
311 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include 392 valid only for DVB-H */
312 * errors after MPE RS decoding */ 393 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table,
313 u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors 394 valid only for DVB-H */
314 * after MPE RS decoding */ 395 u32 ErrorTSPackets; /* Number of erroneous
315 u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected 396 transport-stream packets */
316 * by MPE RS decoding */ 397 u32 TotalTSPackets; /* Total number of transport-stream packets */
317 398 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
399 errors after MPE RS decoding */
400 u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
401 after MPE RS decoding */
402 u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
403 corrected by MPE RS decoding */
318 /* Common params */ 404 /* Common params */
319 u32 BERErrorCount; /* Number of errornous SYNC bits. */ 405 u32 BERErrorCount; /* Number of errornous SYNC bits. */
320 u32 BERBitCount; /* Total number of SYNC bits. */ 406 u32 BERBitCount; /* Total number of SYNC bits. */
321 407
322 /* Interface information */ 408 /* Interface information */
323 u32 SmsToHostTxErrors; /* Total number of transmission errors. */ 409 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
324 410
325 /* DAB/T-DMB */ 411 /* DAB/T-DMB */
326 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ 412 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
327 413
328 /* DVB-H TPS parameters */ 414 /* DVB-H TPS parameters */
329 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; 415 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
330 * if set to 0xFFFFFFFF cell_id not yet recovered */ 416 if set to 0xFFFFFFFF cell_id not yet recovered */
417 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
418 Time Slicing indicator, bit 0 - MPE-FEC indicator */
419 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
420 Time Slicing indicator, bit 0 - MPE-FEC indicator */
331 421
422 u32 NumMPEReceived; /* DVB-H, Num MPE section received */
423
424 u32 ReservedFields[10]; /* Reserved */
332}; 425};
333 426
334struct SmsMsgStatisticsInfo_ST { 427struct PID_STATISTICS_DATA_S {
335 u32 RequestResult; 428 struct PID_BURST_S {
429 u32 size;
430 u32 padding_cols;
431 u32 punct_cols;
432 u32 duration;
433 u32 cycle;
434 u32 calc_cycle;
435 } burst;
436
437 u32 tot_tbl_cnt;
438 u32 invalid_tbl_cnt;
439 u32 tot_cor_tbl;
440};
336 441
337 struct SMSHOSTLIB_STATISTICS_ST Stat; 442struct PID_DATA_S {
443 u32 pid;
444 u32 num_rows;
445 struct PID_STATISTICS_DATA_S pid_statistics;
446};
338 447
339 /* Split the calc of the SNR in DAB */ 448#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
340 u32 Signal; /* dB */ 449#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
341 u32 Noise; /* dB */ 450#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
451 if (_stat.TransmissionMode == 0) \
452 _stat.TransmissionMode = 2; \
453 else if (_stat.TransmissionMode == 1) \
454 _stat.TransmissionMode = 8; \
455 else \
456 _stat.TransmissionMode = 4;
457
458struct TRANSMISSION_STATISTICS_S {
459 u32 Frequency; /* Frequency in Hz */
460 u32 Bandwidth; /* Bandwidth in MHz */
461 u32 TransmissionMode; /* FFT mode carriers in Kilos */
462 u32 GuardInterval; /* Guard Interval from
463 SMSHOSTLIB_GUARD_INTERVALS_ET */
464 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
465 u32 LPCodeRate; /* Low Priority Code Rate from
466 SMSHOSTLIB_CODE_RATE_ET */
467 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
468 u32 Constellation; /* Constellation from
469 SMSHOSTLIB_CONSTELLATION_ET */
342 470
471 /* DVB-H TPS parameters */
472 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
473 if set to 0xFFFFFFFF cell_id not yet recovered */
474 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
475 Time Slicing indicator, bit 0 - MPE-FEC indicator */
476 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
477 Time Slicing indicator, bit 0 - MPE-FEC indicator */
478 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
343}; 479};
344 480
481struct RECEPTION_STATISTICS_S {
482 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
483 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
484 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
485
486 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
487 s32 SNR; /* dB */
488 u32 BER; /* Post Viterbi BER [1E-5] */
489 u32 BERErrorCount; /* Number of erronous SYNC bits. */
490 u32 BERBitCount; /* Total number of SYNC bits. */
491 u32 TS_PER; /* Transport stream PER,
492 0xFFFFFFFF indicate N/A */
493 u32 MFER; /* DVB-H frame error rate in percentage,
494 0xFFFFFFFF indicate N/A, valid only for DVB-H */
495 s32 RSSI; /* dBm */
496 s32 InBandPwr; /* In band power in dBM */
497 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
498 u32 ErrorTSPackets; /* Number of erroneous
499 transport-stream packets */
500 u32 TotalTSPackets; /* Total number of transport-stream packets */
501
502 s32 MRC_SNR; /* dB */
503 s32 MRC_RSSI; /* dBm */
504 s32 MRC_InBandPwr; /* In band power in dBM */
505};
345 506
346struct smscore_gpio_config { 507
508/* Statistics information returned as response for
509 * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
510struct SMSHOSTLIB_STATISTICS_DVB_S {
511 /* Reception */
512 struct RECEPTION_STATISTICS_S ReceptionData;
513
514 /* Transmission parameters */
515 struct TRANSMISSION_STATISTICS_S TransmissionData;
516
517 /* Burst parameters, valid only for DVB-H */
518#define SRVM_MAX_PID_FILTERS 8
519 struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
520};
521
522struct SRVM_SIGNAL_STATUS_S {
523 u32 result;
524 u32 snr;
525 u32 tsPackets;
526 u32 etsPackets;
527 u32 constellation;
528 u32 hpCode;
529 u32 tpsSrvIndLP;
530 u32 tpsSrvIndHP;
531 u32 cellId;
532 u32 reason;
533
534 s32 inBandPower;
535 u32 requestId;
536};
537
538struct SMSHOSTLIB_I2C_REQ_ST {
539 u32 DeviceAddress; /* I2c device address */
540 u32 WriteCount; /* number of bytes to write */
541 u32 ReadCount; /* number of bytes to read */
542 u8 Data[1];
543};
544
545struct SMSHOSTLIB_I2C_RES_ST {
546 u32 Status; /* non-zero value in case of failure */
547 u32 ReadCount; /* number of bytes read */
548 u8 Data[1];
549};
550
551
552struct smscore_config_gpio {
347#define SMS_GPIO_DIRECTION_INPUT 0 553#define SMS_GPIO_DIRECTION_INPUT 0
348#define SMS_GPIO_DIRECTION_OUTPUT 1 554#define SMS_GPIO_DIRECTION_OUTPUT 1
349 u8 direction; 555 u8 direction;
@@ -369,6 +575,47 @@ struct smscore_gpio_config {
369 u8 outputdriving; 575 u8 outputdriving;
370}; 576};
371 577
578struct smscore_gpio_config {
579#define SMS_GPIO_DIRECTION_INPUT 0
580#define SMS_GPIO_DIRECTION_OUTPUT 1
581 u8 Direction;
582
583#define SMS_GPIO_PULL_UP_DOWN_NONE 0
584#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
585#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2
586#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3
587 u8 PullUpDown;
588
589#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0
590#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
591 u8 InputCharacteristics;
592
593#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */
594#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */
595
596
597#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */
598#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */
599#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */
600#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */
601 u8 OutputSlewRate;
602
603#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */
604#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */
605#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */
606#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */
607
608#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */
609#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */
610#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */
611#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */
612#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */
613#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */
614#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */
615#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */
616 u8 OutputDriving;
617};
618
372extern void smscore_registry_setmode(char *devpath, int mode); 619extern void smscore_registry_setmode(char *devpath, int mode);
373extern int smscore_registry_getmode(char *devpath); 620extern int smscore_registry_getmode(char *devpath);
374 621
@@ -410,10 +657,19 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
410extern void smscore_putbuffer(struct smscore_device_t *coredev, 657extern void smscore_putbuffer(struct smscore_device_t *coredev,
411 struct smscore_buffer_t *cb); 658 struct smscore_buffer_t *cb);
412 659
660/* old GPIO managment */
413int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, 661int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
414 struct smscore_gpio_config *pinconfig); 662 struct smscore_config_gpio *pinconfig);
415int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); 663int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
416 664
665/* new GPIO managment */
666extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
667 struct smscore_gpio_config *pGpioConfig);
668extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
669 u8 NewLevel);
670extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
671 u8 *level);
672
417void smscore_set_board_id(struct smscore_device_t *core, int id); 673void smscore_set_board_id(struct smscore_device_t *core, int id);
418int smscore_get_board_id(struct smscore_device_t *core); 674int smscore_get_board_id(struct smscore_device_t *core);
419 675
@@ -442,4 +698,4 @@ int smscore_led_state(struct smscore_device_t *core, int led);
442 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) 698 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
443 699
444 700
445#endif /* __smscoreapi_h__ */ 701#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index ba080b95befb..3ee1c3902c56 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -1,28 +1,34 @@
1/* 1/****************************************************************
2 * Driver for the Siano SMS1xxx USB dongle 2
3 * 3Siano Mobile Silicon, Inc.
4 * Author: Uri Shkolni 4MDTV receiver kernel modules.
5 * 5Copyright (C) 2006-2008, Uri Shkolnik
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 6
7 * 7This program is free software: you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License version 2 as 9the Free Software Foundation, either version 2 of the License, or
10 * published by the Free Software Foundation; 10(at your option) any later version.
11 * 11
12 * Software distributed under the License is distributed on an "AS IS" 12 This program is distributed in the hope that it will be useful,
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 13but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * See the GNU General Public License for more details. 15GNU General Public License for more details.
16 * 16
17 * You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19
20 */ 20****************************************************************/
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/init.h> 23#include <linux/init.h>
24 24
25#include "dmxdev.h"
26#include "dvbdev.h"
27#include "dvb_demux.h"
28#include "dvb_frontend.h"
29
25#include "smscoreapi.h" 30#include "smscoreapi.h"
31#include "smsendian.h"
26#include "sms-cards.h" 32#include "sms-cards.h"
27 33
28DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 34DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -39,12 +45,15 @@ struct smsdvb_client_t {
39 struct dvb_frontend frontend; 45 struct dvb_frontend frontend;
40 46
41 fe_status_t fe_status; 47 fe_status_t fe_status;
42 int fe_ber, fe_snr, fe_unc, fe_signal_strength;
43 48
44 struct completion tune_done, stat_done; 49 struct completion tune_done;
45 50
46 /* todo: save freq/band instead whole struct */ 51 /* todo: save freq/band instead whole struct */
47 struct dvb_frontend_parameters fe_params; 52 struct dvb_frontend_parameters fe_params;
53
54 struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
55 int event_fe_state;
56 int event_unc_state;
48}; 57};
49 58
50static struct list_head g_smsdvb_clients; 59static struct list_head g_smsdvb_clients;
@@ -54,11 +63,69 @@ static int sms_dbg;
54module_param_named(debug, sms_dbg, int, 0644); 63module_param_named(debug, sms_dbg, int, 0644);
55MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); 64MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
56 65
66/* Events that may come from DVB v3 adapter */
67static void sms_board_dvb3_event(struct smsdvb_client_t *client,
68 enum SMS_DVB3_EVENTS event) {
69
70 struct smscore_device_t *coredev = client->coredev;
71 switch (event) {
72 case DVB3_EVENT_INIT:
73 sms_debug("DVB3_EVENT_INIT");
74 sms_board_event(coredev, BOARD_EVENT_BIND);
75 break;
76 case DVB3_EVENT_SLEEP:
77 sms_debug("DVB3_EVENT_SLEEP");
78 sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
79 break;
80 case DVB3_EVENT_HOTPLUG:
81 sms_debug("DVB3_EVENT_HOTPLUG");
82 sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
83 break;
84 case DVB3_EVENT_FE_LOCK:
85 if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
86 client->event_fe_state = DVB3_EVENT_FE_LOCK;
87 sms_debug("DVB3_EVENT_FE_LOCK");
88 sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
89 }
90 break;
91 case DVB3_EVENT_FE_UNLOCK:
92 if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
93 client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
94 sms_debug("DVB3_EVENT_FE_UNLOCK");
95 sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
96 }
97 break;
98 case DVB3_EVENT_UNC_OK:
99 if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
100 client->event_unc_state = DVB3_EVENT_UNC_OK;
101 sms_debug("DVB3_EVENT_UNC_OK");
102 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
103 }
104 break;
105 case DVB3_EVENT_UNC_ERR:
106 if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
107 client->event_unc_state = DVB3_EVENT_UNC_ERR;
108 sms_debug("DVB3_EVENT_UNC_ERR");
109 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
110 }
111 break;
112
113 default:
114 sms_err("Unknown dvb3 api event");
115 break;
116 }
117}
118
57static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) 119static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
58{ 120{
59 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; 121 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
60 struct SmsMsgHdr_ST *phdr = 122 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
61 (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); 123 + cb->offset);
124 u32 *pMsgData = (u32 *) phdr + 1;
125 /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
126 bool is_status_update = false;
127
128 smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
62 129
63 switch (phdr->msgType) { 130 switch (phdr->msgType) {
64 case MSG_SMS_DVBT_BDA_DATA: 131 case MSG_SMS_DVBT_BDA_DATA:
@@ -70,43 +137,110 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
70 complete(&client->tune_done); 137 complete(&client->tune_done);
71 break; 138 break;
72 139
73 case MSG_SMS_GET_STATISTICS_RES: 140 case MSG_SMS_SIGNAL_DETECTED_IND:
74 { 141 sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
75 struct SmsMsgStatisticsInfo_ST *p = 142 client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
76 (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); 143 is_status_update = true;
77 144 break;
78 if (p->Stat.IsDemodLocked) { 145
79 client->fe_status = FE_HAS_SIGNAL | 146 case MSG_SMS_NO_SIGNAL_IND:
80 FE_HAS_CARRIER | 147 sms_info("MSG_SMS_NO_SIGNAL_IND");
81 FE_HAS_VITERBI | 148 client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
82 FE_HAS_SYNC | 149 is_status_update = true;
83 FE_HAS_LOCK; 150 break;
84 151
85 client->fe_snr = p->Stat.SNR; 152 case MSG_SMS_TRANSMISSION_IND: {
86 client->fe_ber = p->Stat.BER; 153 sms_info("MSG_SMS_TRANSMISSION_IND");
87 client->fe_unc = p->Stat.BERErrorCount; 154
88 155 pMsgData++;
89 if (p->Stat.InBandPwr < -95) 156 memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
90 client->fe_signal_strength = 0; 157 sizeof(struct TRANSMISSION_STATISTICS_S));
91 else if (p->Stat.InBandPwr > -29) 158
92 client->fe_signal_strength = 100; 159 /* Mo need to correct guard interval
93 else 160 * (as opposed to old statistics message).
94 client->fe_signal_strength = 161 */
95 (p->Stat.InBandPwr + 95) * 3 / 2; 162 CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
163 CORRECT_STAT_TRANSMISSON_MODE(
164 client->sms_stat_dvb.TransmissionData);
165 is_status_update = true;
166 break;
167 }
168 case MSG_SMS_HO_PER_SLICES_IND: {
169 struct RECEPTION_STATISTICS_S *pReceptionData =
170 &client->sms_stat_dvb.ReceptionData;
171 struct SRVM_SIGNAL_STATUS_S SignalStatusData;
172
173 /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
174 pMsgData++;
175 SignalStatusData.result = pMsgData[0];
176 SignalStatusData.snr = pMsgData[1];
177 SignalStatusData.inBandPower = (s32) pMsgData[2];
178 SignalStatusData.tsPackets = pMsgData[3];
179 SignalStatusData.etsPackets = pMsgData[4];
180 SignalStatusData.constellation = pMsgData[5];
181 SignalStatusData.hpCode = pMsgData[6];
182 SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
183 SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
184 SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
185 SignalStatusData.reason = pMsgData[10];
186 SignalStatusData.requestId = pMsgData[11];
187 pReceptionData->IsRfLocked = pMsgData[16];
188 pReceptionData->IsDemodLocked = pMsgData[17];
189 pReceptionData->ModemState = pMsgData[12];
190 pReceptionData->SNR = pMsgData[1];
191 pReceptionData->BER = pMsgData[13];
192 pReceptionData->RSSI = pMsgData[14];
193 CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
194
195 pReceptionData->InBandPwr = (s32) pMsgData[2];
196 pReceptionData->CarrierOffset = (s32) pMsgData[15];
197 pReceptionData->TotalTSPackets = pMsgData[3];
198 pReceptionData->ErrorTSPackets = pMsgData[4];
199
200 /* TS PER */
201 if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
202 > 0) {
203 pReceptionData->TS_PER = (SignalStatusData.etsPackets
204 * 100) / (SignalStatusData.tsPackets
205 + SignalStatusData.etsPackets);
96 } else { 206 } else {
97 client->fe_status = 0; 207 pReceptionData->TS_PER = 0;
98 client->fe_snr =
99 client->fe_ber =
100 client->fe_unc =
101 client->fe_signal_strength = 0;
102 } 208 }
103 209
104 complete(&client->stat_done); 210 pReceptionData->BERBitCount = pMsgData[18];
105 break; 211 pReceptionData->BERErrorCount = pMsgData[19];
106 } }
107 212
213 pReceptionData->MRC_SNR = pMsgData[20];
214 pReceptionData->MRC_InBandPwr = pMsgData[21];
215 pReceptionData->MRC_RSSI = pMsgData[22];
216
217 is_status_update = true;
218 break;
219 }
220 }
108 smscore_putbuffer(client->coredev, cb); 221 smscore_putbuffer(client->coredev, cb);
109 222
223 if (is_status_update) {
224 if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
225 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
226 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
227 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
228 if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
229 == 0)
230 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
231 else
232 sms_board_dvb3_event(client,
233 DVB3_EVENT_UNC_ERR);
234
235 } else {
236 /*client->fe_status =
237 (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ?
238 0 : FE_HAS_SIGNAL;*/
239 client->fe_status = 0;
240 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
241 }
242 }
243
110 return 0; 244 return 0;
111} 245}
112 246
@@ -149,6 +283,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed)
149 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); 283 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
150 PidMsg.msgData[0] = feed->pid; 284 PidMsg.msgData[0] = feed->pid;
151 285
286 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
152 return smsclient_sendrequest(client->smsclient, 287 return smsclient_sendrequest(client->smsclient,
153 &PidMsg, sizeof(PidMsg)); 288 &PidMsg, sizeof(PidMsg));
154} 289}
@@ -169,6 +304,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
169 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); 304 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
170 PidMsg.msgData[0] = feed->pid; 305 PidMsg.msgData[0] = feed->pid;
171 306
307 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
172 return smsclient_sendrequest(client->smsclient, 308 return smsclient_sendrequest(client->smsclient,
173 &PidMsg, sizeof(PidMsg)); 309 &PidMsg, sizeof(PidMsg));
174} 310}
@@ -177,7 +313,10 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
177 void *buffer, size_t size, 313 void *buffer, size_t size,
178 struct completion *completion) 314 struct completion *completion)
179{ 315{
180 int rc = smsclient_sendrequest(client->smsclient, buffer, size); 316 int rc;
317
318 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
319 rc = smsclient_sendrequest(client->smsclient, buffer, size);
181 if (rc < 0) 320 if (rc < 0)
182 return rc; 321 return rc;
183 322
@@ -186,83 +325,61 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
186 0 : -ETIME; 325 0 : -ETIME;
187} 326}
188 327
189static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
190{
191 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
192 DVBT_BDA_CONTROL_MSG_ID,
193 HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 };
194 int ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
195 &client->stat_done);
196 if (ret < 0)
197 return ret;
198
199 if (client->fe_status & FE_HAS_LOCK)
200 sms_board_led_feedback(client->coredev,
201 (client->fe_unc == 0) ?
202 SMS_LED_HI : SMS_LED_LO);
203 else
204 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
205 return ret;
206}
207
208static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) 328static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
209{ 329{
210 struct smsdvb_client_t *client = 330 struct smsdvb_client_t *client;
211 container_of(fe, struct smsdvb_client_t, frontend); 331 client = container_of(fe, struct smsdvb_client_t, frontend);
212 int rc = smsdvb_send_statistics_request(client);
213 332
214 if (!rc) 333 *stat = client->fe_status;
215 *stat = client->fe_status;
216 334
217 return rc; 335 return 0;
218} 336}
219 337
220static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) 338static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
221{ 339{
222 struct smsdvb_client_t *client = 340 struct smsdvb_client_t *client;
223 container_of(fe, struct smsdvb_client_t, frontend); 341 client = container_of(fe, struct smsdvb_client_t, frontend);
224 int rc = smsdvb_send_statistics_request(client);
225 342
226 if (!rc) 343 *ber = client->sms_stat_dvb.ReceptionData.BER;
227 *ber = client->fe_ber;
228 344
229 return rc; 345 return 0;
230} 346}
231 347
232static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 348static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
233{ 349{
234 struct smsdvb_client_t *client = 350 struct smsdvb_client_t *client;
235 container_of(fe, struct smsdvb_client_t, frontend); 351 client = container_of(fe, struct smsdvb_client_t, frontend);
236 int rc = smsdvb_send_statistics_request(client);
237 352
238 if (!rc) 353 if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
239 *strength = client->fe_signal_strength; 354 *strength = 0;
355 else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
356 *strength = 100;
357 else
358 *strength =
359 (client->sms_stat_dvb.ReceptionData.InBandPwr
360 + 95) * 3 / 2;
240 361
241 return rc; 362 return 0;
242} 363}
243 364
244static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) 365static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
245{ 366{
246 struct smsdvb_client_t *client = 367 struct smsdvb_client_t *client;
247 container_of(fe, struct smsdvb_client_t, frontend); 368 client = container_of(fe, struct smsdvb_client_t, frontend);
248 int rc = smsdvb_send_statistics_request(client);
249 369
250 if (!rc) 370 *snr = client->sms_stat_dvb.ReceptionData.SNR;
251 *snr = client->fe_snr;
252 371
253 return rc; 372 return 0;
254} 373}
255 374
256static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 375static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
257{ 376{
258 struct smsdvb_client_t *client = 377 struct smsdvb_client_t *client;
259 container_of(fe, struct smsdvb_client_t, frontend); 378 client = container_of(fe, struct smsdvb_client_t, frontend);
260 int rc = smsdvb_send_statistics_request(client);
261 379
262 if (!rc) 380 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
263 *ucblocks = client->fe_unc;
264 381
265 return rc; 382 return 0;
266} 383}
267 384
268static int smsdvb_get_tune_settings(struct dvb_frontend *fe, 385static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
@@ -286,12 +403,15 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
286 struct SmsMsgHdr_ST Msg; 403 struct SmsMsgHdr_ST Msg;
287 u32 Data[3]; 404 u32 Data[3];
288 } Msg; 405 } Msg;
289 int ret;
290 406
291 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 407 client->fe_status = FE_HAS_SIGNAL;
292 Msg.Msg.msgDstId = HIF_TASK; 408 client->event_fe_state = -1;
293 Msg.Msg.msgFlags = 0; 409 client->event_unc_state = -1;
294 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; 410
411 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
412 Msg.Msg.msgDstId = HIF_TASK;
413 Msg.Msg.msgFlags = 0;
414 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
295 Msg.Msg.msgLength = sizeof(Msg); 415 Msg.Msg.msgLength = sizeof(Msg);
296 Msg.Data[0] = fep->frequency; 416 Msg.Data[0] = fep->frequency;
297 Msg.Data[2] = 12000000; 417 Msg.Data[2] = 12000000;
@@ -307,24 +427,6 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
307 default: return -EINVAL; 427 default: return -EINVAL;
308 } 428 }
309 429
310 /* Disable LNA, if any. An error is returned if no LNA is present */
311 ret = sms_board_lna_control(client->coredev, 0);
312 if (ret == 0) {
313 fe_status_t status;
314
315 /* tune with LNA off at first */
316 ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
317 &client->tune_done);
318
319 smsdvb_read_status(fe, &status);
320
321 if (status & FE_HAS_LOCK)
322 return ret;
323
324 /* previous tune didnt lock - enable LNA and tune again */
325 sms_board_lna_control(client->coredev, 1);
326 }
327
328 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), 430 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
329 &client->tune_done); 431 &client->tune_done);
330} 432}
@@ -349,8 +451,7 @@ static int smsdvb_init(struct dvb_frontend *fe)
349 struct smsdvb_client_t *client = 451 struct smsdvb_client_t *client =
350 container_of(fe, struct smsdvb_client_t, frontend); 452 container_of(fe, struct smsdvb_client_t, frontend);
351 453
352 sms_board_power(client->coredev, 1); 454 sms_board_dvb3_event(client, DVB3_EVENT_INIT);
353
354 return 0; 455 return 0;
355} 456}
356 457
@@ -359,8 +460,7 @@ static int smsdvb_sleep(struct dvb_frontend *fe)
359 struct smsdvb_client_t *client = 460 struct smsdvb_client_t *client =
360 container_of(fe, struct smsdvb_client_t, frontend); 461 container_of(fe, struct smsdvb_client_t, frontend);
361 462
362 sms_board_led_feedback(client->coredev, SMS_LED_OFF); 463 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
363 sms_board_power(client->coredev, 0);
364 464
365 return 0; 465 return 0;
366} 466}
@@ -485,7 +585,6 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
485 client->coredev = coredev; 585 client->coredev = coredev;
486 586
487 init_completion(&client->tune_done); 587 init_completion(&client->tune_done);
488 init_completion(&client->stat_done);
489 588
490 kmutex_lock(&g_smsdvb_clientslock); 589 kmutex_lock(&g_smsdvb_clientslock);
491 590
@@ -493,8 +592,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
493 592
494 kmutex_unlock(&g_smsdvb_clientslock); 593 kmutex_unlock(&g_smsdvb_clientslock);
495 594
496 sms_info("success"); 595 client->event_fe_state = -1;
596 client->event_unc_state = -1;
597 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
497 598
599 sms_info("success");
498 sms_board_setup(coredev); 600 sms_board_setup(coredev);
499 601
500 return 0; 602 return 0;
@@ -547,5 +649,5 @@ module_init(smsdvb_module_init);
547module_exit(smsdvb_module_exit); 649module_exit(smsdvb_module_exit);
548 650
549MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); 651MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
550MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); 652MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
551MODULE_LICENSE("GPL"); 653MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c
new file mode 100644
index 000000000000..457b6d02ef85
--- /dev/null
+++ b/drivers/media/dvb/siano/smsendian.c
@@ -0,0 +1,102 @@
1/****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik
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, see <http://www.gnu.org/licenses/>.
19
20 ****************************************************************/
21
22#include <asm/byteorder.h>
23
24#include "smsendian.h"
25#include "smscoreapi.h"
26
27void smsendian_handle_tx_message(void *buffer)
28{
29#ifdef __BIG_ENDIAN
30 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
31 int i;
32 int msgWords;
33
34 switch (msg->xMsgHeader.msgType) {
35 case MSG_SMS_DATA_DOWNLOAD_REQ:
36 {
37 msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
38 break;
39 }
40
41 default:
42 msgWords = (msg->xMsgHeader.msgLength -
43 sizeof(struct SmsMsgHdr_ST))/4;
44
45 for (i = 0; i < msgWords; i++)
46 msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
47
48 break;
49 }
50#endif /* __BIG_ENDIAN */
51}
52EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
53
54void smsendian_handle_rx_message(void *buffer)
55{
56#ifdef __BIG_ENDIAN
57 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
58 int i;
59 int msgWords;
60
61 switch (msg->xMsgHeader.msgType) {
62 case MSG_SMS_GET_VERSION_EX_RES:
63 {
64 struct SmsVersionRes_ST *ver =
65 (struct SmsVersionRes_ST *) msg;
66 ver->ChipModel = le16_to_cpu(ver->ChipModel);
67 break;
68 }
69
70 case MSG_SMS_DVBT_BDA_DATA:
71 case MSG_SMS_DAB_CHANNEL:
72 case MSG_SMS_DATA_MSG:
73 {
74 break;
75 }
76
77 default:
78 {
79 msgWords = (msg->xMsgHeader.msgLength -
80 sizeof(struct SmsMsgHdr_ST))/4;
81
82 for (i = 0; i < msgWords; i++)
83 msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
84
85 break;
86 }
87 }
88#endif /* __BIG_ENDIAN */
89}
90EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
91
92void smsendian_handle_message_header(void *msg)
93{
94#ifdef __BIG_ENDIAN
95 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
96
97 phdr->msgType = le16_to_cpu(phdr->msgType);
98 phdr->msgLength = le16_to_cpu(phdr->msgLength);
99 phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
100#endif /* __BIG_ENDIAN */
101}
102EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/dvb/siano/smsendian.h
new file mode 100644
index 000000000000..1624d6fd367b
--- /dev/null
+++ b/drivers/media/dvb/siano/smsendian.h
@@ -0,0 +1,32 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the 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,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#ifndef __SMS_ENDIAN_H__
23#define __SMS_ENDIAN_H__
24
25#include <asm/byteorder.h>
26
27extern void smsendian_handle_tx_message(void *buffer);
28extern void smsendian_handle_rx_message(void *buffer);
29extern void smsendian_handle_message_header(void *msg);
30
31#endif /* __SMS_ENDIAN_H__ */
32
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
new file mode 100644
index 000000000000..e3d776feeaca
--- /dev/null
+++ b/drivers/media/dvb/siano/smsir.c
@@ -0,0 +1,301 @@
1/****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik
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, see <http://www.gnu.org/licenses/>.
19
20 ****************************************************************/
21
22
23#include <linux/types.h>
24#include <linux/input.h>
25
26#include "smscoreapi.h"
27#include "smsir.h"
28#include "sms-cards.h"
29
30/* In order to add new IR remote control -
31 * 1) Add it to the <enum ir_kb_type> @ smsir,h,
32 * 2) Add its map to keyboard_layout_maps below
33 * 3) Set your board (sms-cards sub-module) to use it
34 */
35
36static struct keyboard_layout_map_t keyboard_layout_maps[] = {
37 [SMS_IR_KB_DEFAULT_TV] = {
38 .ir_protocol = IR_RC5,
39 .rc5_kbd_address = KEYBOARD_ADDRESS_TV1,
40 .keyboard_layout_map = {
41 KEY_0, KEY_1, KEY_2,
42 KEY_3, KEY_4, KEY_5,
43 KEY_6, KEY_7, KEY_8,
44 KEY_9, 0, 0, KEY_POWER,
45 KEY_MUTE, 0, 0,
46 KEY_VOLUMEUP, KEY_VOLUMEDOWN,
47 KEY_BRIGHTNESSUP,
48 KEY_BRIGHTNESSDOWN, KEY_CHANNELUP,
49 KEY_CHANNELDOWN,
50 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
55 }
56 },
57 [SMS_IR_KB_HCW_SILVER] = {
58 .ir_protocol = IR_RC5,
59 .rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1,
60 .keyboard_layout_map = {
61 KEY_0, KEY_1, KEY_2,
62 KEY_3, KEY_4, KEY_5,
63 KEY_6, KEY_7, KEY_8,
64 KEY_9, KEY_TEXT, KEY_RED,
65 KEY_RADIO, KEY_MENU,
66 KEY_SUBTITLE,
67 KEY_MUTE, KEY_VOLUMEUP,
68 KEY_VOLUMEDOWN, KEY_PREVIOUS, 0,
69 KEY_UP, KEY_DOWN, KEY_LEFT,
70 KEY_RIGHT, KEY_VIDEO, KEY_AUDIO,
71 KEY_MHP, KEY_EPG, KEY_TV,
72 0, KEY_NEXTSONG, KEY_EXIT,
73 KEY_CHANNELUP, KEY_CHANNELDOWN,
74 KEY_CHANNEL, 0,
75 KEY_PREVIOUSSONG, KEY_ENTER,
76 KEY_SLEEP, 0, 0, KEY_BLUE,
77 0, 0, 0, 0, KEY_GREEN, 0,
78 KEY_PAUSE, 0, KEY_REWIND,
79 0, KEY_FASTFORWARD, KEY_PLAY,
80 KEY_STOP, KEY_RECORD,
81 KEY_YELLOW, 0, 0, KEY_SELECT,
82 KEY_ZOOM, KEY_POWER, 0, 0
83 }
84 },
85 { } /* Terminating entry */
86};
87
88u32 ir_pos;
89u32 ir_word;
90u32 ir_toggle;
91
92#define RC5_PUSH_BIT(dst, bit, pos) \
93 { dst <<= 1; dst |= bit; pos++; }
94
95
96static void sms_ir_rc5_event(struct smscore_device_t *coredev,
97 u32 toggle, u32 addr, u32 cmd)
98{
99 bool toggle_changed;
100 u16 keycode;
101
102 sms_log("IR RC5 word: address %d, command %d, toggle %d",
103 addr, cmd, toggle);
104
105 toggle_changed = ir_toggle != toggle;
106 /* keep toggle */
107 ir_toggle = toggle;
108
109 if (addr !=
110 keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address)
111 return; /* Check for valid address */
112
113 keycode =
114 keyboard_layout_maps
115 [coredev->ir.ir_kb_type].keyboard_layout_map[cmd];
116
117 if (!toggle_changed &&
118 (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN))
119 return; /* accept only repeated volume, reject other keys */
120
121 sms_log("kernel input keycode (from ir) %d", keycode);
122 input_report_key(coredev->ir.input_dev, keycode, 1);
123 input_sync(coredev->ir.input_dev);
124
125}
126
127/* decode raw bit pattern to RC5 code */
128/* taken from ir-functions.c */
129static u32 ir_rc5_decode(unsigned int code)
130{
131/* unsigned int org_code = code;*/
132 unsigned int pair;
133 unsigned int rc5 = 0;
134 int i;
135
136 for (i = 0; i < 14; ++i) {
137 pair = code & 0x3;
138 code >>= 2;
139
140 rc5 <<= 1;
141 switch (pair) {
142 case 0:
143 case 2:
144 break;
145 case 1:
146 rc5 |= 1;
147 break;
148 case 3:
149/* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/
150 sms_log("bad code");
151 return 0;
152 }
153 }
154/*
155 dprintk(1, "ir-common: code=%x, rc5=%x, start=%x,
156 toggle=%x, address=%x, "
157 "instr=%x\n", rc5, org_code, RC5_START(rc5),
158 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
159*/
160 return rc5;
161}
162
163static void sms_rc5_parse_word(struct smscore_device_t *coredev)
164{
165 #define RC5_START(x) (((x)>>12)&3)
166 #define RC5_TOGGLE(x) (((x)>>11)&1)
167 #define RC5_ADDR(x) (((x)>>6)&0x1F)
168 #define RC5_INSTR(x) ((x)&0x3F)
169
170 int i, j;
171 u32 rc5_word = 0;
172
173 /* Reverse the IR word direction */
174 for (i = 0 ; i < 28 ; i++)
175 RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j)
176
177 rc5_word = ir_rc5_decode(rc5_word);
178 /* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */
179
180 sms_ir_rc5_event(coredev,
181 RC5_TOGGLE(rc5_word),
182 RC5_ADDR(rc5_word),
183 RC5_INSTR(rc5_word));
184}
185
186
187static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev,
188 s32 ir_sample)
189{
190 #define RC5_TIME_GRANULARITY 200
191 #define RC5_DEF_BIT_TIME 889
192 #define RC5_MAX_SAME_BIT_CONT 4
193 #define RC5_WORD_LEN 27 /* 28 bit */
194
195 u32 i, j;
196 s32 delta_time;
197 u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample);
198 u32 level = (ir_sample < 0) ? 0 : 1;
199
200 for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) {
201 delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY;
202 if (delta_time < 0)
203 continue; /* not so many consecutive bits */
204 if (delta_time > (2 * RC5_TIME_GRANULARITY)) {
205 /* timeout */
206 if (ir_pos == (RC5_WORD_LEN-1))
207 /* complete last bit */
208 RC5_PUSH_BIT(ir_word, level, ir_pos)
209
210 if (ir_pos == RC5_WORD_LEN)
211 sms_rc5_parse_word(coredev);
212 else if (ir_pos) /* timeout within a word */
213 sms_log("IR error parsing a word");
214
215 ir_pos = 0;
216 ir_word = 0;
217 /* sms_log("timeout %d", time); */
218 break;
219 }
220 /* The time is within the range of this number of bits */
221 for (j = 0 ; j < i ; j++)
222 RC5_PUSH_BIT(ir_word, level, ir_pos)
223
224 break;
225 }
226}
227
228void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
229{
230 #define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */
231 u32 i;
232 enum ir_protocol ir_protocol =
233 keyboard_layout_maps[coredev->ir.ir_kb_type]
234 .ir_protocol;
235 s32 *samples;
236 int count = len>>2;
237
238 samples = (s32 *)buf;
239/* sms_log("IR buffer received, length = %d", count);*/
240
241 for (i = 0; i < count; i++)
242 if (ir_protocol == IR_RC5)
243 sms_rc5_accumulate_bits(coredev, samples[i]);
244 /* IR_RCMM not implemented */
245}
246
247int sms_ir_init(struct smscore_device_t *coredev)
248{
249 struct input_dev *input_dev;
250
251 sms_log("Allocating input device");
252 input_dev = input_allocate_device();
253 if (!input_dev) {
254 sms_err("Not enough memory");
255 return -ENOMEM;
256 }
257
258 coredev->ir.input_dev = input_dev;
259 coredev->ir.ir_kb_type =
260 sms_get_board(smscore_get_board_id(coredev))->ir_kb_type;
261 coredev->ir.keyboard_layout_map =
262 keyboard_layout_maps[coredev->ir.ir_kb_type].
263 keyboard_layout_map;
264 sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type);
265
266 coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
267 coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
268 sms_log("IR port %d, timeout %d ms",
269 coredev->ir.controller, coredev->ir.timeout);
270
271 snprintf(coredev->ir.name,
272 IR_DEV_NAME_MAX_LEN,
273 "SMS IR w/kbd type %d",
274 coredev->ir.ir_kb_type);
275 input_dev->name = coredev->ir.name;
276 input_dev->phys = coredev->ir.name;
277 input_dev->dev.parent = coredev->device;
278
279 /* Key press events only */
280 input_dev->evbit[0] = BIT_MASK(EV_KEY);
281 input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
282
283 sms_log("Input device (IR) %s is set for key events", input_dev->name);
284
285 if (input_register_device(input_dev)) {
286 sms_err("Failed to register device");
287 input_free_device(input_dev);
288 return -EACCES;
289 }
290
291 return 0;
292}
293
294void sms_ir_exit(struct smscore_device_t *coredev)
295{
296 if (coredev->ir.input_dev)
297 input_unregister_device(coredev->ir.input_dev);
298
299 sms_log("");
300}
301
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h
new file mode 100644
index 000000000000..b7d703e2d338
--- /dev/null
+++ b/drivers/media/dvb/siano/smsir.h
@@ -0,0 +1,93 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the 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,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#ifndef __SMS_IR_H__
23#define __SMS_IR_H__
24
25#include <linux/input.h>
26
27#define IR_DEV_NAME_MAX_LEN 23 /* "SMS IR kbd type nn\0" */
28#define IR_KEYBOARD_LAYOUT_SIZE 64
29#define IR_DEFAULT_TIMEOUT 100
30
31enum ir_kb_type {
32 SMS_IR_KB_DEFAULT_TV,
33 SMS_IR_KB_HCW_SILVER
34};
35
36enum rc5_keyboard_address {
37 KEYBOARD_ADDRESS_TV1 = 0,
38 KEYBOARD_ADDRESS_TV2 = 1,
39 KEYBOARD_ADDRESS_TELETEXT = 2,
40 KEYBOARD_ADDRESS_VIDEO = 3,
41 KEYBOARD_ADDRESS_LV1 = 4,
42 KEYBOARD_ADDRESS_VCR1 = 5,
43 KEYBOARD_ADDRESS_VCR2 = 6,
44 KEYBOARD_ADDRESS_EXPERIMENTAL = 7,
45 KEYBOARD_ADDRESS_SAT1 = 8,
46 KEYBOARD_ADDRESS_CAMERA = 9,
47 KEYBOARD_ADDRESS_SAT2 = 10,
48 KEYBOARD_ADDRESS_CDV = 12,
49 KEYBOARD_ADDRESS_CAMCORDER = 13,
50 KEYBOARD_ADDRESS_PRE_AMP = 16,
51 KEYBOARD_ADDRESS_TUNER = 17,
52 KEYBOARD_ADDRESS_RECORDER1 = 18,
53 KEYBOARD_ADDRESS_PRE_AMP1 = 19,
54 KEYBOARD_ADDRESS_CD_PLAYER = 20,
55 KEYBOARD_ADDRESS_PHONO = 21,
56 KEYBOARD_ADDRESS_SATA = 22,
57 KEYBOARD_ADDRESS_RECORDER2 = 23,
58 KEYBOARD_ADDRESS_CDR = 26,
59 KEYBOARD_ADDRESS_LIGHTING = 29,
60 KEYBOARD_ADDRESS_LIGHTING1 = 30, /* KEYBOARD_ADDRESS_HCW_SILVER */
61 KEYBOARD_ADDRESS_PHONE = 31,
62 KEYBOARD_ADDRESS_NOT_RC5 = 0xFFFF
63};
64
65enum ir_protocol {
66 IR_RC5,
67 IR_RCMM
68};
69
70struct keyboard_layout_map_t {
71 enum ir_protocol ir_protocol;
72 enum rc5_keyboard_address rc5_kbd_address;
73 u16 keyboard_layout_map[IR_KEYBOARD_LAYOUT_SIZE];
74};
75
76struct smscore_device_t;
77
78struct ir_t {
79 struct input_dev *input_dev;
80 enum ir_kb_type ir_kb_type;
81 char name[IR_DEV_NAME_MAX_LEN+1];
82 u16 *keyboard_layout_map;
83 u32 timeout;
84 u32 controller;
85};
86
87int sms_ir_init(struct smscore_device_t *coredev);
88void sms_ir_exit(struct smscore_device_t *coredev);
89void sms_ir_event(struct smscore_device_t *coredev,
90 const char *buf, int len);
91
92#endif /* __SMS_IR_H__ */
93
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
new file mode 100644
index 000000000000..dfaa49a53f32
--- /dev/null
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -0,0 +1,357 @@
1/*
2 * smssdio.c - Siano 1xxx SDIO interface driver
3 *
4 * Copyright 2008 Pierre Ossman
5 *
6 * Based on code by Siano Mobile Silicon, Inc.,
7 * Copyright (C) 2006-2008, Uri Shkolnik
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 (at
12 * your option) any later version.
13 *
14 *
15 * This hardware is a bit odd in that all transfers should be done
16 * to/from the SMSSDIO_DATA register, yet the "increase address" bit
17 * always needs to be set.
18 *
19 * Also, buffers from the card are always aligned to 128 byte
20 * boundaries.
21 */
22
23/*
24 * General cleanup notes:
25 *
26 * - only typedefs should be name *_t
27 *
28 * - use ERR_PTR and friends for smscore_register_device()
29 *
30 * - smscore_getbuffer should zero fields
31 *
32 * Fix stop command
33 */
34
35#include <linux/moduleparam.h>
36#include <linux/firmware.h>
37#include <linux/delay.h>
38#include <linux/mmc/card.h>
39#include <linux/mmc/sdio_func.h>
40#include <linux/mmc/sdio_ids.h>
41
42#include "smscoreapi.h"
43#include "sms-cards.h"
44
45/* Registers */
46
47#define SMSSDIO_DATA 0x00
48#define SMSSDIO_INT 0x04
49
50static const struct sdio_device_id smssdio_ids[] = {
51 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
52 .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
53 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
54 .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
55 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
56 .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
57 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
58 .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
59 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
60 .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
61 { /* end: all zeroes */ },
62};
63
64MODULE_DEVICE_TABLE(sdio, smssdio_ids);
65
66struct smssdio_device {
67 struct sdio_func *func;
68
69 struct smscore_device_t *coredev;
70
71 struct smscore_buffer_t *split_cb;
72};
73
74/*******************************************************************/
75/* Siano core callbacks */
76/*******************************************************************/
77
78static int smssdio_sendrequest(void *context, void *buffer, size_t size)
79{
80 int ret;
81 struct smssdio_device *smsdev;
82
83 smsdev = context;
84
85 sdio_claim_host(smsdev->func);
86
87 while (size >= smsdev->func->cur_blksize) {
88 ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1);
89 if (ret)
90 goto out;
91
92 buffer += smsdev->func->cur_blksize;
93 size -= smsdev->func->cur_blksize;
94 }
95
96 if (size) {
97 ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA,
98 buffer, size);
99 }
100
101out:
102 sdio_release_host(smsdev->func);
103
104 return ret;
105}
106
107/*******************************************************************/
108/* SDIO callbacks */
109/*******************************************************************/
110
111static void smssdio_interrupt(struct sdio_func *func)
112{
113 int ret, isr;
114
115 struct smssdio_device *smsdev;
116 struct smscore_buffer_t *cb;
117 struct SmsMsgHdr_ST *hdr;
118 size_t size;
119
120 smsdev = sdio_get_drvdata(func);
121
122 /*
123 * The interrupt register has no defined meaning. It is just
124 * a way of turning of the level triggered interrupt.
125 */
126 isr = sdio_readb(func, SMSSDIO_INT, &ret);
127 if (ret) {
128 dev_err(&smsdev->func->dev,
129 "Unable to read interrupt register!\n");
130 return;
131 }
132
133 if (smsdev->split_cb == NULL) {
134 cb = smscore_getbuffer(smsdev->coredev);
135 if (!cb) {
136 dev_err(&smsdev->func->dev,
137 "Unable to allocate data buffer!\n");
138 return;
139 }
140
141 ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1);
142 if (ret) {
143 dev_err(&smsdev->func->dev,
144 "Error %d reading initial block!\n", ret);
145 return;
146 }
147
148 hdr = cb->p;
149
150 if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
151 smsdev->split_cb = cb;
152 return;
153 }
154
155 size = hdr->msgLength - smsdev->func->cur_blksize;
156 } else {
157 cb = smsdev->split_cb;
158 hdr = cb->p;
159
160 size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
161
162 smsdev->split_cb = NULL;
163 }
164
165 if (hdr->msgLength > smsdev->func->cur_blksize) {
166 void *buffer;
167
168 size = ALIGN(size, 128);
169 buffer = cb->p + hdr->msgLength;
170
171 BUG_ON(smsdev->func->cur_blksize != 128);
172
173 /*
174 * First attempt to transfer all of it in one go...
175 */
176 ret = sdio_read_blocks(smsdev->func, buffer,
177 SMSSDIO_DATA, size / 128);
178 if (ret && ret != -EINVAL) {
179 smscore_putbuffer(smsdev->coredev, cb);
180 dev_err(&smsdev->func->dev,
181 "Error %d reading data from card!\n", ret);
182 return;
183 }
184
185 /*
186 * ..then fall back to one block at a time if that is
187 * not possible...
188 *
189 * (we have to do this manually because of the
190 * problem with the "increase address" bit)
191 */
192 if (ret == -EINVAL) {
193 while (size) {
194 ret = sdio_read_blocks(smsdev->func,
195 buffer, SMSSDIO_DATA, 1);
196 if (ret) {
197 smscore_putbuffer(smsdev->coredev, cb);
198 dev_err(&smsdev->func->dev,
199 "Error %d reading "
200 "data from card!\n", ret);
201 return;
202 }
203
204 buffer += smsdev->func->cur_blksize;
205 if (size > smsdev->func->cur_blksize)
206 size -= smsdev->func->cur_blksize;
207 else
208 size = 0;
209 }
210 }
211 }
212
213 cb->size = hdr->msgLength;
214 cb->offset = 0;
215
216 smscore_onresponse(smsdev->coredev, cb);
217}
218
219static int smssdio_probe(struct sdio_func *func,
220 const struct sdio_device_id *id)
221{
222 int ret;
223
224 int board_id;
225 struct smssdio_device *smsdev;
226 struct smsdevice_params_t params;
227
228 board_id = id->driver_data;
229
230 smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
231 if (!smsdev)
232 return -ENOMEM;
233
234 smsdev->func = func;
235
236 memset(&params, 0, sizeof(struct smsdevice_params_t));
237
238 params.device = &func->dev;
239 params.buffer_size = 0x5000; /* ?? */
240 params.num_buffers = 22; /* ?? */
241 params.context = smsdev;
242
243 snprintf(params.devpath, sizeof(params.devpath),
244 "sdio\\%s", sdio_func_id(func));
245
246 params.sendrequest_handler = smssdio_sendrequest;
247
248 params.device_type = sms_get_board(board_id)->type;
249
250 if (params.device_type != SMS_STELLAR)
251 params.flags |= SMS_DEVICE_FAMILY2;
252 else {
253 /*
254 * FIXME: Stellar needs special handling...
255 */
256 ret = -ENODEV;
257 goto free;
258 }
259
260 ret = smscore_register_device(&params, &smsdev->coredev);
261 if (ret < 0)
262 goto free;
263
264 smscore_set_board_id(smsdev->coredev, board_id);
265
266 sdio_claim_host(func);
267
268 ret = sdio_enable_func(func);
269 if (ret)
270 goto release;
271
272 ret = sdio_set_block_size(func, 128);
273 if (ret)
274 goto disable;
275
276 ret = sdio_claim_irq(func, smssdio_interrupt);
277 if (ret)
278 goto disable;
279
280 sdio_set_drvdata(func, smsdev);
281
282 sdio_release_host(func);
283
284 ret = smscore_start_device(smsdev->coredev);
285 if (ret < 0)
286 goto reclaim;
287
288 return 0;
289
290reclaim:
291 sdio_claim_host(func);
292 sdio_release_irq(func);
293disable:
294 sdio_disable_func(func);
295release:
296 sdio_release_host(func);
297 smscore_unregister_device(smsdev->coredev);
298free:
299 kfree(smsdev);
300
301 return ret;
302}
303
304static void smssdio_remove(struct sdio_func *func)
305{
306 struct smssdio_device *smsdev;
307
308 smsdev = sdio_get_drvdata(func);
309
310 /* FIXME: racy! */
311 if (smsdev->split_cb)
312 smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
313
314 smscore_unregister_device(smsdev->coredev);
315
316 sdio_claim_host(func);
317 sdio_release_irq(func);
318 sdio_disable_func(func);
319 sdio_release_host(func);
320
321 kfree(smsdev);
322}
323
324static struct sdio_driver smssdio_driver = {
325 .name = "smssdio",
326 .id_table = smssdio_ids,
327 .probe = smssdio_probe,
328 .remove = smssdio_remove,
329};
330
331/*******************************************************************/
332/* Module functions */
333/*******************************************************************/
334
335int smssdio_module_init(void)
336{
337 int ret = 0;
338
339 printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
340 printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
341
342 ret = sdio_register_driver(&smssdio_driver);
343
344 return ret;
345}
346
347void smssdio_module_exit(void)
348{
349 sdio_unregister_driver(&smssdio_driver);
350}
351
352module_init(smssdio_module_init);
353module_exit(smssdio_module_exit);
354
355MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
356MODULE_AUTHOR("Pierre Ossman");
357MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 71c65f544c07..cb8a358b7310 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -1,23 +1,23 @@
1/* 1/****************************************************************
2 * Driver for the Siano SMS1xxx USB dongle 2
3 * 3Siano Mobile Silicon, Inc.
4 * author: Anatoly Greenblat 4MDTV receiver kernel modules.
5 * 5Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 6
7 * 7This program is free software: you can redistribute it and/or modify
8 * This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by
9 * it under the terms of the GNU General Public License version 2 as 9the Free Software Foundation, either version 2 of the License, or
10 * published by the Free Software Foundation; 10(at your option) any later version.
11 * 11
12 * Software distributed under the License is distributed on an "AS IS" 12 This program is distributed in the hope that it will be useful,
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 13but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * See the GNU General Public License for more details. 15GNU General Public License for more details.
16 * 16
17 * You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19
20 */ 20****************************************************************/
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/init.h> 23#include <linux/init.h>
@@ -26,6 +26,7 @@
26 26
27#include "smscoreapi.h" 27#include "smscoreapi.h"
28#include "sms-cards.h" 28#include "sms-cards.h"
29#include "smsendian.h"
29 30
30static int sms_dbg; 31static int sms_dbg;
31module_param_named(debug, sms_dbg, int, 0644); 32module_param_named(debug, sms_dbg, int, 0644);
@@ -64,15 +65,16 @@ static void smsusb_onresponse(struct urb *urb)
64 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; 65 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
65 struct smsusb_device_t *dev = surb->dev; 66 struct smsusb_device_t *dev = surb->dev;
66 67
67 if (urb->status < 0) { 68 if (urb->status == -ESHUTDOWN) {
68 sms_err("error, urb status %d, %d bytes", 69 sms_err("error, urb status %d (-ESHUTDOWN), %d bytes",
69 urb->status, urb->actual_length); 70 urb->status, urb->actual_length);
70 return; 71 return;
71 } 72 }
72 73
73 if (urb->actual_length > 0) { 74 if ((urb->actual_length > 0) && (urb->status == 0)) {
74 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p; 75 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p;
75 76
77 smsendian_handle_message_header(phdr);
76 if (urb->actual_length >= phdr->msgLength) { 78 if (urb->actual_length >= phdr->msgLength) {
77 surb->cb->size = phdr->msgLength; 79 surb->cb->size = phdr->msgLength;
78 80
@@ -109,7 +111,10 @@ static void smsusb_onresponse(struct urb *urb)
109 "msglen %d actual %d", 111 "msglen %d actual %d",
110 phdr->msgLength, urb->actual_length); 112 phdr->msgLength, urb->actual_length);
111 } 113 }
112 } 114 } else
115 sms_err("error, urb status %d, %d bytes",
116 urb->status, urb->actual_length);
117
113 118
114exit_and_resubmit: 119exit_and_resubmit:
115 smsusb_submit_urb(dev, surb); 120 smsusb_submit_urb(dev, surb);
@@ -176,6 +181,7 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size)
176 struct smsusb_device_t *dev = (struct smsusb_device_t *) context; 181 struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
177 int dummy; 182 int dummy;
178 183
184 smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer);
179 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), 185 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
180 buffer, size, &dummy, 1000); 186 buffer, size, &dummy, 1000);
181} 187}
@@ -333,8 +339,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
333 case SMS_VEGA: 339 case SMS_VEGA:
334 dev->buffer_size = USB2_BUFFER_SIZE; 340 dev->buffer_size = USB2_BUFFER_SIZE;
335 dev->response_alignment = 341 dev->response_alignment =
336 dev->udev->ep_in[1]->desc.wMaxPacketSize - 342 le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
337 sizeof(struct SmsMsgHdr_ST); 343 sizeof(struct SmsMsgHdr_ST);
338 344
339 params.flags |= SMS_DEVICE_FAMILY2; 345 params.flags |= SMS_DEVICE_FAMILY2;
340 break; 346 break;
@@ -479,7 +485,6 @@ static int smsusb_resume(struct usb_interface *intf)
479} 485}
480 486
481struct usb_device_id smsusb_id_table[] = { 487struct usb_device_id smsusb_id_table[] = {
482#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
483 { USB_DEVICE(0x187f, 0x0010), 488 { USB_DEVICE(0x187f, 0x0010),
484 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, 489 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
485 { USB_DEVICE(0x187f, 0x0100), 490 { USB_DEVICE(0x187f, 0x0100),
@@ -490,7 +495,6 @@ struct usb_device_id smsusb_id_table[] = {
490 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, 495 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
491 { USB_DEVICE(0x187f, 0x0300), 496 { USB_DEVICE(0x187f, 0x0300),
492 .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, 497 .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
493#endif
494 { USB_DEVICE(0x2040, 0x1700), 498 { USB_DEVICE(0x2040, 0x1700),
495 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, 499 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
496 { USB_DEVICE(0x2040, 0x1800), 500 { USB_DEVICE(0x2040, 0x1800),
@@ -521,8 +525,13 @@ struct usb_device_id smsusb_id_table[] = {
521 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 525 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
522 { USB_DEVICE(0x2040, 0x5590), 526 { USB_DEVICE(0x2040, 0x5590),
523 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 527 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
524 { } /* Terminating entry */ 528 { USB_DEVICE(0x187f, 0x0202),
525}; 529 .driver_info = SMS1XXX_BOARD_SIANO_NICE },
530 { USB_DEVICE(0x187f, 0x0301),
531 .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
532 { } /* Terminating entry */
533 };
534
526MODULE_DEVICE_TABLE(usb, smsusb_id_table); 535MODULE_DEVICE_TABLE(usb, smsusb_id_table);
527 536
528static struct usb_driver smsusb_driver = { 537static struct usb_driver smsusb_driver = {
@@ -548,14 +557,14 @@ int smsusb_module_init(void)
548 557
549void smsusb_module_exit(void) 558void smsusb_module_exit(void)
550{ 559{
551 sms_debug("");
552 /* Regular USB Cleanup */ 560 /* Regular USB Cleanup */
553 usb_deregister(&smsusb_driver); 561 usb_deregister(&smsusb_driver);
562 sms_info("end");
554} 563}
555 564
556module_init(smsusb_module_init); 565module_init(smsusb_module_init);
557module_exit(smsusb_module_exit); 566module_exit(smsusb_module_exit);
558 567
559MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); 568MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle");
560MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); 569MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
561MODULE_LICENSE("GPL"); 570MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index e4d0900d5121..53884814161c 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -89,6 +89,7 @@
89 89
90static void p_to_t(u8 const *buf, long int length, u16 pid, 90static void p_to_t(u8 const *buf, long int length, u16 pid,
91 u8 *counter, struct dvb_demux_feed *feed); 91 u8 *counter, struct dvb_demux_feed *feed);
92static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len);
92 93
93 94
94int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) 95int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
@@ -192,8 +193,6 @@ int av7110_av_start_play(struct av7110 *av7110, int av)
192 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); 193 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
193 break; 194 break;
194 } 195 }
195 if (!ret)
196 ret = av7110->playing;
197 return ret; 196 return ret;
198} 197}
199 198
@@ -437,6 +436,45 @@ static void play_audio_cb(u8 *buf, int count, void *priv)
437 aux_ring_buffer_write(&av7110->aout, buf, count); 436 aux_ring_buffer_write(&av7110->aout, buf, count);
438} 437}
439 438
439
440#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096)
441
442static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
443 unsigned long count, int nonblock, int type)
444{
445 struct dvb_ringbuffer *rb;
446 u8 *kb;
447 unsigned long todo = count;
448
449 dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count);
450
451 rb = (type) ? &av7110->avout : &av7110->aout;
452 kb = av7110->kbuf[type];
453
454 if (!kb)
455 return -ENOBUFS;
456
457 if (nonblock && !FREE_COND_TS)
458 return -EWOULDBLOCK;
459
460 while (todo >= TS_SIZE) {
461 if (!FREE_COND_TS) {
462 if (nonblock)
463 return count - todo;
464 if (wait_event_interruptible(rb->queue, FREE_COND_TS))
465 return count - todo;
466 }
467 if (copy_from_user(kb, buf, TS_SIZE))
468 return -EFAULT;
469 write_ts_to_decoder(av7110, type, kb, TS_SIZE);
470 todo -= TS_SIZE;
471 buf += TS_SIZE;
472 }
473
474 return count - todo;
475}
476
477
440#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ 478#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
441 dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) 479 dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
442 480
@@ -780,11 +818,37 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
780} 818}
781 819
782 820
821static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len)
822{
823 struct ipack *ipack = &av7110->ipack[type];
824
825 if (buf[1] & TRANS_ERROR) {
826 av7110_ipack_reset(ipack);
827 return -1;
828 }
829
830 if (!(buf[3] & PAYLOAD))
831 return -1;
832
833 if (buf[1] & PAY_START)
834 av7110_ipack_flush(ipack);
835
836 if (buf[3] & ADAPT_FIELD) {
837 len -= buf[4] + 1;
838 buf += buf[4] + 1;
839 if (!len)
840 return 0;
841 }
842
843 av7110_ipack_instant_repack(buf + 4, len - 4, ipack);
844 return 0;
845}
846
847
783int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) 848int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
784{ 849{
785 struct dvb_demux *demux = feed->demux; 850 struct dvb_demux *demux = feed->demux;
786 struct av7110 *av7110 = (struct av7110 *) demux->priv; 851 struct av7110 *av7110 = (struct av7110 *) demux->priv;
787 struct ipack *ipack = &av7110->ipack[feed->pes_type];
788 852
789 dprintk(2, "av7110:%p, \n", av7110); 853 dprintk(2, "av7110:%p, \n", av7110);
790 854
@@ -804,20 +868,7 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l
804 return -1; 868 return -1;
805 } 869 }
806 870
807 if (!(buf[3] & 0x10)) /* no payload? */ 871 return write_ts_to_decoder(av7110, feed->pes_type, buf, len);
808 return -1;
809 if (buf[1] & 0x40)
810 av7110_ipack_flush(ipack);
811
812 if (buf[3] & 0x20) { /* adaptation field? */
813 len -= buf[4] + 1;
814 buf += buf[4] + 1;
815 if (!len)
816 return 0;
817 }
818
819 av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]);
820 return 0;
821} 872}
822 873
823 874
@@ -916,6 +967,7 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf,
916{ 967{
917 struct dvb_device *dvbdev = file->private_data; 968 struct dvb_device *dvbdev = file->private_data;
918 struct av7110 *av7110 = dvbdev->priv; 969 struct av7110 *av7110 = dvbdev->priv;
970 unsigned char c;
919 971
920 dprintk(2, "av7110:%p, \n", av7110); 972 dprintk(2, "av7110:%p, \n", av7110);
921 973
@@ -925,7 +977,12 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf,
925 if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) 977 if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
926 return -EPERM; 978 return -EPERM;
927 979
928 return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); 980 if (get_user(c, buf))
981 return -EFAULT;
982 if (c == 0x47 && count % TS_SIZE == 0)
983 return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
984 else
985 return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
929} 986}
930 987
931static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) 988static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
@@ -952,6 +1009,7 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
952{ 1009{
953 struct dvb_device *dvbdev = file->private_data; 1010 struct dvb_device *dvbdev = file->private_data;
954 struct av7110 *av7110 = dvbdev->priv; 1011 struct av7110 *av7110 = dvbdev->priv;
1012 unsigned char c;
955 1013
956 dprintk(2, "av7110:%p, \n", av7110); 1014 dprintk(2, "av7110:%p, \n", av7110);
957 1015
@@ -959,7 +1017,13 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
959 printk(KERN_ERR "not audio source memory\n"); 1017 printk(KERN_ERR "not audio source memory\n");
960 return -EPERM; 1018 return -EPERM;
961 } 1019 }
962 return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); 1020
1021 if (get_user(c, buf))
1022 return -EFAULT;
1023 if (c == 0x47 && count % TS_SIZE == 0)
1024 return ts_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
1025 else
1026 return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
963} 1027}
964 1028
965static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; 1029static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
@@ -1062,7 +1126,6 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1062 if (ret) 1126 if (ret)
1063 break; 1127 break;
1064 } 1128 }
1065
1066 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { 1129 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
1067 if (av7110->playing == RP_AV) { 1130 if (av7110->playing == RP_AV) {
1068 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1131 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
@@ -1122,20 +1185,16 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1122 case VIDEO_SET_DISPLAY_FORMAT: 1185 case VIDEO_SET_DISPLAY_FORMAT:
1123 { 1186 {
1124 video_displayformat_t format = (video_displayformat_t) arg; 1187 video_displayformat_t format = (video_displayformat_t) arg;
1125
1126 switch (format) { 1188 switch (format) {
1127 case VIDEO_PAN_SCAN: 1189 case VIDEO_PAN_SCAN:
1128 av7110->display_panscan = VID_PAN_SCAN_PREF; 1190 av7110->display_panscan = VID_PAN_SCAN_PREF;
1129 break; 1191 break;
1130
1131 case VIDEO_LETTER_BOX: 1192 case VIDEO_LETTER_BOX:
1132 av7110->display_panscan = VID_VC_AND_PS_PREF; 1193 av7110->display_panscan = VID_VC_AND_PS_PREF;
1133 break; 1194 break;
1134
1135 case VIDEO_CENTER_CUT_OUT: 1195 case VIDEO_CENTER_CUT_OUT:
1136 av7110->display_panscan = VID_CENTRE_CUT_PREF; 1196 av7110->display_panscan = VID_CENTRE_CUT_PREF;
1137 break; 1197 break;
1138
1139 default: 1198 default:
1140 ret = -EINVAL; 1199 ret = -EINVAL;
1141 } 1200 }
@@ -1183,7 +1242,8 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1183 1242
1184 case VIDEO_SLOWMOTION: 1243 case VIDEO_SLOWMOTION:
1185 if (av7110->playing&RP_VIDEO) { 1244 if (av7110->playing&RP_VIDEO) {
1186 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1245 if (av7110->trickmode != TRICK_SLOW)
1246 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
1187 if (!ret) 1247 if (!ret)
1188 ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); 1248 ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg);
1189 } else { 1249 } else {
@@ -1207,7 +1267,6 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1207 case VIDEO_CLEAR_BUFFER: 1267 case VIDEO_CLEAR_BUFFER:
1208 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 1268 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1209 av7110_ipack_reset(&av7110->ipack[1]); 1269 av7110_ipack_reset(&av7110->ipack[1]);
1210
1211 if (av7110->playing == RP_AV) { 1270 if (av7110->playing == RP_AV) {
1212 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1271 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1213 __Play, 2, AV_PES, 0); 1272 __Play, 2, AV_PES, 0);
@@ -1228,13 +1287,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1228 break; 1287 break;
1229 1288
1230 case VIDEO_SET_STREAMTYPE: 1289 case VIDEO_SET_STREAMTYPE:
1231
1232 break; 1290 break;
1233 1291
1234 default: 1292 default:
1235 ret = -ENOIOCTLCMD; 1293 ret = -ENOIOCTLCMD;
1236 break; 1294 break;
1237 } 1295 }
1296
1238 return ret; 1297 return ret;
1239} 1298}
1240 1299
@@ -1309,7 +1368,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1309 1368
1310 case AUDIO_CHANNEL_SELECT: 1369 case AUDIO_CHANNEL_SELECT:
1311 av7110->audiostate.channel_select = (audio_channel_select_t) arg; 1370 av7110->audiostate.channel_select = (audio_channel_select_t) arg;
1312
1313 switch(av7110->audiostate.channel_select) { 1371 switch(av7110->audiostate.channel_select) {
1314 case AUDIO_STEREO: 1372 case AUDIO_STEREO:
1315 ret = audcom(av7110, AUDIO_CMD_STEREO); 1373 ret = audcom(av7110, AUDIO_CMD_STEREO);
@@ -1320,7 +1378,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1320 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); 1378 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220);
1321 } 1379 }
1322 break; 1380 break;
1323
1324 case AUDIO_MONO_LEFT: 1381 case AUDIO_MONO_LEFT:
1325 ret = audcom(av7110, AUDIO_CMD_MONO_L); 1382 ret = audcom(av7110, AUDIO_CMD_MONO_L);
1326 if (!ret) { 1383 if (!ret) {
@@ -1330,7 +1387,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1330 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); 1387 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200);
1331 } 1388 }
1332 break; 1389 break;
1333
1334 case AUDIO_MONO_RIGHT: 1390 case AUDIO_MONO_RIGHT:
1335 ret = audcom(av7110, AUDIO_CMD_MONO_R); 1391 ret = audcom(av7110, AUDIO_CMD_MONO_R);
1336 if (!ret) { 1392 if (!ret) {
@@ -1340,7 +1396,6 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1340 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); 1396 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210);
1341 } 1397 }
1342 break; 1398 break;
1343
1344 default: 1399 default:
1345 ret = -EINVAL; 1400 ret = -EINVAL;
1346 break; 1401 break;
@@ -1366,21 +1421,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1366 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1421 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1367 __Play, 2, AV_PES, 0); 1422 __Play, 2, AV_PES, 0);
1368 break; 1423 break;
1369 case AUDIO_SET_ID:
1370 1424
1425 case AUDIO_SET_ID:
1371 break; 1426 break;
1427
1372 case AUDIO_SET_MIXER: 1428 case AUDIO_SET_MIXER:
1373 { 1429 {
1374 struct audio_mixer *amix = (struct audio_mixer *)parg; 1430 struct audio_mixer *amix = (struct audio_mixer *)parg;
1375
1376 ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); 1431 ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
1377 break; 1432 break;
1378 } 1433 }
1434
1379 case AUDIO_SET_STREAMTYPE: 1435 case AUDIO_SET_STREAMTYPE:
1380 break; 1436 break;
1437
1381 default: 1438 default:
1382 ret = -ENOIOCTLCMD; 1439 ret = -ENOIOCTLCMD;
1383 } 1440 }
1441
1384 return ret; 1442 return ret;
1385} 1443}
1386 1444
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 5e3f88911a1d..e162691b515d 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -1089,7 +1089,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
1089 else { 1089 else {
1090 int i, len = dc->x0-dc->color+1; 1090 int i, len = dc->x0-dc->color+1;
1091 u8 __user *colors = (u8 __user *)dc->data; 1091 u8 __user *colors = (u8 __user *)dc->data;
1092 u8 r, g, b, blend; 1092 u8 r, g = 0, b = 0, blend = 0;
1093 ret = 0; 1093 ret = 0;
1094 for (i = 0; i<len; i++) { 1094 for (i = 0; i<len; i++) {
1095 if (get_user(r, colors + i * 4) || 1095 if (get_user(r, colors + i * 4) ||
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index 2210cff738e6..ce64c6214cc4 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -458,7 +458,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
458 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); 458 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
459 459
460 if (av7110->analog_tuner_flags) { 460 if (av7110->analog_tuner_flags) {
461 if (i->index < 0 || i->index >= 4) 461 if (i->index >= 4)
462 return -EINVAL; 462 return -EINVAL;
463 } else { 463 } else {
464 if (i->index != 0) 464 if (i->index != 0)
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 855fe74b640b..8ea915227674 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1413,7 +1413,7 @@ static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1413static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) 1413static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1414{ 1414{
1415 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); 1415 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1416 if (i->index < 0 || i->index >= KNC1_INPUTS) 1416 if (i->index >= KNC1_INPUTS)
1417 return -EINVAL; 1417 return -EINVAL;
1418 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); 1418 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1419 return 0; 1419 return 0;
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 83e9e7750c8c..e48380c48990 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -47,6 +47,9 @@
47#include "bsru6.h" 47#include "bsru6.h"
48#include "bsbe1.h" 48#include "bsbe1.h"
49#include "tdhd1.h" 49#include "tdhd1.h"
50#include "stv6110x.h"
51#include "stv090x.h"
52#include "isl6423.h"
50 53
51static int diseqc_method; 54static int diseqc_method;
52module_param(diseqc_method, int, 0444); 55module_param(diseqc_method, int, 0444);
@@ -425,6 +428,44 @@ static u8 read_pwm(struct budget* budget)
425 return pwm; 428 return pwm;
426} 429}
427 430
431static struct stv090x_config tt1600_stv090x_config = {
432 .device = STV0903,
433 .demod_mode = STV090x_SINGLE,
434 .clk_mode = STV090x_CLK_EXT,
435
436 .xtal = 27000000,
437 .address = 0x68,
438 .ref_clk = 27000000,
439
440 .ts1_mode = STV090x_TSMODE_DVBCI,
441 .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS,
442
443 .repeater_level = STV090x_RPTLEVEL_16,
444
445 .tuner_init = NULL,
446 .tuner_set_mode = NULL,
447 .tuner_set_frequency = NULL,
448 .tuner_get_frequency = NULL,
449 .tuner_set_bandwidth = NULL,
450 .tuner_get_bandwidth = NULL,
451 .tuner_set_bbgain = NULL,
452 .tuner_get_bbgain = NULL,
453 .tuner_set_refclk = NULL,
454 .tuner_get_status = NULL,
455};
456
457static struct stv6110x_config tt1600_stv6110x_config = {
458 .addr = 0x60,
459 .refclk = 27000000,
460};
461
462static struct isl6423_config tt1600_isl6423_config = {
463 .current_max = SEC_CURRENT_515m,
464 .curlim = SEC_CURRENT_LIM_ON,
465 .mod_extern = 1,
466 .addr = 0x08,
467};
468
428static void frontend_init(struct budget *budget) 469static void frontend_init(struct budget *budget)
429{ 470{
430 (void)alps_bsbe1_config; /* avoid warning */ 471 (void)alps_bsbe1_config; /* avoid warning */
@@ -566,6 +607,48 @@ static void frontend_init(struct budget *budget)
566 } 607 }
567 break; 608 break;
568 } 609 }
610
611 case 0x101c: { /* TT S2-1600 */
612 struct stv6110x_devctl *ctl;
613 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
614 msleep(50);
615 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
616 msleep(250);
617
618 budget->dvb_frontend = dvb_attach(stv090x_attach,
619 &tt1600_stv090x_config,
620 &budget->i2c_adap,
621 STV090x_DEMODULATOR_0);
622
623 if (budget->dvb_frontend) {
624
625 ctl = dvb_attach(stv6110x_attach,
626 budget->dvb_frontend,
627 &tt1600_stv6110x_config,
628 &budget->i2c_adap);
629
630 tt1600_stv090x_config.tuner_init = ctl->tuner_init;
631 tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
632 tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
633 tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
634 tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
635 tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
636 tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
637 tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
638 tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
639 tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status;
640
641 dvb_attach(isl6423_attach,
642 budget->dvb_frontend,
643 &budget->i2c_adap,
644 &tt1600_isl6423_config);
645
646 } else {
647 dvb_frontend_detach(budget->dvb_frontend);
648 budget->dvb_frontend = NULL;
649 }
650 }
651 break;
569 } 652 }
570 653
571 if (budget->dvb_frontend == NULL) { 654 if (budget->dvb_frontend == NULL) {
@@ -641,6 +724,7 @@ MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
641MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 724MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
642MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); 725MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
643MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); 726MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT);
727MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT);
644MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); 728MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
645MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); 729MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
646MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); 730MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);
@@ -653,6 +737,7 @@ static struct pci_device_id pci_tbl[] = {
653 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 737 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
654 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 738 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
655 MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), 739 MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018),
740 MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c),
656 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 741 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
657 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 742 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
658 MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), 743 MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 613576202294..ed9cd7ad0604 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -33,6 +33,10 @@
33 33
34 History: 34 History:
35 35
36 Version 0.46:
37 Removed usb_dsbr100_open/close calls and radio->users counter. Also,
38 radio->muted changed to radio->status and suspend/resume calls updated.
39
36 Version 0.45: 40 Version 0.45:
37 Converted to v4l2_device. 41 Converted to v4l2_device.
38 42
@@ -100,8 +104,8 @@
100 */ 104 */
101#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 105#include <linux/version.h> /* for KERNEL_VERSION MACRO */
102 106
103#define DRIVER_VERSION "v0.45" 107#define DRIVER_VERSION "v0.46"
104#define RADIO_VERSION KERNEL_VERSION(0, 4, 5) 108#define RADIO_VERSION KERNEL_VERSION(0, 4, 6)
105 109
106#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" 110#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
107#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" 111#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
@@ -121,13 +125,15 @@ devices, that would be 76 and 91. */
121#define FREQ_MAX 108.0 125#define FREQ_MAX 108.0
122#define FREQ_MUL 16000 126#define FREQ_MUL 16000
123 127
128/* defines for radio->status */
129#define STARTED 0
130#define STOPPED 1
131
124#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) 132#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
125 133
126static int usb_dsbr100_probe(struct usb_interface *intf, 134static int usb_dsbr100_probe(struct usb_interface *intf,
127 const struct usb_device_id *id); 135 const struct usb_device_id *id);
128static void usb_dsbr100_disconnect(struct usb_interface *intf); 136static void usb_dsbr100_disconnect(struct usb_interface *intf);
129static int usb_dsbr100_open(struct file *file);
130static int usb_dsbr100_close(struct file *file);
131static int usb_dsbr100_suspend(struct usb_interface *intf, 137static int usb_dsbr100_suspend(struct usb_interface *intf,
132 pm_message_t message); 138 pm_message_t message);
133static int usb_dsbr100_resume(struct usb_interface *intf); 139static int usb_dsbr100_resume(struct usb_interface *intf);
@@ -145,9 +151,8 @@ struct dsbr100_device {
145 struct mutex lock; /* buffer locking */ 151 struct mutex lock; /* buffer locking */
146 int curfreq; 152 int curfreq;
147 int stereo; 153 int stereo;
148 int users;
149 int removed; 154 int removed;
150 int muted; 155 int status;
151}; 156};
152 157
153static struct usb_device_id usb_dsbr100_device_table [] = { 158static struct usb_device_id usb_dsbr100_device_table [] = {
@@ -201,7 +206,7 @@ static int dsbr100_start(struct dsbr100_device *radio)
201 goto usb_control_msg_failed; 206 goto usb_control_msg_failed;
202 } 207 }
203 208
204 radio->muted = 0; 209 radio->status = STARTED;
205 mutex_unlock(&radio->lock); 210 mutex_unlock(&radio->lock);
206 return (radio->transfer_buffer)[0]; 211 return (radio->transfer_buffer)[0];
207 212
@@ -244,7 +249,7 @@ static int dsbr100_stop(struct dsbr100_device *radio)
244 goto usb_control_msg_failed; 249 goto usb_control_msg_failed;
245 } 250 }
246 251
247 radio->muted = 1; 252 radio->status = STOPPED;
248 mutex_unlock(&radio->lock); 253 mutex_unlock(&radio->lock);
249 return (radio->transfer_buffer)[0]; 254 return (radio->transfer_buffer)[0];
250 255
@@ -258,12 +263,12 @@ usb_control_msg_failed:
258} 263}
259 264
260/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 265/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
261static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) 266static int dsbr100_setfreq(struct dsbr100_device *radio)
262{ 267{
263 int retval; 268 int retval;
264 int request; 269 int request;
270 int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
265 271
266 freq = (freq / 16 * 80) / 1000 + 856;
267 mutex_lock(&radio->lock); 272 mutex_lock(&radio->lock);
268 273
269 retval = usb_control_msg(radio->usbdev, 274 retval = usb_control_msg(radio->usbdev,
@@ -431,7 +436,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
431 radio->curfreq = f->frequency; 436 radio->curfreq = f->frequency;
432 mutex_unlock(&radio->lock); 437 mutex_unlock(&radio->lock);
433 438
434 retval = dsbr100_setfreq(radio, radio->curfreq); 439 retval = dsbr100_setfreq(radio);
435 if (retval < 0) 440 if (retval < 0)
436 dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); 441 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
437 return 0; 442 return 0;
@@ -473,7 +478,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
473 478
474 switch (ctrl->id) { 479 switch (ctrl->id) {
475 case V4L2_CID_AUDIO_MUTE: 480 case V4L2_CID_AUDIO_MUTE:
476 ctrl->value = radio->muted; 481 ctrl->value = radio->status;
477 return 0; 482 return 0;
478 } 483 }
479 return -EINVAL; 484 return -EINVAL;
@@ -543,65 +548,27 @@ static int vidioc_s_audio(struct file *file, void *priv,
543 return 0; 548 return 0;
544} 549}
545 550
546static int usb_dsbr100_open(struct file *file)
547{
548 struct dsbr100_device *radio = video_drvdata(file);
549 int retval;
550
551 lock_kernel();
552 radio->users = 1;
553 radio->muted = 1;
554
555 retval = dsbr100_start(radio);
556 if (retval < 0) {
557 dev_warn(&radio->usbdev->dev,
558 "Radio did not start up properly\n");
559 radio->users = 0;
560 unlock_kernel();
561 return -EIO;
562 }
563
564 retval = dsbr100_setfreq(radio, radio->curfreq);
565 if (retval < 0)
566 dev_warn(&radio->usbdev->dev,
567 "set frequency failed\n");
568
569 unlock_kernel();
570 return 0;
571}
572
573static int usb_dsbr100_close(struct file *file)
574{
575 struct dsbr100_device *radio = video_drvdata(file);
576 int retval;
577
578 if (!radio)
579 return -ENODEV;
580
581 mutex_lock(&radio->lock);
582 radio->users = 0;
583 mutex_unlock(&radio->lock);
584
585 if (!radio->removed) {
586 retval = dsbr100_stop(radio);
587 if (retval < 0) {
588 dev_warn(&radio->usbdev->dev,
589 "dsbr100_stop failed\n");
590 }
591
592 }
593 return 0;
594}
595
596/* Suspend device - stop device. */ 551/* Suspend device - stop device. */
597static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) 552static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
598{ 553{
599 struct dsbr100_device *radio = usb_get_intfdata(intf); 554 struct dsbr100_device *radio = usb_get_intfdata(intf);
600 int retval; 555 int retval;
601 556
602 retval = dsbr100_stop(radio); 557 if (radio->status == STARTED) {
603 if (retval < 0) 558 retval = dsbr100_stop(radio);
604 dev_warn(&intf->dev, "dsbr100_stop failed\n"); 559 if (retval < 0)
560 dev_warn(&intf->dev, "dsbr100_stop failed\n");
561
562 /* After dsbr100_stop() status set to STOPPED.
563 * If we want driver to start radio on resume
564 * we set status equal to STARTED.
565 * On resume we will check status and run radio if needed.
566 */
567
568 mutex_lock(&radio->lock);
569 radio->status = STARTED;
570 mutex_unlock(&radio->lock);
571 }
605 572
606 dev_info(&intf->dev, "going into suspend..\n"); 573 dev_info(&intf->dev, "going into suspend..\n");
607 574
@@ -614,9 +581,11 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
614 struct dsbr100_device *radio = usb_get_intfdata(intf); 581 struct dsbr100_device *radio = usb_get_intfdata(intf);
615 int retval; 582 int retval;
616 583
617 retval = dsbr100_start(radio); 584 if (radio->status == STARTED) {
618 if (retval < 0) 585 retval = dsbr100_start(radio);
619 dev_warn(&intf->dev, "dsbr100_start failed\n"); 586 if (retval < 0)
587 dev_warn(&intf->dev, "dsbr100_start failed\n");
588 }
620 589
621 dev_info(&intf->dev, "coming out of suspend..\n"); 590 dev_info(&intf->dev, "coming out of suspend..\n");
622 591
@@ -636,8 +605,6 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev)
636/* File system interface */ 605/* File system interface */
637static const struct v4l2_file_operations usb_dsbr100_fops = { 606static const struct v4l2_file_operations usb_dsbr100_fops = {
638 .owner = THIS_MODULE, 607 .owner = THIS_MODULE,
639 .open = usb_dsbr100_open,
640 .release = usb_dsbr100_close,
641 .ioctl = video_ioctl2, 608 .ioctl = video_ioctl2,
642}; 609};
643 610
@@ -695,9 +662,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
695 mutex_init(&radio->lock); 662 mutex_init(&radio->lock);
696 663
697 radio->removed = 0; 664 radio->removed = 0;
698 radio->users = 0;
699 radio->usbdev = interface_to_usbdev(intf); 665 radio->usbdev = interface_to_usbdev(intf);
700 radio->curfreq = FREQ_MIN * FREQ_MUL; 666 radio->curfreq = FREQ_MIN * FREQ_MUL;
667 radio->status = STOPPED;
701 668
702 video_set_drvdata(&radio->videodev, radio); 669 video_set_drvdata(&radio->videodev, radio);
703 670
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index cab19d05e02f..837467f93805 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -64,6 +64,7 @@
64#include <media/v4l2-ioctl.h> 64#include <media/v4l2-ioctl.h>
65#include <linux/usb.h> 65#include <linux/usb.h>
66#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 66#include <linux/version.h> /* for KERNEL_VERSION MACRO */
67#include <linux/mutex.h>
67 68
68/* driver and module definitions */ 69/* driver and module definitions */
69#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>" 70#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 5cf6c45b91fe..49c4aab95dab 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -49,7 +49,6 @@ struct fmi
49 int io; 49 int io;
50 int curvol; /* 1 or 0 */ 50 int curvol; /* 1 or 0 */
51 unsigned long curfreq; /* freq in kHz */ 51 unsigned long curfreq; /* freq in kHz */
52 __u32 flags;
53 struct mutex lock; 52 struct mutex lock;
54}; 53};
55 54
@@ -57,7 +56,7 @@ static struct fmi fmi_card;
57static struct pnp_dev *dev; 56static struct pnp_dev *dev;
58 57
59/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ 58/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
60/* It is only useful to give freq in intervall of 800 (=0.05Mhz), 59/* It is only useful to give freq in interval of 800 (=0.05Mhz),
61 * other bits will be truncated, e.g 92.7400016 -> 92.7, but 60 * other bits will be truncated, e.g 92.7400016 -> 92.7, but
62 * 92.7400017 -> 92.75 61 * 92.7400017 -> 92.75
63 */ 62 */
@@ -142,7 +141,6 @@ static int vidioc_querycap(struct file *file, void *priv,
142static int vidioc_g_tuner(struct file *file, void *priv, 141static int vidioc_g_tuner(struct file *file, void *priv,
143 struct v4l2_tuner *v) 142 struct v4l2_tuner *v)
144{ 143{
145 int mult;
146 struct fmi *fmi = video_drvdata(file); 144 struct fmi *fmi = video_drvdata(file);
147 145
148 if (v->index > 0) 146 if (v->index > 0)
@@ -150,11 +148,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
150 148
151 strlcpy(v->name, "FM", sizeof(v->name)); 149 strlcpy(v->name, "FM", sizeof(v->name));
152 v->type = V4L2_TUNER_RADIO; 150 v->type = V4L2_TUNER_RADIO;
153 mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; 151 v->rangelow = RSF16_MINFREQ;
154 v->rangelow = RSF16_MINFREQ / mult; 152 v->rangehigh = RSF16_MAXFREQ;
155 v->rangehigh = RSF16_MAXFREQ / mult;
156 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 153 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
157 v->capability = fmi->flags & V4L2_TUNER_CAP_LOW; 154 v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW;
158 v->audmode = V4L2_TUNER_MODE_STEREO; 155 v->audmode = V4L2_TUNER_MODE_STEREO;
159 v->signal = fmi_getsigstr(fmi); 156 v->signal = fmi_getsigstr(fmi);
160 return 0; 157 return 0;
@@ -171,8 +168,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
171{ 168{
172 struct fmi *fmi = video_drvdata(file); 169 struct fmi *fmi = video_drvdata(file);
173 170
174 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
175 f->frequency *= 1000;
176 if (f->frequency < RSF16_MINFREQ || 171 if (f->frequency < RSF16_MINFREQ ||
177 f->frequency > RSF16_MAXFREQ) 172 f->frequency > RSF16_MAXFREQ)
178 return -EINVAL; 173 return -EINVAL;
@@ -189,8 +184,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
189 184
190 f->type = V4L2_TUNER_RADIO; 185 f->type = V4L2_TUNER_RADIO;
191 f->frequency = fmi->curfreq; 186 f->frequency = fmi->curfreq;
192 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
193 f->frequency /= 1000;
194 return 0; 187 return 0;
195} 188}
196 189
@@ -347,7 +340,6 @@ static int __init fmi_init(void)
347 return res; 340 return res;
348 } 341 }
349 342
350 fmi->flags = V4L2_TUNER_CAP_LOW;
351 strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name)); 343 strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
352 fmi->vdev.v4l2_dev = v4l2_dev; 344 fmi->vdev.v4l2_dev = v4l2_dev;
353 fmi->vdev.fops = &fmi_fops; 345 fmi->vdev.fops = &fmi_fops;
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 935ff9bcdfcc..a11414f648d4 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -61,13 +61,12 @@ struct fmr2
61 int stereo; /* card is producing stereo audio */ 61 int stereo; /* card is producing stereo audio */
62 unsigned long curfreq; /* freq in kHz */ 62 unsigned long curfreq; /* freq in kHz */
63 int card_type; 63 int card_type;
64 u32 flags;
65}; 64};
66 65
67static struct fmr2 fmr2_card; 66static struct fmr2 fmr2_card;
68 67
69/* hw precision is 12.5 kHz 68/* hw precision is 12.5 kHz
70 * It is only useful to give freq in intervall of 200 (=0.0125Mhz), 69 * It is only useful to give freq in interval of 200 (=0.0125Mhz),
71 * other bits will be truncated 70 * other bits will be truncated
72 */ 71 */
73#define RSF16_ENCODE(x) ((x) / 200 + 856) 72#define RSF16_ENCODE(x) ((x) / 200 + 856)
@@ -221,7 +220,6 @@ static int vidioc_querycap(struct file *file, void *priv,
221static int vidioc_g_tuner(struct file *file, void *priv, 220static int vidioc_g_tuner(struct file *file, void *priv,
222 struct v4l2_tuner *v) 221 struct v4l2_tuner *v)
223{ 222{
224 int mult;
225 struct fmr2 *fmr2 = video_drvdata(file); 223 struct fmr2 *fmr2 = video_drvdata(file);
226 224
227 if (v->index > 0) 225 if (v->index > 0)
@@ -230,13 +228,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
230 strlcpy(v->name, "FM", sizeof(v->name)); 228 strlcpy(v->name, "FM", sizeof(v->name));
231 v->type = V4L2_TUNER_RADIO; 229 v->type = V4L2_TUNER_RADIO;
232 230
233 mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; 231 v->rangelow = RSF16_MINFREQ;
234 v->rangelow = RSF16_MINFREQ / mult; 232 v->rangehigh = RSF16_MAXFREQ;
235 v->rangehigh = RSF16_MAXFREQ / mult; 233 v->rxsubchans = fmr2->stereo ? V4L2_TUNER_SUB_STEREO :
236 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 234 V4L2_TUNER_SUB_MONO;
237 v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW; 235 v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW;
238 v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO: 236 v->audmode = V4L2_TUNER_MODE_STEREO;
239 V4L2_TUNER_MODE_MONO;
240 mutex_lock(&fmr2->lock); 237 mutex_lock(&fmr2->lock);
241 v->signal = fmr2_getsigstr(fmr2); 238 v->signal = fmr2_getsigstr(fmr2);
242 mutex_unlock(&fmr2->lock); 239 mutex_unlock(&fmr2->lock);
@@ -254,8 +251,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
254{ 251{
255 struct fmr2 *fmr2 = video_drvdata(file); 252 struct fmr2 *fmr2 = video_drvdata(file);
256 253
257 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
258 f->frequency *= 1000;
259 if (f->frequency < RSF16_MINFREQ || 254 if (f->frequency < RSF16_MINFREQ ||
260 f->frequency > RSF16_MAXFREQ) 255 f->frequency > RSF16_MAXFREQ)
261 return -EINVAL; 256 return -EINVAL;
@@ -279,8 +274,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
279 274
280 f->type = V4L2_TUNER_RADIO; 275 f->type = V4L2_TUNER_RADIO;
281 f->frequency = fmr2->curfreq; 276 f->frequency = fmr2->curfreq;
282 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
283 f->frequency /= 1000;
284 return 0; 277 return 0;
285} 278}
286 279
@@ -406,7 +399,6 @@ static int __init fmr2_init(void)
406 strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name)); 399 strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name));
407 fmr2->io = io; 400 fmr2->io = io;
408 fmr2->stereo = 1; 401 fmr2->stereo = 1;
409 fmr2->flags = V4L2_TUNER_CAP_LOW;
410 mutex_init(&fmr2->lock); 402 mutex_init(&fmr2->lock);
411 403
412 if (!request_region(fmr2->io, 2, "sf16fmr2")) { 404 if (!request_region(fmr2->io, 2, "sf16fmr2")) {
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index bd945d04dc90..640421ceb24a 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1214,7 +1214,6 @@ static int si470x_fops_release(struct file *file)
1214 usb_autopm_put_interface(radio->intf); 1214 usb_autopm_put_interface(radio->intf);
1215 } 1215 }
1216 1216
1217unlock:
1218 mutex_unlock(&radio->disconnect_lock); 1217 mutex_unlock(&radio->disconnect_lock);
1219 1218
1220done: 1219done:
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 57835f5715fc..94f440535c64 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -440,6 +440,24 @@ config VIDEO_ADV7175
440 To compile this driver as a module, choose M here: the 440 To compile this driver as a module, choose M here: the
441 module will be called adv7175. 441 module will be called adv7175.
442 442
443config VIDEO_THS7303
444 tristate "THS7303 Video Amplifier"
445 depends on I2C
446 help
447 Support for TI THS7303 video amplifier
448
449 To compile this driver as a module, choose M here: the
450 module will be called ths7303.
451
452config VIDEO_ADV7343
453 tristate "ADV7343 video encoder"
454 depends on I2C
455 help
456 Support for Analog Devices I2C bus based ADV7343 encoder.
457
458 To compile this driver as a module, choose M here: the
459 module will be called adv7343.
460
443comment "Video improvement chips" 461comment "Video improvement chips"
444 462
445config VIDEO_UPD64031A 463config VIDEO_UPD64031A
@@ -694,7 +712,7 @@ config VIDEO_CAFE_CCIC
694 712
695config SOC_CAMERA 713config SOC_CAMERA
696 tristate "SoC camera support" 714 tristate "SoC camera support"
697 depends on VIDEO_V4L2 && HAS_DMA 715 depends on VIDEO_V4L2 && HAS_DMA && I2C
698 select VIDEOBUF_GEN 716 select VIDEOBUF_GEN
699 help 717 help
700 SoC Camera is a common API to several cameras, not connecting 718 SoC Camera is a common API to several cameras, not connecting
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3f1a0350a569..7fb3add1b387 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -12,6 +12,8 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
12 12
13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o 13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o
14 14
15# V4L2 core modules
16
15obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o 17obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
16ifeq ($(CONFIG_COMPAT),y) 18ifeq ($(CONFIG_COMPAT),y)
17 obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o 19 obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o
@@ -23,21 +25,15 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
23 obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o 25 obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
24endif 26endif
25 27
26obj-$(CONFIG_VIDEO_TUNER) += tuner.o 28# All i2c modules must come first:
27 29
28obj-$(CONFIG_VIDEO_BT848) += bt8xx/ 30obj-$(CONFIG_VIDEO_TUNER) += tuner.o
29obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
30obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o 31obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
31obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o 32obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
32obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o 33obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
33
34obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o 34obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
35obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 35obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
36obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o 36obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
37obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
38obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
39obj-$(CONFIG_VIDEO_W9966) += w9966.o
40
41obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o 37obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
42obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o 38obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
43obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o 39obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
@@ -49,16 +45,47 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
49obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o 45obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
50obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o 46obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
51obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o 47obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
48obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
52obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o 49obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
53obj-$(CONFIG_VIDEO_BT819) += bt819.o 50obj-$(CONFIG_VIDEO_BT819) += bt819.o
54obj-$(CONFIG_VIDEO_BT856) += bt856.o 51obj-$(CONFIG_VIDEO_BT856) += bt856.o
55obj-$(CONFIG_VIDEO_BT866) += bt866.o 52obj-$(CONFIG_VIDEO_BT866) += bt866.o
56obj-$(CONFIG_VIDEO_KS0127) += ks0127.o 53obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
54obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
55obj-$(CONFIG_VIDEO_VINO) += indycam.o
56obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
57obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
58obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
59obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
60obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
61obj-$(CONFIG_VIDEO_M52790) += m52790.o
62obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
63obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
64obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
65obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
66obj-$(CONFIG_VIDEO_CX25840) += cx25840/
67obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
68obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
69obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
70obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
71obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
57 72
58obj-$(CONFIG_VIDEO_ZORAN) += zoran/ 73obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
74obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
75obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
76obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
77obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
78obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
59 79
80# And now the v4l2 drivers:
81
82obj-$(CONFIG_VIDEO_BT848) += bt8xx/
83obj-$(CONFIG_VIDEO_ZORAN) += zoran/
84obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
85obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
86obj-$(CONFIG_VIDEO_W9966) += w9966.o
60obj-$(CONFIG_VIDEO_PMS) += pms.o 87obj-$(CONFIG_VIDEO_PMS) += pms.o
61obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o 88obj-$(CONFIG_VIDEO_VINO) += vino.o
62obj-$(CONFIG_VIDEO_STRADIS) += stradis.o 89obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
63obj-$(CONFIG_VIDEO_CPIA) += cpia.o 90obj-$(CONFIG_VIDEO_CPIA) += cpia.o
64obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o 91obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
@@ -69,17 +96,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
69obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 96obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
70obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ 97obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
71obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 98obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
72obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
73obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
74obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 99obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
75obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
76obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
77obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
78obj-$(CONFIG_VIDEO_M52790) += m52790.o
79obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
80obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
81obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
82obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
83obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ 100obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
84obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ 101obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
85obj-$(CONFIG_VIDEO_MXB) += mxb.o 102obj-$(CONFIG_VIDEO_MXB) += mxb.o
@@ -92,19 +109,12 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
92obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o 109obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
93obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o 110obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
94obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o 111obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
95obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
96 112
97obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o 113obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
98 114
99obj-$(CONFIG_VIDEO_CX25840) += cx25840/
100obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
101obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
102obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o 115obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
103 116
104obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o 117obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
105obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
106
107obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
108 118
109obj-$(CONFIG_USB_DABUSB) += dabusb.o 119obj-$(CONFIG_USB_DABUSB) += dabusb.o
110obj-$(CONFIG_USB_OV511) += ov511.o 120obj-$(CONFIG_USB_OV511) += ov511.o
@@ -134,24 +144,21 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
134obj-$(CONFIG_VIDEO_VIVI) += vivi.o 144obj-$(CONFIG_VIDEO_VIVI) += vivi.o
135obj-$(CONFIG_VIDEO_CX23885) += cx23885/ 145obj-$(CONFIG_VIDEO_CX23885) += cx23885/
136 146
147obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
148obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
149obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
150# soc-camera host drivers have to be linked after camera drivers
137obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o 151obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
138obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o 152obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
139obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 153obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
140obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 154obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
141obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
142obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
143obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
144obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
145obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
146obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
147obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
148obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
149obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
150 155
151obj-$(CONFIG_VIDEO_AU0828) += au0828/ 156obj-$(CONFIG_VIDEO_AU0828) += au0828/
152 157
153obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ 158obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
154 159
160obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
161
155EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 162EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
156EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 163EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
157EXTRA_CFLAGS += -Idrivers/media/common/tuners 164EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
new file mode 100644
index 000000000000..30f5caf5dda5
--- /dev/null
+++ b/drivers/media/video/adv7343.c
@@ -0,0 +1,534 @@
1/*
2 * adv7343 - ADV7343 Video Encoder Driver
3 *
4 * The encoder hardware does not support SECAM.
5 *
6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation version 2.
11 *
12 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/ctype.h>
21#include <linux/i2c.h>
22#include <linux/device.h>
23#include <linux/delay.h>
24#include <linux/module.h>
25#include <linux/videodev2.h>
26#include <linux/uaccess.h>
27#include <linux/version.h>
28
29#include <media/adv7343.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-chip-ident.h>
32
33#include "adv7343_regs.h"
34
35MODULE_DESCRIPTION("ADV7343 video encoder driver");
36MODULE_LICENSE("GPL");
37
38static int debug;
39module_param(debug, int, 0644);
40MODULE_PARM_DESC(debug, "Debug level 0-1");
41
42struct adv7343_state {
43 struct v4l2_subdev sd;
44 u8 reg00;
45 u8 reg01;
46 u8 reg02;
47 u8 reg35;
48 u8 reg80;
49 u8 reg82;
50 int bright;
51 int hue;
52 int gain;
53 u32 output;
54 v4l2_std_id std;
55};
56
57static inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
58{
59 return container_of(sd, struct adv7343_state, sd);
60}
61
62static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
63{
64 struct i2c_client *client = v4l2_get_subdevdata(sd);
65
66 return i2c_smbus_write_byte_data(client, reg, value);
67}
68
69static const u8 adv7343_init_reg_val[] = {
70 ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT,
71 ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT,
72
73 ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT,
74 ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT,
75 ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT,
76 ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT,
77 ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT,
78 ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT,
79 ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT,
80
81 ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT,
82 ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT,
83 ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT,
84 ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT,
85 ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT,
86 ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT,
87 ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT,
88 ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT,
89
90 ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT,
91 ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT,
92 ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT,
93};
94
95/*
96 * 2^32
97 * FSC(reg) = FSC (HZ) * --------
98 * 27000000
99 */
100static const struct adv7343_std_info stdinfo[] = {
101 {
102 /* FSC(Hz) = 3,579,545.45 Hz */
103 SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
104 }, {
105 /* FSC(Hz) = 3,575,611.00 Hz */
106 SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
107 }, {
108 /* FSC(Hz) = 3,582,056.00 */
109 SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
110 }, {
111 /* FSC(Hz) = 4,433,618.75 Hz */
112 SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
113 }, {
114 /* FSC(Hz) = 4,433,618.75 Hz */
115 SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
116 }, {
117 /* FSC(Hz) = 4,433,618.75 Hz */
118 SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
119 }, {
120 /* FSC(Hz) = 4,433,618.75 Hz */
121 SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
122 },
123};
124
125static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
126{
127 struct adv7343_state *state = to_state(sd);
128 struct adv7343_std_info *std_info;
129 int output_idx, num_std;
130 char *fsc_ptr;
131 u8 reg, val;
132 int err = 0;
133 int i = 0;
134
135 output_idx = state->output;
136
137 std_info = (struct adv7343_std_info *)stdinfo;
138 num_std = ARRAY_SIZE(stdinfo);
139
140 for (i = 0; i < num_std; i++) {
141 if (std_info[i].stdid & std)
142 break;
143 }
144
145 if (i == num_std) {
146 v4l2_dbg(1, debug, sd,
147 "Invalid std or std is not supported: %llx\n",
148 (unsigned long long)std);
149 return -EINVAL;
150 }
151
152 /* Set the standard */
153 val = state->reg80 & (~(SD_STD_MASK));
154 val |= std_info[i].standard_val3;
155 err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
156 if (err < 0)
157 goto setstd_exit;
158
159 state->reg80 = val;
160
161 /* Configure the input mode register */
162 val = state->reg01 & (~((u8) INPUT_MODE_MASK));
163 val |= SD_INPUT_MODE;
164 err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val);
165 if (err < 0)
166 goto setstd_exit;
167
168 state->reg01 = val;
169
170 /* Program the sub carrier frequency registers */
171 fsc_ptr = (unsigned char *)&std_info[i].fsc_val;
172 reg = ADV7343_FSC_REG0;
173 for (i = 0; i < 4; i++, reg++, fsc_ptr++) {
174 err = adv7343_write(sd, reg, *fsc_ptr);
175 if (err < 0)
176 goto setstd_exit;
177 }
178
179 val = state->reg80;
180
181 /* Filter settings */
182 if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
183 val &= 0x03;
184 else if (std & ~V4L2_STD_SECAM)
185 val |= 0x04;
186
187 err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
188 if (err < 0)
189 goto setstd_exit;
190
191 state->reg80 = val;
192
193setstd_exit:
194 if (err != 0)
195 v4l2_err(sd, "Error setting std, write failed\n");
196
197 return err;
198}
199
200static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
201{
202 struct adv7343_state *state = to_state(sd);
203 unsigned char val;
204 int err = 0;
205
206 if (output_type > ADV7343_SVIDEO_ID) {
207 v4l2_dbg(1, debug, sd,
208 "Invalid output type or output type not supported:%d\n",
209 output_type);
210 return -EINVAL;
211 }
212
213 /* Enable Appropriate DAC */
214 val = state->reg00 & 0x03;
215
216 if (output_type == ADV7343_COMPOSITE_ID)
217 val |= ADV7343_COMPOSITE_POWER_VALUE;
218 else if (output_type == ADV7343_COMPONENT_ID)
219 val |= ADV7343_COMPONENT_POWER_VALUE;
220 else
221 val |= ADV7343_SVIDEO_POWER_VALUE;
222
223 err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val);
224 if (err < 0)
225 goto setoutput_exit;
226
227 state->reg00 = val;
228
229 /* Enable YUV output */
230 val = state->reg02 | YUV_OUTPUT_SELECT;
231 err = adv7343_write(sd, ADV7343_MODE_REG0, val);
232 if (err < 0)
233 goto setoutput_exit;
234
235 state->reg02 = val;
236
237 /* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */
238 val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI);
239 err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val);
240 if (err < 0)
241 goto setoutput_exit;
242
243 state->reg82 = val;
244
245 /* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to
246 * zero */
247 val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI);
248 err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val);
249 if (err < 0)
250 goto setoutput_exit;
251
252 state->reg35 = val;
253
254setoutput_exit:
255 if (err != 0)
256 v4l2_err(sd, "Error setting output, write failed\n");
257
258 return err;
259}
260
261static int adv7343_log_status(struct v4l2_subdev *sd)
262{
263 struct adv7343_state *state = to_state(sd);
264
265 v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
266 v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
267 ((state->output == 1) ? "Component" : "S-Video"));
268 return 0;
269}
270
271static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
272{
273 switch (qc->id) {
274 case V4L2_CID_BRIGHTNESS:
275 return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN,
276 ADV7343_BRIGHTNESS_MAX, 1,
277 ADV7343_BRIGHTNESS_DEF);
278 case V4L2_CID_HUE:
279 return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN,
280 ADV7343_HUE_MAX, 1 ,
281 ADV7343_HUE_DEF);
282 case V4L2_CID_GAIN:
283 return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN,
284 ADV7343_GAIN_MAX, 1,
285 ADV7343_GAIN_DEF);
286 default:
287 break;
288 }
289
290 return 0;
291}
292
293static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
294{
295 struct adv7343_state *state = to_state(sd);
296 int err = 0;
297
298 switch (ctrl->id) {
299 case V4L2_CID_BRIGHTNESS:
300 if (ctrl->value < ADV7343_BRIGHTNESS_MIN ||
301 ctrl->value > ADV7343_BRIGHTNESS_MAX) {
302 v4l2_dbg(1, debug, sd,
303 "invalid brightness settings %d\n",
304 ctrl->value);
305 return -ERANGE;
306 }
307
308 state->bright = ctrl->value;
309 err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
310 state->bright);
311 break;
312
313 case V4L2_CID_HUE:
314 if (ctrl->value < ADV7343_HUE_MIN ||
315 ctrl->value > ADV7343_HUE_MAX) {
316 v4l2_dbg(1, debug, sd, "invalid hue settings %d\n",
317 ctrl->value);
318 return -ERANGE;
319 }
320
321 state->hue = ctrl->value;
322 err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue);
323 break;
324
325 case V4L2_CID_GAIN:
326 if (ctrl->value < ADV7343_GAIN_MIN ||
327 ctrl->value > ADV7343_GAIN_MAX) {
328 v4l2_dbg(1, debug, sd, "invalid gain settings %d\n",
329 ctrl->value);
330 return -ERANGE;
331 }
332
333 if ((ctrl->value > POSITIVE_GAIN_MAX) &&
334 (ctrl->value < NEGATIVE_GAIN_MIN)) {
335 v4l2_dbg(1, debug, sd,
336 "gain settings not within the specified range\n");
337 return -ERANGE;
338 }
339
340 state->gain = ctrl->value;
341 err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain);
342 break;
343
344 default:
345 return -EINVAL;
346 }
347
348 if (err < 0)
349 v4l2_err(sd, "Failed to set the encoder controls\n");
350
351 return err;
352}
353
354static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
355{
356 struct adv7343_state *state = to_state(sd);
357
358 switch (ctrl->id) {
359 case V4L2_CID_BRIGHTNESS:
360 ctrl->value = state->bright;
361 break;
362
363 case V4L2_CID_HUE:
364 ctrl->value = state->hue;
365 break;
366
367 case V4L2_CID_GAIN:
368 ctrl->value = state->gain;
369 break;
370
371 default:
372 return -EINVAL;
373 }
374
375 return 0;
376}
377
378static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
379 struct v4l2_dbg_chip_ident *chip)
380{
381 struct i2c_client *client = v4l2_get_subdevdata(sd);
382
383 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
384}
385
386static const struct v4l2_subdev_core_ops adv7343_core_ops = {
387 .log_status = adv7343_log_status,
388 .g_chip_ident = adv7343_g_chip_ident,
389 .g_ctrl = adv7343_g_ctrl,
390 .s_ctrl = adv7343_s_ctrl,
391 .queryctrl = adv7343_queryctrl,
392};
393
394static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
395{
396 struct adv7343_state *state = to_state(sd);
397 int err = 0;
398
399 if (state->std == std)
400 return 0;
401
402 err = adv7343_setstd(sd, std);
403 if (!err)
404 state->std = std;
405
406 return err;
407}
408
409static int adv7343_s_routing(struct v4l2_subdev *sd,
410 u32 input, u32 output, u32 config)
411{
412 struct adv7343_state *state = to_state(sd);
413 int err = 0;
414
415 if (state->output == output)
416 return 0;
417
418 err = adv7343_setoutput(sd, output);
419 if (!err)
420 state->output = output;
421
422 return err;
423}
424
425static const struct v4l2_subdev_video_ops adv7343_video_ops = {
426 .s_std_output = adv7343_s_std_output,
427 .s_routing = adv7343_s_routing,
428};
429
430static const struct v4l2_subdev_ops adv7343_ops = {
431 .core = &adv7343_core_ops,
432 .video = &adv7343_video_ops,
433};
434
435static int adv7343_initialize(struct v4l2_subdev *sd)
436{
437 struct adv7343_state *state = to_state(sd);
438 int err = 0;
439 int i;
440
441 for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) {
442
443 err = adv7343_write(sd, adv7343_init_reg_val[i],
444 adv7343_init_reg_val[i+1]);
445 if (err) {
446 v4l2_err(sd, "Error initializing\n");
447 return err;
448 }
449 }
450
451 /* Configure for default video standard */
452 err = adv7343_setoutput(sd, state->output);
453 if (err < 0) {
454 v4l2_err(sd, "Error setting output during init\n");
455 return -EINVAL;
456 }
457
458 err = adv7343_setstd(sd, state->std);
459 if (err < 0) {
460 v4l2_err(sd, "Error setting std during init\n");
461 return -EINVAL;
462 }
463
464 return err;
465}
466
467static int adv7343_probe(struct i2c_client *client,
468 const struct i2c_device_id *id)
469{
470 struct adv7343_state *state;
471
472 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
473 return -ENODEV;
474
475 v4l_info(client, "chip found @ 0x%x (%s)\n",
476 client->addr << 1, client->adapter->name);
477
478 state = kzalloc(sizeof(struct adv7343_state), GFP_KERNEL);
479 if (state == NULL)
480 return -ENOMEM;
481
482 state->reg00 = 0x80;
483 state->reg01 = 0x00;
484 state->reg02 = 0x20;
485 state->reg35 = 0x00;
486 state->reg80 = ADV7343_SD_MODE_REG1_DEFAULT;
487 state->reg82 = ADV7343_SD_MODE_REG2_DEFAULT;
488
489 state->output = ADV7343_COMPOSITE_ID;
490 state->std = V4L2_STD_NTSC;
491
492 v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
493 return adv7343_initialize(&state->sd);
494}
495
496static int adv7343_remove(struct i2c_client *client)
497{
498 struct v4l2_subdev *sd = i2c_get_clientdata(client);
499
500 v4l2_device_unregister_subdev(sd);
501 kfree(to_state(sd));
502
503 return 0;
504}
505
506static const struct i2c_device_id adv7343_id[] = {
507 {"adv7343", 0},
508 {},
509};
510
511MODULE_DEVICE_TABLE(i2c, adv7343_id);
512
513static struct i2c_driver adv7343_driver = {
514 .driver = {
515 .owner = THIS_MODULE,
516 .name = "adv7343",
517 },
518 .probe = adv7343_probe,
519 .remove = adv7343_remove,
520 .id_table = adv7343_id,
521};
522
523static __init int init_adv7343(void)
524{
525 return i2c_add_driver(&adv7343_driver);
526}
527
528static __exit void exit_adv7343(void)
529{
530 i2c_del_driver(&adv7343_driver);
531}
532
533module_init(init_adv7343);
534module_exit(exit_adv7343);
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h
new file mode 100644
index 000000000000..3431045b33da
--- /dev/null
+++ b/drivers/media/video/adv7343_regs.h
@@ -0,0 +1,185 @@
1/*
2 * ADV7343 encoder related structure and register definitions
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
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 as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef ADV7343_REG_H
17#define ADV7343_REGS_H
18
19struct adv7343_std_info {
20 u32 standard_val3;
21 u32 fsc_val;
22 v4l2_std_id stdid;
23};
24
25/* Register offset macros */
26#define ADV7343_POWER_MODE_REG (0x00)
27#define ADV7343_MODE_SELECT_REG (0x01)
28#define ADV7343_MODE_REG0 (0x02)
29
30#define ADV7343_DAC2_OUTPUT_LEVEL (0x0b)
31
32#define ADV7343_SOFT_RESET (0x17)
33
34#define ADV7343_HD_MODE_REG1 (0x30)
35#define ADV7343_HD_MODE_REG2 (0x31)
36#define ADV7343_HD_MODE_REG3 (0x32)
37#define ADV7343_HD_MODE_REG4 (0x33)
38#define ADV7343_HD_MODE_REG5 (0x34)
39#define ADV7343_HD_MODE_REG6 (0x35)
40
41#define ADV7343_HD_MODE_REG7 (0x39)
42
43#define ADV7343_SD_MODE_REG1 (0x80)
44#define ADV7343_SD_MODE_REG2 (0x82)
45#define ADV7343_SD_MODE_REG3 (0x83)
46#define ADV7343_SD_MODE_REG4 (0x84)
47#define ADV7343_SD_MODE_REG5 (0x86)
48#define ADV7343_SD_MODE_REG6 (0x87)
49#define ADV7343_SD_MODE_REG7 (0x88)
50#define ADV7343_SD_MODE_REG8 (0x89)
51
52#define ADV7343_FSC_REG0 (0x8C)
53#define ADV7343_FSC_REG1 (0x8D)
54#define ADV7343_FSC_REG2 (0x8E)
55#define ADV7343_FSC_REG3 (0x8F)
56
57#define ADV7343_SD_CGMS_WSS0 (0x99)
58
59#define ADV7343_SD_HUE_REG (0xA0)
60#define ADV7343_SD_BRIGHTNESS_WSS (0xA1)
61
62/* Default values for the registers */
63#define ADV7343_POWER_MODE_REG_DEFAULT (0x10)
64#define ADV7343_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default
65 720p EAVSAV code*/
66#define ADV7343_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data
67 valid */
68#define ADV7343_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */
69#define ADV7343_HD_MODE_REG4_DEFAULT (0xE8) /* Changed */
70#define ADV7343_HD_MODE_REG5_DEFAULT (0x08)
71#define ADV7343_HD_MODE_REG6_DEFAULT (0x00)
72#define ADV7343_HD_MODE_REG7_DEFAULT (0x00)
73#define ADV7343_SD_MODE_REG8_DEFAULT (0x00)
74#define ADV7343_SOFT_RESET_DEFAULT (0x02)
75#define ADV7343_COMPOSITE_POWER_VALUE (0x80)
76#define ADV7343_COMPONENT_POWER_VALUE (0x1C)
77#define ADV7343_SVIDEO_POWER_VALUE (0x60)
78#define ADV7343_SD_HUE_REG_DEFAULT (127)
79#define ADV7343_SD_BRIGHTNESS_WSS_DEFAULT (0x03)
80
81#define ADV7343_SD_CGMS_WSS0_DEFAULT (0x10)
82
83#define ADV7343_SD_MODE_REG1_DEFAULT (0x00)
84#define ADV7343_SD_MODE_REG2_DEFAULT (0xC9)
85#define ADV7343_SD_MODE_REG3_DEFAULT (0x10)
86#define ADV7343_SD_MODE_REG4_DEFAULT (0x01)
87#define ADV7343_SD_MODE_REG5_DEFAULT (0x02)
88#define ADV7343_SD_MODE_REG6_DEFAULT (0x0C)
89#define ADV7343_SD_MODE_REG7_DEFAULT (0x04)
90#define ADV7343_SD_MODE_REG8_DEFAULT (0x00)
91
92/* Bit masks for Mode Select Register */
93#define INPUT_MODE_MASK (0x70)
94#define SD_INPUT_MODE (0x00)
95#define HD_720P_INPUT_MODE (0x10)
96#define HD_1080I_INPUT_MODE (0x10)
97
98/* Bit masks for Mode Register 0 */
99#define TEST_PATTERN_BLACK_BAR_EN (0x04)
100#define YUV_OUTPUT_SELECT (0x20)
101#define RGB_OUTPUT_SELECT (0xDF)
102
103/* Bit masks for DAC output levels */
104#define DAC_OUTPUT_LEVEL_MASK (0xFF)
105#define POSITIVE_GAIN_MAX (0x40)
106#define POSITIVE_GAIN_MIN (0x00)
107#define NEGATIVE_GAIN_MAX (0xFF)
108#define NEGATIVE_GAIN_MIN (0xC0)
109
110/* Bit masks for soft reset register */
111#define SOFT_RESET (0x02)
112
113/* Bit masks for HD Mode Register 1 */
114#define OUTPUT_STD_MASK (0x03)
115#define OUTPUT_STD_SHIFT (0)
116#define OUTPUT_STD_EIA0_2 (0x00)
117#define OUTPUT_STD_EIA0_1 (0x01)
118#define OUTPUT_STD_FULL (0x02)
119#define EMBEDDED_SYNC (0x04)
120#define EXTERNAL_SYNC (0xFB)
121#define STD_MODE_SHIFT (3)
122#define STD_MODE_MASK (0x1F)
123#define STD_MODE_720P (0x05)
124#define STD_MODE_720P_25 (0x08)
125#define STD_MODE_720P_30 (0x07)
126#define STD_MODE_720P_50 (0x06)
127#define STD_MODE_1080I (0x0D)
128#define STD_MODE_1080I_25fps (0x0E)
129#define STD_MODE_1080P_24 (0x12)
130#define STD_MODE_1080P_25 (0x10)
131#define STD_MODE_1080P_30 (0x0F)
132#define STD_MODE_525P (0x00)
133#define STD_MODE_625P (0x03)
134
135/* Bit masks for SD Mode Register 1 */
136#define SD_STD_MASK (0x03)
137#define SD_STD_NTSC (0x00)
138#define SD_STD_PAL_BDGHI (0x01)
139#define SD_STD_PAL_M (0x02)
140#define SD_STD_PAL_N (0x03)
141#define SD_LUMA_FLTR_MASK (0x7)
142#define SD_LUMA_FLTR_SHIFT (0x2)
143#define SD_CHROMA_FLTR_MASK (0x7)
144#define SD_CHROMA_FLTR_SHIFT (0x5)
145
146/* Bit masks for SD Mode Register 2 */
147#define SD_PBPR_SSAF_EN (0x01)
148#define SD_PBPR_SSAF_DI (0xFE)
149#define SD_DAC_1_DI (0xFD)
150#define SD_DAC_2_DI (0xFB)
151#define SD_PEDESTAL_EN (0x08)
152#define SD_PEDESTAL_DI (0xF7)
153#define SD_SQUARE_PIXEL_EN (0x10)
154#define SD_SQUARE_PIXEL_DI (0xEF)
155#define SD_PIXEL_DATA_VALID (0x40)
156#define SD_ACTIVE_EDGE_EN (0x80)
157#define SD_ACTIVE_EDGE_DI (0x7F)
158
159/* Bit masks for HD Mode Register 6 */
160#define HD_RGB_INPUT_EN (0x02)
161#define HD_RGB_INPUT_DI (0xFD)
162#define HD_PBPR_SYNC_EN (0x04)
163#define HD_PBPR_SYNC_DI (0xFB)
164#define HD_DAC_SWAP_EN (0x08)
165#define HD_DAC_SWAP_DI (0xF7)
166#define HD_GAMMA_CURVE_A (0xEF)
167#define HD_GAMMA_CURVE_B (0x10)
168#define HD_GAMMA_EN (0x20)
169#define HD_GAMMA_DI (0xDF)
170#define HD_ADPT_FLTR_MODEB (0x40)
171#define HD_ADPT_FLTR_MODEA (0xBF)
172#define HD_ADPT_FLTR_EN (0x80)
173#define HD_ADPT_FLTR_DI (0x7F)
174
175#define ADV7343_BRIGHTNESS_MAX (127)
176#define ADV7343_BRIGHTNESS_MIN (0)
177#define ADV7343_BRIGHTNESS_DEF (3)
178#define ADV7343_HUE_MAX (255)
179#define ADV7343_HUE_MIN (0)
180#define ADV7343_HUE_DEF (127)
181#define ADV7343_GAIN_MAX (255)
182#define ADV7343_GAIN_MIN (0)
183#define ADV7343_GAIN_DEF (0)
184
185#endif
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 053bbe8c8e3a..830c4a933f63 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -136,9 +136,9 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
136 /* Tuner Reset Command from xc5000 */ 136 /* Tuner Reset Command from xc5000 */
137 /* Drive the tuner into reset and out */ 137 /* Drive the tuner into reset and out */
138 au0828_clear(dev, REG_001, 2); 138 au0828_clear(dev, REG_001, 2);
139 mdelay(200); 139 mdelay(10);
140 au0828_set(dev, REG_001, 2); 140 au0828_set(dev, REG_001, 2);
141 mdelay(50); 141 mdelay(10);
142 return 0; 142 return 0;
143 } else { 143 } else {
144 printk(KERN_ERR 144 printk(KERN_ERR
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index a1e4c0d769a6..3544a2f12f13 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -36,6 +36,11 @@ int au0828_debug;
36module_param_named(debug, au0828_debug, int, 0644); 36module_param_named(debug, au0828_debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debug messages"); 37MODULE_PARM_DESC(debug, "enable debug messages");
38 38
39static unsigned int disable_usb_speed_check;
40module_param(disable_usb_speed_check, int, 0444);
41MODULE_PARM_DESC(disable_usb_speed_check,
42 "override min bandwidth requirement of 480M bps");
43
39#define _AU0828_BULKPIPE 0x03 44#define _AU0828_BULKPIPE 0x03
40#define _BULKPIPESIZE 0xffff 45#define _BULKPIPESIZE 0xffff
41 46
@@ -181,6 +186,18 @@ static int au0828_usb_probe(struct usb_interface *interface,
181 le16_to_cpu(usbdev->descriptor.idProduct), 186 le16_to_cpu(usbdev->descriptor.idProduct),
182 ifnum); 187 ifnum);
183 188
189 /*
190 * Make sure we have 480 Mbps of bandwidth, otherwise things like
191 * video stream wouldn't likely work, since 12 Mbps is generally
192 * not enough even for most Digital TV streams.
193 */
194 if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
195 printk(KERN_ERR "au0828: Device initialization failed.\n");
196 printk(KERN_ERR "au0828: Device must be connected to a "
197 "high-speed USB 2.0 port.\n");
198 return -ENODEV;
199 }
200
184 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 201 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
185 if (dev == NULL) { 202 if (dev == NULL) {
186 printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); 203 printk(KERN_ERR "%s() Unable to allocate memory\n", __func__);
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 27bedc6c7791..51527d7b55a7 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -829,6 +829,9 @@ static int au0828_v4l2_close(struct file *filp)
829 829
830 au0828_uninit_isoc(dev); 830 au0828_uninit_isoc(dev);
831 831
832 /* Save some power by putting tuner to sleep */
833 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
834
832 /* When close the device, set the usb intf0 into alt0 to free 835 /* When close the device, set the usb intf0 into alt0 to free
833 USB bandwidth */ 836 USB bandwidth */
834 ret = usb_set_interface(dev->usbdev, 0, 0); 837 ret = usb_set_interface(dev->usbdev, 0, 0);
@@ -910,11 +913,6 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
910 913
911 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); 914 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
912 915
913 dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
914 (unsigned long)vma->vm_start,
915 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
916 rc);
917
918 return rc; 916 return rc;
919} 917}
920 918
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 23b7499b3185..5eb1464af670 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3152,6 +3152,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
3152 struct bttv_fh *fh = file->private_data; 3152 struct bttv_fh *fh = file->private_data;
3153 struct bttv_buffer *buf; 3153 struct bttv_buffer *buf;
3154 enum v4l2_field field; 3154 enum v4l2_field field;
3155 unsigned int rc = POLLERR;
3155 3156
3156 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 3157 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
3157 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI)) 3158 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
@@ -3160,9 +3161,10 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
3160 } 3161 }
3161 3162
3162 if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { 3163 if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
3164 mutex_lock(&fh->cap.vb_lock);
3163 /* streaming capture */ 3165 /* streaming capture */
3164 if (list_empty(&fh->cap.stream)) 3166 if (list_empty(&fh->cap.stream))
3165 return POLLERR; 3167 goto err;
3166 buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); 3168 buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
3167 } else { 3169 } else {
3168 /* read() capture */ 3170 /* read() capture */
@@ -3191,11 +3193,12 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
3191 poll_wait(file, &buf->vb.done, wait); 3193 poll_wait(file, &buf->vb.done, wait);
3192 if (buf->vb.state == VIDEOBUF_DONE || 3194 if (buf->vb.state == VIDEOBUF_DONE ||
3193 buf->vb.state == VIDEOBUF_ERROR) 3195 buf->vb.state == VIDEOBUF_ERROR)
3194 return POLLIN|POLLRDNORM; 3196 rc = POLLIN|POLLRDNORM;
3195 return 0; 3197 else
3198 rc = 0;
3196err: 3199err:
3197 mutex_unlock(&fh->cap.vb_lock); 3200 mutex_unlock(&fh->cap.vb_lock);
3198 return POLLERR; 3201 return rc;
3199} 3202}
3200 3203
3201static int bttv_open(struct file *file) 3204static int bttv_open(struct file *file)
@@ -4166,7 +4169,6 @@ static struct video_device *vdev_init(struct bttv *btv,
4166 if (NULL == vfd) 4169 if (NULL == vfd)
4167 return NULL; 4170 return NULL;
4168 *vfd = *template; 4171 *vfd = *template;
4169 vfd->minor = -1;
4170 vfd->v4l2_dev = &btv->c.v4l2_dev; 4172 vfd->v4l2_dev = &btv->c.v4l2_dev;
4171 vfd->release = video_device_release; 4173 vfd->release = video_device_release;
4172 vfd->debug = bttv_debug; 4174 vfd->debug = bttv_debug;
@@ -4629,7 +4631,7 @@ static int __init bttv_init_module(void)
4629#endif 4631#endif
4630 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) 4632 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
4631 gbuffers = 2; 4633 gbuffers = 2;
4632 if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF) 4634 if (gbufsize > BTTV_MAX_FBUF)
4633 gbufsize = BTTV_MAX_FBUF; 4635 gbufsize = BTTV_MAX_FBUF;
4634 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; 4636 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
4635 if (bttv_verbose) 4637 if (bttv_verbose)
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index a99d92fac3dc..ebd1ee9dc871 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -389,6 +389,27 @@ int __devinit init_bttv_i2c(struct bttv *btv)
389 } 389 }
390 if (0 == btv->i2c_rc && i2c_scan) 390 if (0 == btv->i2c_rc && i2c_scan)
391 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); 391 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
392
393 /* Instantiate the IR receiver device, if present */
394 if (0 == btv->i2c_rc) {
395 struct i2c_board_info info;
396 /* The external IR receiver is at i2c address 0x34 (0x35 for
397 reads). Future Hauppauge cards will have an internal
398 receiver at 0x30 (0x31 for reads). In theory, both can be
399 fitted, and Hauppauge suggest an external overrides an
400 internal.
401
402 That's why we probe 0x1a (~0x34) first. CB
403 */
404 const unsigned short addr_list[] = {
405 0x1a, 0x18, 0x4b, 0x64, 0x30,
406 I2C_CLIENT_END
407 };
408
409 memset(&info, 0, sizeof(struct i2c_board_info));
410 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
411 i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
412 }
392 return btv->i2c_rc; 413 return btv->i2c_rc;
393} 414}
394 415
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index d4099f5312ac..0b4a8f309cfa 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1064,7 +1064,7 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
1064 1064
1065 switch(m->id) { 1065 switch(m->id) {
1066 case CPIA2_CID_FLICKER_MODE: 1066 case CPIA2_CID_FLICKER_MODE:
1067 if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS) 1067 if (m->index >= NUM_FLICKER_CONTROLS)
1068 return -EINVAL; 1068 return -EINVAL;
1069 1069
1070 strcpy(m->name, flicker_controls[m->index].name); 1070 strcpy(m->name, flicker_controls[m->index].name);
@@ -1082,14 +1082,14 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
1082 maximum = i; 1082 maximum = i;
1083 } 1083 }
1084 } 1084 }
1085 if(m->index < 0 || m->index > maximum) 1085 if (m->index > maximum)
1086 return -EINVAL; 1086 return -EINVAL;
1087 1087
1088 strcpy(m->name, framerate_controls[m->index].name); 1088 strcpy(m->name, framerate_controls[m->index].name);
1089 break; 1089 break;
1090 } 1090 }
1091 case CPIA2_CID_LIGHTS: 1091 case CPIA2_CID_LIGHTS:
1092 if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS) 1092 if (m->index >= NUM_LIGHTS_CONTROLS)
1093 return -EINVAL; 1093 return -EINVAL;
1094 1094
1095 strcpy(m->name, lights_controls[m->index].name); 1095 strcpy(m->name, lights_controls[m->index].name);
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 7a8ad5963de8..35268923911c 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -26,14 +26,18 @@
26#include "cx18-cards.h" 26#include "cx18-cards.h"
27#include "cx18-audio.h" 27#include "cx18-audio.h"
28 28
29#define CX18_AUDIO_ENABLE 0xc72014 29#define CX18_AUDIO_ENABLE 0xc72014
30#define CX18_AI1_MUX_MASK 0x30
31#define CX18_AI1_MUX_I2S1 0x00
32#define CX18_AI1_MUX_I2S2 0x10
33#define CX18_AI1_MUX_843_I2S 0x20
30 34
31/* Selects the audio input and output according to the current 35/* Selects the audio input and output according to the current
32 settings. */ 36 settings. */
33int cx18_audio_set_io(struct cx18 *cx) 37int cx18_audio_set_io(struct cx18 *cx)
34{ 38{
35 const struct cx18_card_audio_input *in; 39 const struct cx18_card_audio_input *in;
36 u32 val; 40 u32 u, v;
37 int err; 41 int err;
38 42
39 /* Determine which input to use */ 43 /* Determine which input to use */
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx)
52 return err; 56 return err;
53 57
54 /* FIXME - this internal mux should be abstracted to a subdev */ 58 /* FIXME - this internal mux should be abstracted to a subdev */
55 val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; 59 u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
56 val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : 60 v = u & ~CX18_AI1_MUX_MASK;
57 (in->audio_input << 4); 61 switch (in->audio_input) {
58 cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); 62 case CX18_AV_AUDIO_SERIAL1:
63 v |= CX18_AI1_MUX_I2S1;
64 break;
65 case CX18_AV_AUDIO_SERIAL2:
66 v |= CX18_AI1_MUX_I2S2;
67 break;
68 default:
69 v |= CX18_AI1_MUX_843_I2S;
70 break;
71 }
72 if (v == u) {
73 /* force a toggle of some AI1 MUX control bits */
74 u &= ~CX18_AI1_MUX_MASK;
75 switch (in->audio_input) {
76 case CX18_AV_AUDIO_SERIAL1:
77 u |= CX18_AI1_MUX_843_I2S;
78 break;
79 case CX18_AV_AUDIO_SERIAL2:
80 u |= CX18_AI1_MUX_843_I2S;
81 break;
82 default:
83 u |= CX18_AI1_MUX_I2S1;
84 break;
85 }
86 cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
87 u, CX18_AI1_MUX_MASK);
88 }
89 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
90 v, CX18_AI1_MUX_MASK);
59 return 0; 91 return 0;
60} 92}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index cf2bd888a429..536dedb23ba3 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -99,9 +99,39 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
99 or_value); 99 or_value);
100} 100}
101 101
102static void cx18_av_initialize(struct cx18 *cx) 102static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
103{ 103{
104 struct cx18_av_state *state = &cx->av_state; 104 struct cx18 *cx = v4l2_get_subdevdata(sd);
105
106 /*
107 * The crystal freq used in calculations in this driver will be
108 * 28.636360 MHz.
109 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
110 */
111
112 /*
113 * VDCLK Integer = 0x0f, Post Divider = 0x04
114 * AIMCLK Integer = 0x0e, Post Divider = 0x16
115 */
116 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
117
118 /* VDCLK Fraction = 0x2be2fe */
119 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
120 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
121
122 /* AIMCLK Fraction = 0x05227ad */
123 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
124 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
125
126 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
127 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
128 return 0;
129}
130
131static void cx18_av_initialize(struct v4l2_subdev *sd)
132{
133 struct cx18_av_state *state = to_cx18_av_state(sd);
134 struct cx18 *cx = v4l2_get_subdevdata(sd);
105 u32 v; 135 u32 v;
106 136
107 cx18_av_loadfw(cx); 137 cx18_av_loadfw(cx);
@@ -150,6 +180,26 @@ static void cx18_av_initialize(struct cx18 *cx)
150 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); 180 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
151 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); 181 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
152 182
183 /*
184 * Disable Video Auto-config of the Analog Front End and Video PLL.
185 *
186 * Since we only use BT.656 pixel mode, which works for both 525 and 625
187 * line systems, it's just easier for us to set registers
188 * 0x102 (CXADEC_CHIP_CTRL), 0x104-0x106 (CXADEC_AFE_CTRL),
189 * 0x108-0x109 (CXADEC_PLL_CTRL1), and 0x10c-0x10f (CXADEC_VID_PLL_FRAC)
190 * ourselves, than to run around cleaning up after the auto-config.
191 *
192 * (Note: my CX23418 chip doesn't seem to let the ACFG_DIS bit
193 * get set to 1, but OTOH, it doesn't seem to do AFE and VID PLL
194 * autoconfig either.)
195 *
196 * As a default, also turn off Dual mode for ADC2 and set ADC2 to CH3.
197 */
198 cx18_av_and_or4(cx, CXADEC_CHIP_CTRL, 0xFFFBFFFF, 0x00120000);
199
200 /* Setup the Video and and Aux/Audio PLLs */
201 cx18_av_init(sd, 0);
202
153 /* set video to auto-detect */ 203 /* set video to auto-detect */
154 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ 204 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
155 /* set the comb notch = 1 */ 205 /* set the comb notch = 1 */
@@ -176,12 +226,23 @@ static void cx18_av_initialize(struct cx18 *cx)
176 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ 226 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
177 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ 227 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
178 228
179 v = cx18_av_read4(cx, CXADEC_AFE_CTRL); 229 /*
180 v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */ 230 * Analog Front End (AFE)
181 v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */ 231 * Default to luma on ch1/ADC1, chroma on ch2/ADC2, SIF on ch3/ADC2
182 v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */ 232 * bypass_ch[1-3] use filter
183 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */ 233 * droop_comp_ch[1-3] disable
184 cx18_av_write4(cx, CXADEC_AFE_CTRL, v); 234 * clamp_en_ch[1-3] disable
235 * aud_in_sel ADC2
236 * luma_in_sel ADC1
237 * chroma_in_sel ADC2
238 * clamp_sel_ch[2-3] midcode
239 * clamp_sel_ch1 video decoder
240 * vga_sel_ch3 audio decoder
241 * vga_sel_ch[1-2] video decoder
242 * half_bw_ch[1-3] disable
243 * +12db_ch[1-3] disable
244 */
245 cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
185 246
186/* if(dwEnable && dw3DCombAvailable) { */ 247/* if(dwEnable && dw3DCombAvailable) { */
187/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ 248/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
@@ -195,50 +256,18 @@ static void cx18_av_initialize(struct cx18 *cx)
195 256
196static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) 257static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
197{ 258{
198 struct cx18 *cx = v4l2_get_subdevdata(sd); 259 cx18_av_initialize(sd);
199
200 cx18_av_initialize(cx);
201 return 0;
202}
203
204static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
205{
206 struct cx18 *cx = v4l2_get_subdevdata(sd);
207
208 /*
209 * The crystal freq used in calculations in this driver will be
210 * 28.636360 MHz.
211 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
212 */
213
214 /*
215 * VDCLK Integer = 0x0f, Post Divider = 0x04
216 * AIMCLK Integer = 0x0e, Post Divider = 0x16
217 */
218 cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
219
220 /* VDCLK Fraction = 0x2be2fe */
221 /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
222 cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
223
224 /* AIMCLK Fraction = 0x05227ad */
225 /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
226 cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
227
228 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
229 cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
230 return 0; 260 return 0;
231} 261}
232 262
233static int cx18_av_load_fw(struct v4l2_subdev *sd) 263static int cx18_av_load_fw(struct v4l2_subdev *sd)
234{ 264{
235 struct cx18_av_state *state = to_cx18_av_state(sd); 265 struct cx18_av_state *state = to_cx18_av_state(sd);
236 struct cx18 *cx = v4l2_get_subdevdata(sd);
237 266
238 if (!state->is_initialized) { 267 if (!state->is_initialized) {
239 /* initialize on first use */ 268 /* initialize on first use */
240 state->is_initialized = 1; 269 state->is_initialized = 1;
241 cx18_av_initialize(cx); 270 cx18_av_initialize(sd);
242 } 271 }
243 return 0; 272 return 0;
244} 273}
@@ -248,8 +277,15 @@ void cx18_av_std_setup(struct cx18 *cx)
248 struct cx18_av_state *state = &cx->av_state; 277 struct cx18_av_state *state = &cx->av_state;
249 struct v4l2_subdev *sd = &state->sd; 278 struct v4l2_subdev *sd = &state->sd;
250 v4l2_std_id std = state->std; 279 v4l2_std_id std = state->std;
280
281 /*
282 * Video ADC crystal clock to pixel clock SRC decimation ratio
283 * 28.636360 MHz/13.5 Mpps * 256 = 0x21f.07b
284 */
285 const int src_decimation = 0x21f;
286
251 int hblank, hactive, burst, vblank, vactive, sc; 287 int hblank, hactive, burst, vblank, vactive, sc;
252 int vblank656, src_decimation; 288 int vblank656;
253 int luma_lpf, uv_lpf, comb; 289 int luma_lpf, uv_lpf, comb;
254 u32 pll_int, pll_frac, pll_post; 290 u32 pll_int, pll_frac, pll_post;
255 291
@@ -259,40 +295,96 @@ void cx18_av_std_setup(struct cx18 *cx)
259 else 295 else
260 cx18_av_write(cx, 0x49f, 0x14); 296 cx18_av_write(cx, 0x49f, 0x14);
261 297
298 /*
299 * Note: At the end of a field, there are 3 sets of half line duration
300 * (double horizontal rate) pulses:
301 *
302 * 5 (625) or 6 (525) half-lines to blank for the vertical retrace
303 * 5 (625) or 6 (525) vertical sync pulses of half line duration
304 * 5 (625) or 6 (525) half-lines of equalization pulses
305 */
262 if (std & V4L2_STD_625_50) { 306 if (std & V4L2_STD_625_50) {
263 /* FIXME - revisit these for Sliced VBI */ 307 /*
308 * The following relationships of half line counts should hold:
309 * 625 = vblank656 + vactive
310 * 10 = vblank656 - vblank = vsync pulses + equalization pulses
311 *
312 * vblank656: half lines after line 625/mid-313 of blanked video
313 * vblank: half lines, after line 5/317, of blanked video
314 * vactive: half lines of active video +
315 * 5 half lines after the end of active video
316 *
317 * As far as I can tell:
318 * vblank656 starts counting from the falling edge of the first
319 * vsync pulse (start of line 1 or mid-313)
320 * vblank starts counting from the after the 5 vsync pulses and
321 * 5 or 4 equalization pulses (start of line 6 or 318)
322 *
323 * For 625 line systems the driver will extract VBI information
324 * from lines 6-23 and lines 318-335 (but the slicer can only
325 * handle 17 lines, not the 18 in the vblank region).
326 * In addition, we need vblank656 and vblank to be one whole
327 * line longer, to cover line 24 and 336, so the SAV/EAV RP
328 * codes get generated such that the encoder can actually
329 * extract line 23 & 335 (WSS). We'll lose 1 line in each field
330 * at the top of the screen.
331 *
332 * It appears the 5 half lines that happen after active
333 * video must be included in vactive (579 instead of 574),
334 * otherwise the colors get badly displayed in various regions
335 * of the screen. I guess the chroma comb filter gets confused
336 * without them (at least when a PVR-350 is the PAL source).
337 */
338 vblank656 = 48; /* lines 1 - 24 & 313 - 336 */
339 vblank = 38; /* lines 6 - 24 & 318 - 336 */
340 vactive = 579; /* lines 24 - 313 & 337 - 626 */
341
342 /*
343 * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
344 * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601
345 * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
346 * the end of active video to start a horizontal line, so that
347 * leaves 132 pixels of hblank to ignore.
348 */
264 hblank = 132; 349 hblank = 132;
265 hactive = 720; 350 hactive = 720;
266 burst = 93;
267 vblank = 36;
268 vactive = 580;
269 vblank656 = 40;
270 src_decimation = 0x21f;
271 351
352 /*
353 * Burst gate delay (for 625 line systems)
354 * Hsync leading edge to color burst rise = 5.6 us
355 * Color burst width = 2.25 us
356 * Gate width = 4 pixel clocks
357 * (5.6 us + 2.25/2 us) * 13.5 Mpps + 4/2 clocks = 92.79 clocks
358 */
359 burst = 93;
272 luma_lpf = 2; 360 luma_lpf = 2;
273 if (std & V4L2_STD_PAL) { 361 if (std & V4L2_STD_PAL) {
274 uv_lpf = 1; 362 uv_lpf = 1;
275 comb = 0x20; 363 comb = 0x20;
276 sc = 688739; 364 /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
365 sc = 688700;
277 } else if (std == V4L2_STD_PAL_Nc) { 366 } else if (std == V4L2_STD_PAL_Nc) {
278 uv_lpf = 1; 367 uv_lpf = 1;
279 comb = 0x20; 368 comb = 0x20;
280 sc = 556453; 369 /* sc = 3582056.25 * src_decimation/28636360 * 2^13 */
370 sc = 556422;
281 } else { /* SECAM */ 371 } else { /* SECAM */
282 uv_lpf = 0; 372 uv_lpf = 0;
283 comb = 0; 373 comb = 0;
284 sc = 672351; 374 /* (fr + fb)/2 = (4406260 + 4250000)/2 = 4328130 */
375 /* sc = 4328130 * src_decimation/28636360 * 2^13 */
376 sc = 672314;
285 } 377 }
286 } else { 378 } else {
287 /* 379 /*
288 * The following relationships of half line counts should hold: 380 * The following relationships of half line counts should hold:
289 * 525 = vsync + vactive + vblank656 381 * 525 = prevsync + vblank656 + vactive
290 * 12 = vblank656 - vblank 382 * 12 = vblank656 - vblank = vsync pulses + equalization pulses
291 * 383 *
292 * vsync: always 6 half-lines of vsync pulses 384 * prevsync: 6 half-lines before the vsync pulses
293 * vactive: half lines of active video
294 * vblank656: half lines, after line 3/mid-266, of blanked video 385 * vblank656: half lines, after line 3/mid-266, of blanked video
295 * vblank: half lines, after line 9/272, of blanked video 386 * vblank: half lines, after line 9/272, of blanked video
387 * vactive: half lines of active video
296 * 388 *
297 * As far as I can tell: 389 * As far as I can tell:
298 * vblank656 starts counting from the falling edge of the first 390 * vblank656 starts counting from the falling edge of the first
@@ -319,20 +411,30 @@ void cx18_av_std_setup(struct cx18 *cx)
319 luma_lpf = 1; 411 luma_lpf = 1;
320 uv_lpf = 1; 412 uv_lpf = 1;
321 413
322 src_decimation = 0x21f; 414 /*
415 * Burst gate delay (for 525 line systems)
416 * Hsync leading edge to color burst rise = 5.3 us
417 * Color burst width = 2.5 us
418 * Gate width = 4 pixel clocks
419 * (5.3 us + 2.5/2 us) * 13.5 Mpps + 4/2 clocks = 90.425 clocks
420 */
323 if (std == V4L2_STD_PAL_60) { 421 if (std == V4L2_STD_PAL_60) {
324 burst = 0x5b; 422 burst = 90;
325 luma_lpf = 2; 423 luma_lpf = 2;
326 comb = 0x20; 424 comb = 0x20;
327 sc = 688739; 425 /* sc = 4433618.75 * src_decimation/28636360 * 2^13 */
426 sc = 688700;
328 } else if (std == V4L2_STD_PAL_M) { 427 } else if (std == V4L2_STD_PAL_M) {
329 burst = 0x61; 428 /* The 97 needs to be verified against PAL-M timings */
429 burst = 97;
330 comb = 0x20; 430 comb = 0x20;
331 sc = 555452; 431 /* sc = 3575611.49 * src_decimation/28636360 * 2^13 */
432 sc = 555421;
332 } else { 433 } else {
333 burst = 0x5b; 434 burst = 90;
334 comb = 0x66; 435 comb = 0x66;
335 sc = 556063; 436 /* sc = 3579545.45.. * src_decimation/28636360 * 2^13 */
437 sc = 556032;
336 } 438 }
337 } 439 }
338 440
@@ -344,23 +446,26 @@ void cx18_av_std_setup(struct cx18 *cx)
344 pll_int, pll_frac, pll_post); 446 pll_int, pll_frac, pll_post);
345 447
346 if (pll_post) { 448 if (pll_post) {
347 int fin, fsc, pll; 449 int fsc, pll;
450 u64 tmp;
348 451
349 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; 452 pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
350 pll /= pll_post; 453 pll /= pll_post;
351 CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n", 454 CX18_DEBUG_INFO_DEV(sd, "Video PLL = %d.%06d MHz\n",
352 pll / 1000000, pll % 1000000); 455 pll / 1000000, pll % 1000000);
353 CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n", 456 CX18_DEBUG_INFO_DEV(sd, "Pixel rate = %d.%06d Mpixel/sec\n",
354 pll / 8000000, (pll / 8) % 1000000); 457 pll / 8000000, (pll / 8) % 1000000);
355 458
356 fin = ((u64)src_decimation * pll) >> 12; 459 CX18_DEBUG_INFO_DEV(sd, "ADC XTAL/pixel clock decimation ratio "
357 CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n", 460 "= %d.%03d\n", src_decimation / 256,
358 fin / 1000000, fin % 1000000); 461 ((src_decimation % 256) * 1000) / 256);
359 462
360 fsc = (((u64)sc) * pll) >> 24L; 463 tmp = 28636360 * (u64) sc;
464 do_div(tmp, src_decimation);
465 fsc = tmp >> 13;
361 CX18_DEBUG_INFO_DEV(sd, 466 CX18_DEBUG_INFO_DEV(sd,
362 "Chroma sub-carrier freq = %d.%06d MHz\n", 467 "Chroma sub-carrier initial freq = %d.%06d "
363 fsc / 1000000, fsc % 1000000); 468 "MHz\n", fsc / 1000000, fsc % 1000000);
364 469
365 CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " 470 CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
366 "vactive %i, vblank656 %i, src_dec %i, " 471 "vactive %i, vblank656 %i, src_dec %i, "
@@ -470,16 +575,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
470{ 575{
471 struct cx18_av_state *state = &cx->av_state; 576 struct cx18_av_state *state = &cx->av_state;
472 struct v4l2_subdev *sd = &state->sd; 577 struct v4l2_subdev *sd = &state->sd;
473 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && 578
474 vid_input <= CX18_AV_COMPOSITE8); 579 enum analog_signal_type {
475 u8 reg; 580 NONE, CVBS, Y, C, SIF, Pb, Pr
476 u8 v; 581 } ch[3] = {NONE, NONE, NONE};
582
583 u8 afe_mux_cfg;
584 u8 adc2_cfg;
585 u32 afe_cfg;
586 int i;
477 587
478 CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", 588 CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
479 vid_input, aud_input); 589 vid_input, aud_input);
480 590
481 if (is_composite) { 591 if (vid_input >= CX18_AV_COMPOSITE1 &&
482 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); 592 vid_input <= CX18_AV_COMPOSITE8) {
593 afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
594 ch[0] = CVBS;
483 } else { 595 } else {
484 int luma = vid_input & 0xf0; 596 int luma = vid_input & 0xf0;
485 int chroma = vid_input & 0xf00; 597 int chroma = vid_input & 0xf00;
@@ -493,26 +605,45 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
493 vid_input); 605 vid_input);
494 return -EINVAL; 606 return -EINVAL;
495 } 607 }
496 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); 608 afe_mux_cfg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
609 ch[0] = Y;
497 if (chroma >= CX18_AV_SVIDEO_CHROMA7) { 610 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
498 reg &= 0x3f; 611 afe_mux_cfg &= 0x3f;
499 reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; 612 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
613 ch[2] = C;
500 } else { 614 } else {
501 reg &= 0xcf; 615 afe_mux_cfg &= 0xcf;
502 reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; 616 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
617 ch[1] = C;
503 } 618 }
504 } 619 }
620 /* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */
505 621
506 switch (aud_input) { 622 switch (aud_input) {
507 case CX18_AV_AUDIO_SERIAL1: 623 case CX18_AV_AUDIO_SERIAL1:
508 case CX18_AV_AUDIO_SERIAL2: 624 case CX18_AV_AUDIO_SERIAL2:
509 /* do nothing, use serial audio input */ 625 /* do nothing, use serial audio input */
510 break; 626 break;
511 case CX18_AV_AUDIO4: reg &= ~0x30; break; 627 case CX18_AV_AUDIO4:
512 case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break; 628 afe_mux_cfg &= ~0x30;
513 case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break; 629 ch[1] = SIF;
514 case CX18_AV_AUDIO7: reg &= ~0xc0; break; 630 break;
515 case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; 631 case CX18_AV_AUDIO5:
632 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x10;
633 ch[1] = SIF;
634 break;
635 case CX18_AV_AUDIO6:
636 afe_mux_cfg = (afe_mux_cfg & ~0x30) | 0x20;
637 ch[1] = SIF;
638 break;
639 case CX18_AV_AUDIO7:
640 afe_mux_cfg &= ~0xc0;
641 ch[2] = SIF;
642 break;
643 case CX18_AV_AUDIO8:
644 afe_mux_cfg = (afe_mux_cfg & ~0xc0) | 0x40;
645 ch[2] = SIF;
646 break;
516 647
517 default: 648 default:
518 CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", 649 CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
@@ -520,24 +651,65 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
520 return -EINVAL; 651 return -EINVAL;
521 } 652 }
522 653
523 cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7); 654 /* Set up analog front end multiplexers */
655 cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
524 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 656 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
525 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); 657 cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02);
526 658
527 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 659 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
528 v = cx18_av_read(cx, 0x102); 660 adc2_cfg = cx18_av_read(cx, 0x102);
529 if (reg & 0x80) 661 if (ch[2] == NONE)
530 v &= ~0x2; 662 adc2_cfg &= ~0x2; /* No sig on CH3, set ADC2 to CH2 for input */
531 else 663 else
532 v |= 0x2; 664 adc2_cfg |= 0x2; /* Signal on CH3, set ADC2 to CH3 for input */
665
533 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ 666 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
534 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) 667 if (ch[1] != NONE && ch[2] != NONE)
535 v |= 0x4; 668 adc2_cfg |= 0x4; /* Set dual mode */
536 else 669 else
537 v &= ~0x4; 670 adc2_cfg &= ~0x4; /* Clear dual mode */
538 cx18_av_write_expect(cx, 0x102, v, v, 0x17); 671 cx18_av_write_expect(cx, 0x102, adc2_cfg, adc2_cfg, 0x17);
672
673 /* Configure the analog front end */
674 afe_cfg = cx18_av_read4(cx, CXADEC_AFE_CTRL);
675 afe_cfg &= 0xff000000;
676 afe_cfg |= 0x00005000; /* CHROMA_IN, AUD_IN: ADC2; LUMA_IN: ADC1 */
677 if (ch[1] != NONE && ch[2] != NONE)
678 afe_cfg |= 0x00000030; /* half_bw_ch[2-3] since in dual mode */
679
680 for (i = 0; i < 3; i++) {
681 switch (ch[i]) {
682 default:
683 case NONE:
684 /* CLAMP_SEL = Fixed to midcode clamp level */
685 afe_cfg |= (0x00000200 << i);
686 break;
687 case CVBS:
688 case Y:
689 if (i > 0)
690 afe_cfg |= 0x00002000; /* LUMA_IN_SEL: ADC2 */
691 break;
692 case C:
693 case Pb:
694 case Pr:
695 /* CLAMP_SEL = Fixed to midcode clamp level */
696 afe_cfg |= (0x00000200 << i);
697 if (i == 0 && ch[i] == C)
698 afe_cfg &= ~0x00001000; /* CHROMA_IN_SEL ADC1 */
699 break;
700 case SIF:
701 /*
702 * VGA_GAIN_SEL = Audio Decoder
703 * CLAMP_SEL = Fixed to midcode clamp level
704 */
705 afe_cfg |= (0x00000240 << i);
706 if (i == 0)
707 afe_cfg &= ~0x00004000; /* AUD_IN_SEL ADC1 */
708 break;
709 }
710 }
539 711
540 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ 712 cx18_av_write4(cx, CXADEC_AFE_CTRL, afe_cfg);
541 713
542 state->vid_input = vid_input; 714 state->vid_input = vid_input;
543 state->aud_input = aud_input; 715 state->aud_input = aud_input;
@@ -858,9 +1030,9 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
858 * cx18_av_std_setup(), above standard values: 1030 * cx18_av_std_setup(), above standard values:
859 * 1031 *
860 * 480 + 1 for 60 Hz systems 1032 * 480 + 1 for 60 Hz systems
861 * 576 + 4 for 50 Hz systems 1033 * 576 + 3 for 50 Hz systems
862 */ 1034 */
863 Vlines = pix->height + (is_50Hz ? 4 : 1); 1035 Vlines = pix->height + (is_50Hz ? 3 : 1);
864 1036
865 /* 1037 /*
866 * Invalid height and width scaling requests are: 1038 * Invalid height and width scaling requests are:
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 49a55cc8d839..b9e8cc5d264a 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -24,15 +24,63 @@
24#include "cx18-io.h" 24#include "cx18-io.h"
25#include <linux/firmware.h> 25#include <linux/firmware.h>
26 26
27#define CX18_AUDIO_ENABLE 0xc72014 27#define CX18_AUDIO_ENABLE 0xc72014
28#define CX18_AI1_MUX_MASK 0x30
29#define CX18_AI1_MUX_I2S1 0x00
30#define CX18_AI1_MUX_I2S2 0x10
31#define CX18_AI1_MUX_843_I2S 0x20
32#define CX18_AI1_MUX_INVALID 0x30
33
28#define FWFILE "v4l-cx23418-dig.fw" 34#define FWFILE "v4l-cx23418-dig.fw"
29 35
36static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
37{
38 struct v4l2_subdev *sd = &cx->av_state.sd;
39 int ret = 0;
40 const u8 *data;
41 u32 size;
42 int addr;
43 u32 expected, dl_control;
44
45 /* Ensure we put the 8051 in reset and enable firmware upload mode */
46 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
47 do {
48 dl_control &= 0x00ffffff;
49 dl_control |= 0x0f000000;
50 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
51 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
52 } while ((dl_control & 0xff000000) != 0x0f000000);
53
54 /* Read and auto increment until at address 0x0000 */
55 while (dl_control & 0x3fff)
56 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
57
58 data = fw->data;
59 size = fw->size;
60 for (addr = 0; addr < size; addr++) {
61 dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
62 expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
63 if (expected != dl_control) {
64 CX18_ERR_DEV(sd, "verification of %s firmware load "
65 "failed: expected %#010x got %#010x\n",
66 FWFILE, expected, dl_control);
67 ret = -EIO;
68 break;
69 }
70 dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
71 }
72 if (ret == 0)
73 CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
74 FWFILE, size);
75 return ret;
76}
77
30int cx18_av_loadfw(struct cx18 *cx) 78int cx18_av_loadfw(struct cx18 *cx)
31{ 79{
32 struct v4l2_subdev *sd = &cx->av_state.sd; 80 struct v4l2_subdev *sd = &cx->av_state.sd;
33 const struct firmware *fw = NULL; 81 const struct firmware *fw = NULL;
34 u32 size; 82 u32 size;
35 u32 v; 83 u32 u, v;
36 const u8 *ptr; 84 const u8 *ptr;
37 int i; 85 int i;
38 int retries1 = 0; 86 int retries1 = 0;
@@ -95,6 +143,12 @@ int cx18_av_loadfw(struct cx18 *cx)
95 } 143 }
96 144
97 cx18_av_write4_expect(cx, CXADEC_DL_CTL, 145 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
146 0x03000000 | fw->size, 0x03000000, 0x13000000);
147
148 CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
149
150 if (cx18_av_verifyfw(cx, fw) == 0)
151 cx18_av_write4_expect(cx, CXADEC_DL_CTL,
98 0x13000000 | fw->size, 0x13000000, 0x13000000); 152 0x13000000 | fw->size, 0x13000000, 0x13000000);
99 153
100 /* Output to the 416 */ 154 /* Output to the 416 */
@@ -135,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx)
135 cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, 189 cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
136 0, 0x400); 190 0, 0x400);
137 191
192 /* Toggle the AI1 MUX */
193 v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
194 u = v & CX18_AI1_MUX_MASK;
195 v &= ~CX18_AI1_MUX_MASK;
196 if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
197 /* Switch to I2S1 */
198 v |= CX18_AI1_MUX_I2S1;
199 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
200 v, CX18_AI1_MUX_MASK);
201 /* Switch back to the A/V decoder core I2S output */
202 v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
203 } else {
204 /* Switch to the A/V decoder core I2S output */
205 v |= CX18_AI1_MUX_843_I2S;
206 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
207 v, CX18_AI1_MUX_MASK);
208 /* Switch back to I2S1 or I2S2 */
209 v = (v & ~CX18_AI1_MUX_MASK) | u;
210 }
211 cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
212 v, CX18_AI1_MUX_MASK);
213
138 /* Enable WW auto audio standard detection */ 214 /* Enable WW auto audio standard detection */
139 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); 215 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
140 v |= 0xFF; /* Auto by default */ 216 v |= 0xFF; /* Auto by default */
@@ -143,7 +219,5 @@ int cx18_av_loadfw(struct cx18 *cx)
143 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); 219 cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
144 220
145 release_firmware(fw); 221 release_firmware(fw);
146
147 CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
148 return 0; 222 return 0;
149} 223}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 23b31670bf1d..a51732bcca4b 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -255,8 +255,8 @@ int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
255 } 255 }
256 256
257 cx18_av_write(cx, 0x43c, 0x16); 257 cx18_av_write(cx, 0x43c, 0x16);
258 /* FIXME - should match vblank set in cx18_av_std_setup() */ 258 /* Should match vblank set in cx18_av_std_setup() */
259 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); 259 cx18_av_write(cx, 0x474, is_pal ? 38 : 26);
260 return 0; 260 return 0;
261} 261}
262 262
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 9bc221837847..c92a25036f0e 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -340,13 +340,12 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
340 340
341static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { 341static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
342 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ 342 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
343 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
344 { 0, 0, 0 } 343 { 0, 0, 0 }
345}; 344};
346 345
347static const struct cx18_card cx18_card_leadtek_pvr2100 = { 346static const struct cx18_card cx18_card_leadtek_pvr2100 = {
348 .type = CX18_CARD_LEADTEK_PVR2100, 347 .type = CX18_CARD_LEADTEK_PVR2100,
349 .name = "Leadtek WinFast PVR2100/DVR3100 H", 348 .name = "Leadtek WinFast PVR2100",
350 .comment = "Experimenters and photos needed for device to work well.\n" 349 .comment = "Experimenters and photos needed for device to work well.\n"
351 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", 350 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
352 .v4l2_capabilities = CX18_CAP_ENCODER, 351 .v4l2_capabilities = CX18_CAP_ENCODER,
@@ -365,15 +364,12 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
365 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, 364 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
366 }, 365 },
367 .tuners = { 366 .tuners = {
368 /* XC3028 tuner */ 367 /* XC2028 tuner */
369 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, 368 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
370 }, 369 },
371 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, 370 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
372 .ddr = { 371 .ddr = {
373 /* 372 /* Pointer to proper DDR config values provided by Terry Wu */
374 * Pointer to proper DDR config values provided by
375 * Terry Wu <terrywu at leadtek.com.tw>
376 */
377 .chip_config = 0x303, 373 .chip_config = 0x303,
378 .refresh = 0x3bb, 374 .refresh = 0x3bb,
379 .timing1 = 0x24220e83, 375 .timing1 = 0x24220e83,
@@ -392,6 +388,58 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
392 388
393/* ------------------------------------------------------------------------- */ 389/* ------------------------------------------------------------------------- */
394 390
391/* Leadtek WinFast DVR3100 H */
392
393static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
394 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
395 { 0, 0, 0 }
396};
397
398static const struct cx18_card cx18_card_leadtek_dvr3100h = {
399 .type = CX18_CARD_LEADTEK_DVR3100H,
400 .name = "Leadtek WinFast DVR3100 H",
401 .comment = "Simultaneous DVB-T and Analog capture supported,\n"
402 "\texcept when capturing Analog from the antenna input.\n",
403 .v4l2_capabilities = CX18_CAP_ENCODER,
404 .hw_audio_ctrl = CX18_HW_418_AV,
405 .hw_muxer = CX18_HW_GPIO_MUX,
406 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
407 CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
408 .video_inputs = {
409 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
410 { CX18_CARD_INPUT_SVIDEO1, 1,
411 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
412 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
413 },
414 .audio_inputs = {
415 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
416 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
417 },
418 .tuners = {
419 /* XC3028 tuner */
420 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
421 },
422 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
423 .ddr = {
424 /* Pointer to proper DDR config values provided by Terry Wu */
425 .chip_config = 0x303,
426 .refresh = 0x3bb,
427 .timing1 = 0x24220e83,
428 .timing2 = 0x1f,
429 .tune_lane = 0,
430 .initial_emrs = 0x2,
431 },
432 .gpio_init.initial_value = 0x6,
433 .gpio_init.direction = 0x7,
434 .gpio_audio_input = { .mask = 0x7,
435 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
436 .xceive_pin = 1,
437 .pci_list = cx18_pci_leadtek_dvr3100h,
438 .i2c = &cx18_i2c_std,
439};
440
441/* ------------------------------------------------------------------------- */
442
395static const struct cx18_card *cx18_card_list[] = { 443static const struct cx18_card *cx18_card_list[] = {
396 &cx18_card_hvr1600_esmt, 444 &cx18_card_hvr1600_esmt,
397 &cx18_card_hvr1600_samsung, 445 &cx18_card_hvr1600_samsung,
@@ -400,6 +448,7 @@ static const struct cx18_card *cx18_card_list[] = {
400 &cx18_card_cnxt_raptor_pal, 448 &cx18_card_cnxt_raptor_pal,
401 &cx18_card_toshiba_qosmio_dvbt, 449 &cx18_card_toshiba_qosmio_dvbt,
402 &cx18_card_leadtek_pvr2100, 450 &cx18_card_leadtek_pvr2100,
451 &cx18_card_leadtek_dvr3100h,
403}; 452};
404 453
405const struct cx18_card *cx18_get_card(u16 index) 454const struct cx18_card *cx18_get_card(u16 index)
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 82fc2f9d4021..8e35c3aed544 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx,
176 return -EBUSY; 176 return -EBUSY;
177 177
178 if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || 178 if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
179 type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { 179 !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
180 /* We don't do VBI insertion aside from IVTV format in a PS */ 180 type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
181 type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
182 /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
181 cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; 183 cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
182 CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " 184 CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
183 "the MPEG stream\n"); 185 "the MPEG stream\n");
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 49b1c3d7b1a8..92026e82e10e 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -30,6 +30,7 @@
30#include "cx18-irq.h" 30#include "cx18-irq.h"
31#include "cx18-gpio.h" 31#include "cx18-gpio.h"
32#include "cx18-firmware.h" 32#include "cx18-firmware.h"
33#include "cx18-queue.h"
33#include "cx18-streams.h" 34#include "cx18-streams.h"
34#include "cx18-av-core.h" 35#include "cx18-av-core.h"
35#include "cx18-scb.h" 36#include "cx18-scb.h"
@@ -151,7 +152,8 @@ MODULE_PARM_DESC(cardtype,
151 "\t\t\t 4 = Yuan MPC718\n" 152 "\t\t\t 4 = Yuan MPC718\n"
152 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" 153 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
153 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" 154 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
154 "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n" 155 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
156 "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
155 "\t\t\t 0 = Autodetect (default)\n" 157 "\t\t\t 0 = Autodetect (default)\n"
156 "\t\t\t-1 = Ignore this card\n\t\t"); 158 "\t\t\t-1 = Ignore this card\n\t\t");
157MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); 159MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -312,7 +314,7 @@ static void cx18_process_eeprom(struct cx18 *cx)
312 CX18_INFO("Autodetected %s\n", cx->card_name); 314 CX18_INFO("Autodetected %s\n", cx->card_name);
313 315
314 if (tv.tuner_type == TUNER_ABSENT) 316 if (tv.tuner_type == TUNER_ABSENT)
315 CX18_ERR("tveeprom cannot autodetect tuner!"); 317 CX18_ERR("tveeprom cannot autodetect tuner!\n");
316 318
317 if (cx->options.tuner == -1) 319 if (cx->options.tuner == -1)
318 cx->options.tuner = tv.tuner_type; 320 cx->options.tuner = tv.tuner_type;
@@ -546,6 +548,40 @@ done:
546 cx->card_i2c = cx->card->i2c; 548 cx->card_i2c = cx->card->i2c;
547} 549}
548 550
551static int __devinit cx18_create_in_workq(struct cx18 *cx)
552{
553 snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
554 cx->v4l2_dev.name);
555 cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
556 if (cx->in_work_queue == NULL) {
557 CX18_ERR("Unable to create incoming mailbox handler thread\n");
558 return -ENOMEM;
559 }
560 return 0;
561}
562
563static int __devinit cx18_create_out_workq(struct cx18 *cx)
564{
565 snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out",
566 cx->v4l2_dev.name);
567 cx->out_work_queue = create_workqueue(cx->out_workq_name);
568 if (cx->out_work_queue == NULL) {
569 CX18_ERR("Unable to create outgoing mailbox handler threads\n");
570 return -ENOMEM;
571 }
572 return 0;
573}
574
575static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
576{
577 int i;
578 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
579 cx->in_work_order[i].cx = cx;
580 cx->in_work_order[i].str = cx->epu_debug_str;
581 INIT_WORK(&cx->in_work_order[i].work, cx18_in_work_handler);
582 }
583}
584
549/* Precondition: the cx18 structure has been memset to 0. Only 585/* Precondition: the cx18 structure has been memset to 0. Only
550 the dev and instance fields have been filled in. 586 the dev and instance fields have been filled in.
551 No assumptions on the card type may be made here (see cx18_init_struct2 587 No assumptions on the card type may be made here (see cx18_init_struct2
@@ -553,7 +589,7 @@ done:
553 */ 589 */
554static int __devinit cx18_init_struct1(struct cx18 *cx) 590static int __devinit cx18_init_struct1(struct cx18 *cx)
555{ 591{
556 int i; 592 int ret;
557 593
558 cx->base_addr = pci_resource_start(cx->pci_dev, 0); 594 cx->base_addr = pci_resource_start(cx->pci_dev, 0);
559 595
@@ -562,18 +598,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
562 mutex_init(&cx->epu2apu_mb_lock); 598 mutex_init(&cx->epu2apu_mb_lock);
563 mutex_init(&cx->epu2cpu_mb_lock); 599 mutex_init(&cx->epu2cpu_mb_lock);
564 600
565 cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name); 601 ret = cx18_create_out_workq(cx);
566 if (cx->work_queue == NULL) { 602 if (ret)
567 CX18_ERR("Unable to create work hander thread\n"); 603 return ret;
568 return -ENOMEM;
569 }
570 604
571 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { 605 ret = cx18_create_in_workq(cx);
572 cx->epu_work_order[i].cx = cx; 606 if (ret) {
573 cx->epu_work_order[i].str = cx->epu_debug_str; 607 destroy_workqueue(cx->out_work_queue);
574 INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler); 608 return ret;
575 } 609 }
576 610
611 cx18_init_in_work_orders(cx);
612
577 /* start counting open_id at 1 */ 613 /* start counting open_id at 1 */
578 cx->open_id = 1; 614 cx->open_id = 1;
579 615
@@ -759,17 +795,17 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
759 retval = -ENODEV; 795 retval = -ENODEV;
760 goto err; 796 goto err;
761 } 797 }
762 if (cx18_init_struct1(cx)) { 798
763 retval = -ENOMEM; 799 retval = cx18_init_struct1(cx);
800 if (retval)
764 goto err; 801 goto err;
765 }
766 802
767 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); 803 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
768 804
769 /* PCI Device Setup */ 805 /* PCI Device Setup */
770 retval = cx18_setup_pci(cx, pci_dev, pci_id); 806 retval = cx18_setup_pci(cx, pci_dev, pci_id);
771 if (retval != 0) 807 if (retval != 0)
772 goto free_workqueue; 808 goto free_workqueues;
773 809
774 /* map io memory */ 810 /* map io memory */
775 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", 811 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -943,8 +979,9 @@ free_map:
943 cx18_iounmap(cx); 979 cx18_iounmap(cx);
944free_mem: 980free_mem:
945 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 981 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
946free_workqueue: 982free_workqueues:
947 destroy_workqueue(cx->work_queue); 983 destroy_workqueue(cx->in_work_queue);
984 destroy_workqueue(cx->out_work_queue);
948err: 985err:
949 if (retval == 0) 986 if (retval == 0)
950 retval = -ENODEV; 987 retval = -ENODEV;
@@ -1053,11 +1090,19 @@ int cx18_init_on_first_open(struct cx18 *cx)
1053 return 0; 1090 return 0;
1054} 1091}
1055 1092
1056static void cx18_cancel_epu_work_orders(struct cx18 *cx) 1093static void cx18_cancel_in_work_orders(struct cx18 *cx)
1057{ 1094{
1058 int i; 1095 int i;
1059 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) 1096 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++)
1060 cancel_work_sync(&cx->epu_work_order[i].work); 1097 cancel_work_sync(&cx->in_work_order[i].work);
1098}
1099
1100static void cx18_cancel_out_work_orders(struct cx18 *cx)
1101{
1102 int i;
1103 for (i = 0; i < CX18_MAX_STREAMS; i++)
1104 if (&cx->streams[i].video_dev != NULL)
1105 cancel_work_sync(&cx->streams[i].out_work_order);
1061} 1106}
1062 1107
1063static void cx18_remove(struct pci_dev *pci_dev) 1108static void cx18_remove(struct pci_dev *pci_dev)
@@ -1073,15 +1118,20 @@ static void cx18_remove(struct pci_dev *pci_dev)
1073 if (atomic_read(&cx->tot_capturing) > 0) 1118 if (atomic_read(&cx->tot_capturing) > 0)
1074 cx18_stop_all_captures(cx); 1119 cx18_stop_all_captures(cx);
1075 1120
1076 /* Interrupts */ 1121 /* Stop interrupts that cause incoming work to be queued */
1077 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); 1122 cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
1123
1124 /* Incoming work can cause outgoing work, so clean up incoming first */
1125 cx18_cancel_in_work_orders(cx);
1126 cx18_cancel_out_work_orders(cx);
1127
1128 /* Stop ack interrupts that may have been needed for work to finish */
1078 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); 1129 cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
1079 1130
1080 cx18_halt_firmware(cx); 1131 cx18_halt_firmware(cx);
1081 1132
1082 cx18_cancel_epu_work_orders(cx); 1133 destroy_workqueue(cx->in_work_queue);
1083 1134 destroy_workqueue(cx->out_work_queue);
1084 destroy_workqueue(cx->work_queue);
1085 1135
1086 cx18_streams_cleanup(cx, 1); 1136 cx18_streams_cleanup(cx, 1);
1087 1137
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index ece4f281ef42..c6a1e907f63a 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -80,8 +80,9 @@
80#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ 80#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
81#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ 81#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
82#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ 82#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
83#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */ 83#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
84#define CX18_CARD_LAST 6 84#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
85#define CX18_CARD_LAST 7
85 86
86#define CX18_ENC_STREAM_TYPE_MPG 0 87#define CX18_ENC_STREAM_TYPE_MPG 0
87#define CX18_ENC_STREAM_TYPE_TS 1 88#define CX18_ENC_STREAM_TYPE_TS 1
@@ -254,6 +255,7 @@ struct cx18_options {
254#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ 255#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
255#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ 256#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
256#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ 257#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
258#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
257 259
258/* per-cx18, i_flags */ 260/* per-cx18, i_flags */
259#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ 261#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
@@ -285,6 +287,7 @@ struct cx18_queue {
285 struct list_head list; 287 struct list_head list;
286 atomic_t buffers; 288 atomic_t buffers;
287 u32 bytesused; 289 u32 bytesused;
290 spinlock_t lock;
288}; 291};
289 292
290struct cx18_dvb { 293struct cx18_dvb {
@@ -305,7 +308,7 @@ struct cx18_scb; /* forward reference */
305 308
306 309
307#define CX18_MAX_MDL_ACKS 2 310#define CX18_MAX_MDL_ACKS 2
308#define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) 311#define CX18_MAX_IN_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7)
309/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ 312/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */
310 313
311#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 314#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1
@@ -313,7 +316,7 @@ struct cx18_scb; /* forward reference */
313#define CX18_F_EWO_MB_STALE \ 316#define CX18_F_EWO_MB_STALE \
314 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) 317 (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC)
315 318
316struct cx18_epu_work_order { 319struct cx18_in_work_order {
317 struct work_struct work; 320 struct work_struct work;
318 atomic_t pending; 321 atomic_t pending;
319 struct cx18 *cx; 322 struct cx18 *cx;
@@ -337,7 +340,6 @@ struct cx18_stream {
337 unsigned mdl_offset; 340 unsigned mdl_offset;
338 341
339 u32 id; 342 u32 id;
340 struct mutex qlock; /* locks access to the queues */
341 unsigned long s_flags; /* status flags, see above */ 343 unsigned long s_flags; /* status flags, see above */
342 int dma; /* can be PCI_DMA_TODEVICE, 344 int dma; /* can be PCI_DMA_TODEVICE,
343 PCI_DMA_FROMDEVICE or 345 PCI_DMA_FROMDEVICE or
@@ -353,6 +355,8 @@ struct cx18_stream {
353 struct cx18_queue q_busy; /* busy buffers - in use by firmware */ 355 struct cx18_queue q_busy; /* busy buffers - in use by firmware */
354 struct cx18_queue q_full; /* full buffers - data for user apps */ 356 struct cx18_queue q_full; /* full buffers - data for user apps */
355 357
358 struct work_struct out_work_order;
359
356 /* DVB / Digital Transport */ 360 /* DVB / Digital Transport */
357 struct cx18_dvb dvb; 361 struct cx18_dvb dvb;
358}; 362};
@@ -568,10 +572,14 @@ struct cx18 {
568 u32 sw2_irq_mask; 572 u32 sw2_irq_mask;
569 u32 hw2_irq_mask; 573 u32 hw2_irq_mask;
570 574
571 struct workqueue_struct *work_queue; 575 struct workqueue_struct *in_work_queue;
572 struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS]; 576 char in_workq_name[11]; /* "cx18-NN-in" */
577 struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
573 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ 578 char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
574 579
580 struct workqueue_struct *out_work_queue;
581 char out_workq_name[12]; /* "cx18-NN-out" */
582
575 /* i2c */ 583 /* i2c */
576 struct i2c_adapter i2c_adap[2]; 584 struct i2c_adapter i2c_adap[2];
577 struct i2c_algo_bit_data i2c_algo[2]; 585 struct i2c_algo_bit_data i2c_algo[2];
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 3b86f57cd15a..6ea3fe623ef4 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -23,14 +23,20 @@
23#include "cx18-version.h" 23#include "cx18-version.h"
24#include "cx18-dvb.h" 24#include "cx18-dvb.h"
25#include "cx18-io.h" 25#include "cx18-io.h"
26#include "cx18-queue.h"
26#include "cx18-streams.h" 27#include "cx18-streams.h"
27#include "cx18-cards.h" 28#include "cx18-cards.h"
29#include "cx18-gpio.h"
28#include "s5h1409.h" 30#include "s5h1409.h"
29#include "mxl5005s.h" 31#include "mxl5005s.h"
32#include "zl10353.h"
33#include "tuner-xc2028.h"
30 34
31DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 35DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
32 36
33#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 37#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
38#define CX18_CLOCK_ENABLE2 0xc71024
39#define CX18_DMUX_CLK_MASK 0x0080
34 40
35static struct mxl5005s_config hauppauge_hvr1600_tuner = { 41static struct mxl5005s_config hauppauge_hvr1600_tuner = {
36 .i2c_address = 0xC6 >> 1, 42 .i2c_address = 0xC6 >> 1,
@@ -57,7 +63,15 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
57 .inversion = S5H1409_INVERSION_OFF, 63 .inversion = S5H1409_INVERSION_OFF,
58 .status_mode = S5H1409_DEMODLOCKING, 64 .status_mode = S5H1409_DEMODLOCKING,
59 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 65 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
66};
60 67
68/* Information/confirmation of proper config values provided by Terry Wu */
69static struct zl10353_config leadtek_dvr3100h_demod = {
70 .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
71 .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
72 .parallel_ts = 1, /* Not a serial TS */
73 .no_tuner = 1, /* XC3028 is not behind the gate */
74 .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
61}; 75};
62 76
63static int dvb_register(struct cx18_stream *stream); 77static int dvb_register(struct cx18_stream *stream);
@@ -98,6 +112,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
98 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); 112 cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
99 break; 113 break;
100 114
115 case CX18_CARD_LEADTEK_DVR3100H:
101 default: 116 default:
102 /* Assumption - Parallel transport - Signalling 117 /* Assumption - Parallel transport - Signalling
103 * undefined or default. 118 * undefined or default.
@@ -267,8 +282,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream)
267} 282}
268 283
269/* All the DVB attach calls go here, this function get's modified 284/* All the DVB attach calls go here, this function get's modified
270 * for each new card. No other function in this file needs 285 * for each new card. cx18_dvb_start_feed() will also need changes.
271 * to change.
272 */ 286 */
273static int dvb_register(struct cx18_stream *stream) 287static int dvb_register(struct cx18_stream *stream)
274{ 288{
@@ -289,6 +303,29 @@ static int dvb_register(struct cx18_stream *stream)
289 ret = 0; 303 ret = 0;
290 } 304 }
291 break; 305 break;
306 case CX18_CARD_LEADTEK_DVR3100H:
307 dvb->fe = dvb_attach(zl10353_attach,
308 &leadtek_dvr3100h_demod,
309 &cx->i2c_adap[1]);
310 if (dvb->fe != NULL) {
311 struct dvb_frontend *fe;
312 struct xc2028_config cfg = {
313 .i2c_adap = &cx->i2c_adap[1],
314 .i2c_addr = 0xc2 >> 1,
315 .ctrl = NULL,
316 };
317 static struct xc2028_ctrl ctrl = {
318 .fname = XC2028_DEFAULT_FIRMWARE,
319 .max_len = 64,
320 .demod = XC3028_FE_ZARLINK456,
321 .type = XC2028_AUTO,
322 };
323
324 fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
325 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
326 fe->ops.tuner_ops.set_config(fe, &ctrl);
327 }
328 break;
292 default: 329 default:
293 /* No Digital Tv Support */ 330 /* No Digital Tv Support */
294 break; 331 break;
@@ -299,6 +336,8 @@ static int dvb_register(struct cx18_stream *stream)
299 return -1; 336 return -1;
300 } 337 }
301 338
339 dvb->fe->callback = cx18_reset_tuner_gpio;
340
302 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); 341 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
303 if (ret < 0) { 342 if (ret < 0) {
304 if (dvb->fe->ops.release) 343 if (dvb->fe->ops.release)
@@ -306,5 +345,16 @@ static int dvb_register(struct cx18_stream *stream)
306 return ret; 345 return ret;
307 } 346 }
308 347
348 /*
349 * The firmware seems to enable the TS DMUX clock
350 * under various circumstances. However, since we know we
351 * might use it, let's just turn it on ourselves here.
352 */
353 cx18_write_reg_expect(cx,
354 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK,
355 CX18_CLOCK_ENABLE2,
356 CX18_DMUX_CLK_MASK,
357 (CX18_DMUX_CLK_MASK << 16) | CX18_DMUX_CLK_MASK);
358
309 return ret; 359 return ret;
310} 360}
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index b3889c0b2697..29969c18949c 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -265,8 +265,13 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
265 * an MPEG-2 Program Pack start code, and provide only 265 * an MPEG-2 Program Pack start code, and provide only
266 * up to that point to the user, so it's easy to insert VBI data 266 * up to that point to the user, so it's easy to insert VBI data
267 * the next time around. 267 * the next time around.
268 *
269 * This will not work for an MPEG-2 TS and has only been
270 * verified by analysis to work for an MPEG-2 PS. Helen Buus
271 * pointed out this works for the CX23416 MPEG-2 DVD compatible
272 * stream, and research indicates both the MPEG 2 SVCD and DVD
273 * stream types use an MPEG-2 PS container.
268 */ 274 */
269 /* FIXME - This only works for an MPEG-2 PS, not a TS */
270 /* 275 /*
271 * An MPEG-2 Program Stream (PS) is a series of 276 * An MPEG-2 Program Stream (PS) is a series of
272 * MPEG-2 Program Packs terminated by an 277 * MPEG-2 Program Packs terminated by an
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2226e5791e99..afe46c3d4057 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,7 +131,7 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
131 * Functions that run in a work_queue work handling context 131 * Functions that run in a work_queue work handling context
132 */ 132 */
133 133
134static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) 134static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
135{ 135{
136 u32 handle, mdl_ack_count, id; 136 u32 handle, mdl_ack_count, id;
137 struct cx18_mailbox *mb; 137 struct cx18_mailbox *mb;
@@ -191,29 +191,30 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
191 if (buf == NULL) { 191 if (buf == NULL) {
192 CX18_WARN("Could not find buf %d for stream %s\n", 192 CX18_WARN("Could not find buf %d for stream %s\n",
193 id, s->name); 193 id, s->name);
194 /* Put as many buffers as possible back into fw use */
195 cx18_stream_load_fw_queue(s);
196 continue; 194 continue;
197 } 195 }
198 196
199 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { 197 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
200 CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", 198 s->name, buf->bytesused);
201 buf->bytesused); 199
202 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 200 if (s->type != CX18_ENC_STREAM_TYPE_TS)
203 buf->bytesused); 201 cx18_enqueue(s, buf, &s->q_full);
202 else {
203 if (s->dvb.enabled)
204 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
205 buf->bytesused);
206 cx18_enqueue(s, buf, &s->q_free);
204 } 207 }
205 /* Put as many buffers as possible back into fw use */
206 cx18_stream_load_fw_queue(s);
207 /* Put back TS buffer, since it was removed from all queues */
208 if (s->type == CX18_ENC_STREAM_TYPE_TS)
209 cx18_stream_put_buf_fw(s, buf);
210 } 208 }
209 /* Put as many buffers as possible back into fw use */
210 cx18_stream_load_fw_queue(s);
211
211 wake_up(&cx->dma_waitq); 212 wake_up(&cx->dma_waitq);
212 if (s->id != -1) 213 if (s->id != -1)
213 wake_up(&s->waitq); 214 wake_up(&s->waitq);
214} 215}
215 216
216static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) 217static void epu_debug(struct cx18 *cx, struct cx18_in_work_order *order)
217{ 218{
218 char *p; 219 char *p;
219 char *str = order->str; 220 char *str = order->str;
@@ -224,7 +225,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order)
224 CX18_INFO("FW version: %s\n", p - 1); 225 CX18_INFO("FW version: %s\n", p - 1);
225} 226}
226 227
227static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) 228static void epu_cmd(struct cx18 *cx, struct cx18_in_work_order *order)
228{ 229{
229 switch (order->rpu) { 230 switch (order->rpu) {
230 case CPU: 231 case CPU:
@@ -253,18 +254,18 @@ static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order)
253} 254}
254 255
255static 256static
256void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order) 257void free_in_work_order(struct cx18 *cx, struct cx18_in_work_order *order)
257{ 258{
258 atomic_set(&order->pending, 0); 259 atomic_set(&order->pending, 0);
259} 260}
260 261
261void cx18_epu_work_handler(struct work_struct *work) 262void cx18_in_work_handler(struct work_struct *work)
262{ 263{
263 struct cx18_epu_work_order *order = 264 struct cx18_in_work_order *order =
264 container_of(work, struct cx18_epu_work_order, work); 265 container_of(work, struct cx18_in_work_order, work);
265 struct cx18 *cx = order->cx; 266 struct cx18 *cx = order->cx;
266 epu_cmd(cx, order); 267 epu_cmd(cx, order);
267 free_epu_work_order(cx, order); 268 free_in_work_order(cx, order);
268} 269}
269 270
270 271
@@ -272,7 +273,7 @@ void cx18_epu_work_handler(struct work_struct *work)
272 * Functions that run in an interrupt handling context 273 * Functions that run in an interrupt handling context
273 */ 274 */
274 275
275static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 276static void mb_ack_irq(struct cx18 *cx, struct cx18_in_work_order *order)
276{ 277{
277 struct cx18_mailbox __iomem *ack_mb; 278 struct cx18_mailbox __iomem *ack_mb;
278 u32 ack_irq, req; 279 u32 ack_irq, req;
@@ -308,7 +309,7 @@ static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
308 return; 309 return;
309} 310}
310 311
311static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 312static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order)
312{ 313{
313 u32 handle, mdl_ack_offset, mdl_ack_count; 314 u32 handle, mdl_ack_offset, mdl_ack_count;
314 struct cx18_mailbox *mb; 315 struct cx18_mailbox *mb;
@@ -334,7 +335,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
334} 335}
335 336
336static 337static
337int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 338int epu_debug_irq(struct cx18 *cx, struct cx18_in_work_order *order)
338{ 339{
339 u32 str_offset; 340 u32 str_offset;
340 char *str = order->str; 341 char *str = order->str;
@@ -355,7 +356,7 @@ int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
355} 356}
356 357
357static inline 358static inline
358int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) 359int epu_cmd_irq(struct cx18 *cx, struct cx18_in_work_order *order)
359{ 360{
360 int ret = -1; 361 int ret = -1;
361 362
@@ -387,12 +388,12 @@ int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order)
387} 388}
388 389
389static inline 390static inline
390struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) 391struct cx18_in_work_order *alloc_in_work_order_irq(struct cx18 *cx)
391{ 392{
392 int i; 393 int i;
393 struct cx18_epu_work_order *order = NULL; 394 struct cx18_in_work_order *order = NULL;
394 395
395 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { 396 for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) {
396 /* 397 /*
397 * We only need "pending" atomic to inspect its contents, 398 * We only need "pending" atomic to inspect its contents,
398 * and need not do a check and set because: 399 * and need not do a check and set because:
@@ -401,8 +402,8 @@ struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx)
401 * 2. "pending" is only set here, and we're serialized because 402 * 2. "pending" is only set here, and we're serialized because
402 * we're called in an IRQ handler context. 403 * we're called in an IRQ handler context.
403 */ 404 */
404 if (atomic_read(&cx->epu_work_order[i].pending) == 0) { 405 if (atomic_read(&cx->in_work_order[i].pending) == 0) {
405 order = &cx->epu_work_order[i]; 406 order = &cx->in_work_order[i];
406 atomic_set(&order->pending, 1); 407 atomic_set(&order->pending, 1);
407 break; 408 break;
408 } 409 }
@@ -414,7 +415,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
414{ 415{
415 struct cx18_mailbox __iomem *mb; 416 struct cx18_mailbox __iomem *mb;
416 struct cx18_mailbox *order_mb; 417 struct cx18_mailbox *order_mb;
417 struct cx18_epu_work_order *order; 418 struct cx18_in_work_order *order;
418 int submit; 419 int submit;
419 420
420 switch (rpu) { 421 switch (rpu) {
@@ -428,7 +429,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
428 return; 429 return;
429 } 430 }
430 431
431 order = alloc_epu_work_order_irq(cx); 432 order = alloc_in_work_order_irq(cx);
432 if (order == NULL) { 433 if (order == NULL) {
433 CX18_WARN("Unable to find blank work order form to schedule " 434 CX18_WARN("Unable to find blank work order form to schedule "
434 "incoming mailbox command processing\n"); 435 "incoming mailbox command processing\n");
@@ -461,7 +462,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
461 */ 462 */
462 submit = epu_cmd_irq(cx, order); 463 submit = epu_cmd_irq(cx, order);
463 if (submit > 0) { 464 if (submit > 0) {
464 queue_work(cx->work_queue, &order->work); 465 queue_work(cx->in_work_queue, &order->work);
465 } 466 }
466} 467}
467 468
@@ -478,9 +479,10 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
478 u32 __iomem *xpu_state; 479 u32 __iomem *xpu_state;
479 wait_queue_head_t *waitq; 480 wait_queue_head_t *waitq;
480 struct mutex *mb_lock; 481 struct mutex *mb_lock;
481 long int timeout, ret; 482 unsigned long int t0, timeout, ret;
482 int i; 483 int i;
483 char argstr[MAX_MB_ARGUMENTS*11+1]; 484 char argstr[MAX_MB_ARGUMENTS*11+1];
485 DEFINE_WAIT(w);
484 486
485 if (info == NULL) { 487 if (info == NULL) {
486 CX18_WARN("unknown cmd %x\n", cmd); 488 CX18_WARN("unknown cmd %x\n", cmd);
@@ -562,25 +564,49 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
562 564
563 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", 565 CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n",
564 irq, info->name); 566 irq, info->name);
567
568 /* So we don't miss the wakeup, prepare to wait before notifying fw */
569 prepare_to_wait(waitq, &w, TASK_UNINTERRUPTIBLE);
565 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); 570 cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq);
566 571
567 ret = wait_event_timeout( 572 t0 = jiffies;
568 *waitq, 573 ack = cx18_readl(cx, &mb->ack);
569 cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), 574 if (ack != req) {
570 timeout); 575 schedule_timeout(timeout);
576 ret = jiffies - t0;
577 ack = cx18_readl(cx, &mb->ack);
578 } else {
579 ret = jiffies - t0;
580 }
571 581
572 if (ret == 0) { 582 finish_wait(waitq, &w);
573 /* Timed out */ 583
584 if (req != ack) {
574 mutex_unlock(mb_lock); 585 mutex_unlock(mb_lock);
575 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " 586 if (ret >= timeout) {
576 "acknowledgement\n", 587 /* Timed out */
577 info->name, jiffies_to_msecs(timeout)); 588 CX18_DEBUG_WARN("sending %s timed out waiting %d msecs "
589 "for RPU acknowledgement\n",
590 info->name, jiffies_to_msecs(ret));
591 } else {
592 CX18_DEBUG_WARN("woken up before mailbox ack was ready "
593 "after submitting %s to RPU. only "
594 "waited %d msecs on req %u but awakened"
595 " with unmatched ack %u\n",
596 info->name,
597 jiffies_to_msecs(ret),
598 req, ack);
599 }
578 return -EINVAL; 600 return -EINVAL;
579 } 601 }
580 602
581 if (ret != timeout) 603 if (ret >= timeout)
604 CX18_DEBUG_WARN("failed to be awakened upon RPU acknowledgment "
605 "sending %s; timed out waiting %d msecs\n",
606 info->name, jiffies_to_msecs(ret));
607 else
582 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", 608 CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n",
583 jiffies_to_msecs(timeout-ret), info->name); 609 jiffies_to_msecs(ret), info->name);
584 610
585 /* Collect data returned by the XPU */ 611 /* Collect data returned by the XPU */
586 for (i = 0; i < MAX_MB_ARGUMENTS; i++) 612 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index ce2b6686aa00..e23aaac5b280 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -95,6 +95,6 @@ int cx18_api_func(void *priv, u32 cmd, int in, int out,
95 95
96void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); 96void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu);
97 97
98void cx18_epu_work_handler(struct work_struct *work); 98void cx18_in_work_handler(struct work_struct *work);
99 99
100#endif 100#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 3046b8e74345..fa1ed7897d97 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -23,8 +23,8 @@
23 */ 23 */
24 24
25#include "cx18-driver.h" 25#include "cx18-driver.h"
26#include "cx18-streams.h"
27#include "cx18-queue.h" 26#include "cx18-queue.h"
27#include "cx18-streams.h"
28#include "cx18-scb.h" 28#include "cx18-scb.h"
29 29
30void cx18_buf_swap(struct cx18_buffer *buf) 30void cx18_buf_swap(struct cx18_buffer *buf)
@@ -53,13 +53,13 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
53 buf->skipped = 0; 53 buf->skipped = 0;
54 } 54 }
55 55
56 mutex_lock(&s->qlock);
57
58 /* q_busy is restricted to a max buffer count imposed by firmware */ 56 /* q_busy is restricted to a max buffer count imposed by firmware */
59 if (q == &s->q_busy && 57 if (q == &s->q_busy &&
60 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) 58 atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM)
61 q = &s->q_free; 59 q = &s->q_free;
62 60
61 spin_lock(&q->lock);
62
63 if (to_front) 63 if (to_front)
64 list_add(&buf->list, &q->list); /* LIFO */ 64 list_add(&buf->list, &q->list); /* LIFO */
65 else 65 else
@@ -67,7 +67,7 @@ struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
67 q->bytesused += buf->bytesused - buf->readpos; 67 q->bytesused += buf->bytesused - buf->readpos;
68 atomic_inc(&q->buffers); 68 atomic_inc(&q->buffers);
69 69
70 mutex_unlock(&s->qlock); 70 spin_unlock(&q->lock);
71 return q; 71 return q;
72} 72}
73 73
@@ -75,7 +75,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
75{ 75{
76 struct cx18_buffer *buf = NULL; 76 struct cx18_buffer *buf = NULL;
77 77
78 mutex_lock(&s->qlock); 78 spin_lock(&q->lock);
79 if (!list_empty(&q->list)) { 79 if (!list_empty(&q->list)) {
80 buf = list_first_entry(&q->list, struct cx18_buffer, list); 80 buf = list_first_entry(&q->list, struct cx18_buffer, list);
81 list_del_init(&buf->list); 81 list_del_init(&buf->list);
@@ -83,7 +83,7 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
83 buf->skipped = 0; 83 buf->skipped = 0;
84 atomic_dec(&q->buffers); 84 atomic_dec(&q->buffers);
85 } 85 }
86 mutex_unlock(&s->qlock); 86 spin_unlock(&q->lock);
87 return buf; 87 return buf;
88} 88}
89 89
@@ -94,9 +94,23 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
94 struct cx18_buffer *buf; 94 struct cx18_buffer *buf;
95 struct cx18_buffer *tmp; 95 struct cx18_buffer *tmp;
96 struct cx18_buffer *ret = NULL; 96 struct cx18_buffer *ret = NULL;
97 97 LIST_HEAD(sweep_up);
98 mutex_lock(&s->qlock); 98
99 /*
100 * We don't have to acquire multiple q locks here, because we are
101 * serialized by the single threaded work handler.
102 * Buffers from the firmware will thus remain in order as
103 * they are moved from q_busy to q_full or to the dvb ring buffer.
104 */
105 spin_lock(&s->q_busy.lock);
99 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { 106 list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) {
107 /*
108 * We should find what the firmware told us is done,
109 * right at the front of the queue. If we don't, we likely have
110 * missed a buffer done message from the firmware.
111 * Once we skip a buffer repeatedly, relative to the size of
112 * q_busy, we have high confidence we've missed it.
113 */
100 if (buf->id != id) { 114 if (buf->id != id) {
101 buf->skipped++; 115 buf->skipped++;
102 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { 116 if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) {
@@ -105,38 +119,41 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
105 "times - it must have dropped out of " 119 "times - it must have dropped out of "
106 "rotation\n", s->name, buf->id, 120 "rotation\n", s->name, buf->id,
107 buf->skipped); 121 buf->skipped);
108 /* move it to q_free */ 122 /* Sweep it up to put it back into rotation */
109 list_move_tail(&buf->list, &s->q_free.list); 123 list_move_tail(&buf->list, &sweep_up);
110 buf->bytesused = buf->readpos = buf->b_flags =
111 buf->skipped = 0;
112 atomic_dec(&s->q_busy.buffers); 124 atomic_dec(&s->q_busy.buffers);
113 atomic_inc(&s->q_free.buffers);
114 } 125 }
115 continue; 126 continue;
116 } 127 }
117 128 /*
118 buf->bytesused = bytesused; 129 * We pull the desired buffer off of the queue here. Something
119 /* Sync the buffer before we release the qlock */ 130 * will have to put it back on a queue later.
120 cx18_buf_sync_for_cpu(s, buf); 131 */
121 if (s->type == CX18_ENC_STREAM_TYPE_TS) { 132 list_del_init(&buf->list);
122 /*
123 * TS doesn't use q_full. As we pull the buffer off of
124 * the queue here, the caller will have to put it back.
125 */
126 list_del_init(&buf->list);
127 } else {
128 /* Move buffer from q_busy to q_full */
129 list_move_tail(&buf->list, &s->q_full.list);
130 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
131 s->q_full.bytesused += buf->bytesused;
132 atomic_inc(&s->q_full.buffers);
133 }
134 atomic_dec(&s->q_busy.buffers); 133 atomic_dec(&s->q_busy.buffers);
135
136 ret = buf; 134 ret = buf;
137 break; 135 break;
138 } 136 }
139 mutex_unlock(&s->qlock); 137 spin_unlock(&s->q_busy.lock);
138
139 /*
140 * We found the buffer for which we were looking. Get it ready for
141 * the caller to put on q_full or in the dvb ring buffer.
142 */
143 if (ret != NULL) {
144 ret->bytesused = bytesused;
145 ret->skipped = 0;
146 /* readpos and b_flags were 0'ed when the buf went on q_busy */
147 cx18_buf_sync_for_cpu(s, ret);
148 if (s->type != CX18_ENC_STREAM_TYPE_TS)
149 set_bit(CX18_F_B_NEED_BUF_SWAP, &ret->b_flags);
150 }
151
152 /* Put any buffers the firmware is ignoring back into normal rotation */
153 list_for_each_entry_safe(buf, tmp, &sweep_up, list) {
154 list_del_init(&buf->list);
155 cx18_enqueue(s, buf, &s->q_free);
156 }
140 return ret; 157 return ret;
141} 158}
142 159
@@ -148,7 +165,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
148 if (q == &s->q_free) 165 if (q == &s->q_free)
149 return; 166 return;
150 167
151 mutex_lock(&s->qlock); 168 spin_lock(&q->lock);
152 while (!list_empty(&q->list)) { 169 while (!list_empty(&q->list)) {
153 buf = list_first_entry(&q->list, struct cx18_buffer, list); 170 buf = list_first_entry(&q->list, struct cx18_buffer, list);
154 list_move_tail(&buf->list, &s->q_free.list); 171 list_move_tail(&buf->list, &s->q_free.list);
@@ -156,7 +173,7 @@ static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
156 atomic_inc(&s->q_free.buffers); 173 atomic_inc(&s->q_free.buffers);
157 } 174 }
158 cx18_queue_init(q); 175 cx18_queue_init(q);
159 mutex_unlock(&s->qlock); 176 spin_unlock(&q->lock);
160} 177}
161 178
162void cx18_flush_queues(struct cx18_stream *s) 179void cx18_flush_queues(struct cx18_stream *s)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 0932b76b2373..54d248e16d85 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -116,12 +116,16 @@ static void cx18_stream_init(struct cx18 *cx, int type)
116 s->buffers = cx->stream_buffers[type]; 116 s->buffers = cx->stream_buffers[type];
117 s->buf_size = cx->stream_buf_size[type]; 117 s->buf_size = cx->stream_buf_size[type];
118 118
119 mutex_init(&s->qlock);
120 init_waitqueue_head(&s->waitq); 119 init_waitqueue_head(&s->waitq);
121 s->id = -1; 120 s->id = -1;
121 spin_lock_init(&s->q_free.lock);
122 cx18_queue_init(&s->q_free); 122 cx18_queue_init(&s->q_free);
123 spin_lock_init(&s->q_busy.lock);
123 cx18_queue_init(&s->q_busy); 124 cx18_queue_init(&s->q_busy);
125 spin_lock_init(&s->q_full.lock);
124 cx18_queue_init(&s->q_full); 126 cx18_queue_init(&s->q_full);
127
128 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
125} 129}
126 130
127static int cx18_prep_dev(struct cx18 *cx, int type) 131static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -367,9 +371,14 @@ static void cx18_vbi_setup(struct cx18_stream *s)
367 * Tell the encoder to capture 21-4+1=18 lines per field, 371 * Tell the encoder to capture 21-4+1=18 lines per field,
368 * since we want lines 10 through 21. 372 * since we want lines 10 through 21.
369 * 373 *
370 * FIXME - revisit for 625/50 systems 374 * For 625/50 systems, according to the VIP 2 & BT.656 std:
375 * The EAV RP code's Field bit toggles on line 1, a few lines
376 * after the Vertcal Blank bit has already toggled.
377 * (We've actually set the digitizer so that the Field bit
378 * toggles on line 2.) Tell the encoder to capture 23-2+1=22
379 * lines per field, since we want lines 6 through 23.
371 */ 380 */
372 lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38; 381 lines = cx->is_60hz ? (21 - 4 + 1) * 2 : (23 - 2 + 1) * 2;
373 } 382 }
374 383
375 data[0] = s->handle; 384 data[0] = s->handle;
@@ -431,14 +440,16 @@ static void cx18_vbi_setup(struct cx18_stream *s)
431 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 440 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
432} 441}
433 442
434struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, 443static
435 struct cx18_buffer *buf) 444struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
445 struct cx18_buffer *buf)
436{ 446{
437 struct cx18 *cx = s->cx; 447 struct cx18 *cx = s->cx;
438 struct cx18_queue *q; 448 struct cx18_queue *q;
439 449
440 /* Don't give it to the firmware, if we're not running a capture */ 450 /* Don't give it to the firmware, if we're not running a capture */
441 if (s->handle == CX18_INVALID_TASK_HANDLE || 451 if (s->handle == CX18_INVALID_TASK_HANDLE ||
452 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
442 !test_bit(CX18_F_S_STREAMING, &s->s_flags)) 453 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
443 return cx18_enqueue(s, buf, &s->q_free); 454 return cx18_enqueue(s, buf, &s->q_free);
444 455
@@ -453,7 +464,8 @@ struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
453 return q; 464 return q;
454} 465}
455 466
456void cx18_stream_load_fw_queue(struct cx18_stream *s) 467static
468void _cx18_stream_load_fw_queue(struct cx18_stream *s)
457{ 469{
458 struct cx18_queue *q; 470 struct cx18_queue *q;
459 struct cx18_buffer *buf; 471 struct cx18_buffer *buf;
@@ -467,11 +479,19 @@ void cx18_stream_load_fw_queue(struct cx18_stream *s)
467 buf = cx18_dequeue(s, &s->q_free); 479 buf = cx18_dequeue(s, &s->q_free);
468 if (buf == NULL) 480 if (buf == NULL)
469 break; 481 break;
470 q = cx18_stream_put_buf_fw(s, buf); 482 q = _cx18_stream_put_buf_fw(s, buf);
471 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM 483 } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM
472 && q == &s->q_busy); 484 && q == &s->q_busy);
473} 485}
474 486
487void cx18_out_work_handler(struct work_struct *work)
488{
489 struct cx18_stream *s =
490 container_of(work, struct cx18_stream, out_work_order);
491
492 _cx18_stream_load_fw_queue(s);
493}
494
475int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 495int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
476{ 496{
477 u32 data[MAX_MB_ARGUMENTS]; 497 u32 data[MAX_MB_ARGUMENTS];
@@ -600,19 +620,20 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
600 620
601 /* Init all the cpu_mdls for this stream */ 621 /* Init all the cpu_mdls for this stream */
602 cx18_flush_queues(s); 622 cx18_flush_queues(s);
603 mutex_lock(&s->qlock); 623 spin_lock(&s->q_free.lock);
604 list_for_each_entry(buf, &s->q_free.list, list) { 624 list_for_each_entry(buf, &s->q_free.list, list) {
605 cx18_writel(cx, buf->dma_handle, 625 cx18_writel(cx, buf->dma_handle,
606 &cx->scb->cpu_mdl[buf->id].paddr); 626 &cx->scb->cpu_mdl[buf->id].paddr);
607 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); 627 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
608 } 628 }
609 mutex_unlock(&s->qlock); 629 spin_unlock(&s->q_free.lock);
610 cx18_stream_load_fw_queue(s); 630 _cx18_stream_load_fw_queue(s);
611 631
612 /* begin_capture */ 632 /* begin_capture */
613 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { 633 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
614 CX18_DEBUG_WARN("Error starting capture!\n"); 634 CX18_DEBUG_WARN("Error starting capture!\n");
615 /* Ensure we're really not capturing before releasing MDLs */ 635 /* Ensure we're really not capturing before releasing MDLs */
636 set_bit(CX18_F_S_STOPPING, &s->s_flags);
616 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 637 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
617 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); 638 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1);
618 else 639 else
@@ -622,6 +643,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
622 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); 643 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
623 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 644 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
624 s->handle = CX18_INVALID_TASK_HANDLE; 645 s->handle = CX18_INVALID_TASK_HANDLE;
646 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
625 if (atomic_read(&cx->tot_capturing) == 0) { 647 if (atomic_read(&cx->tot_capturing) == 0) {
626 set_bit(CX18_F_I_EOS, &cx->i_flags); 648 set_bit(CX18_F_I_EOS, &cx->i_flags);
627 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); 649 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
@@ -666,6 +688,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
666 if (atomic_read(&cx->tot_capturing) == 0) 688 if (atomic_read(&cx->tot_capturing) == 0)
667 return 0; 689 return 0;
668 690
691 set_bit(CX18_F_S_STOPPING, &s->s_flags);
669 if (s->type == CX18_ENC_STREAM_TYPE_MPG) 692 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
670 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); 693 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
671 else 694 else
@@ -689,6 +712,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
689 712
690 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 713 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
691 s->handle = CX18_INVALID_TASK_HANDLE; 714 s->handle = CX18_INVALID_TASK_HANDLE;
715 clear_bit(CX18_F_S_STOPPING, &s->s_flags);
692 716
693 if (atomic_read(&cx->tot_capturing) > 0) 717 if (atomic_read(&cx->tot_capturing) > 0)
694 return 0; 718 return 0;
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 420e0a172945..1afc3fd9d822 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -28,10 +28,24 @@ int cx18_streams_setup(struct cx18 *cx);
28int cx18_streams_register(struct cx18 *cx); 28int cx18_streams_register(struct cx18 *cx);
29void cx18_streams_cleanup(struct cx18 *cx, int unregister); 29void cx18_streams_cleanup(struct cx18 *cx, int unregister);
30 30
31/* Related to submission of buffers to firmware */
32static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
33{
34 struct cx18 *cx = s->cx;
35 queue_work(cx->out_work_queue, &s->out_work_order);
36}
37
38static inline void cx18_stream_put_buf_fw(struct cx18_stream *s,
39 struct cx18_buffer *buf)
40{
41 /* Put buf on q_free; the out work handler will move buf(s) to q_busy */
42 cx18_enqueue(s, buf, &s->q_free);
43 cx18_stream_load_fw_queue(s);
44}
45
46void cx18_out_work_handler(struct work_struct *work);
47
31/* Capture related */ 48/* Capture related */
32void cx18_stream_load_fw_queue(struct cx18_stream *s);
33struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
34 struct cx18_buffer *buf);
35int cx18_start_v4l2_encode_stream(struct cx18_stream *s); 49int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
36int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); 50int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
37 51
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index bd9bd44da791..45494b094e7f 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 1 27#define CX18_DRIVER_VERSION_MINOR 2
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/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 1be3881be991..6a9464079b4c 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -29,7 +29,6 @@
29#include <linux/bitmap.h> 29#include <linux/bitmap.h>
30#include <linux/usb.h> 30#include <linux/usb.h>
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/version.h>
33#include <linux/mm.h> 32#include <linux/mm.h>
34#include <linux/mutex.h> 33#include <linux/mutex.h>
35 34
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index c8a32b1b5381..63d2239fd324 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -281,12 +281,12 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
281} 281}
282 282
283/* ----------------------------------------------------------------------- */ 283/* ----------------------------------------------------------------------- */
284void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir) 284void cx231xx_register_i2c_ir(struct cx231xx *dev)
285{ 285{
286 if (disable_ir) { 286 if (disable_ir)
287 ir->get_key = NULL;
288 return; 287 return;
289 } 288
289 /* REVISIT: instantiate IR device */
290 290
291 /* detect & configure */ 291 /* detect & configure */
292 switch (dev->model) { 292 switch (dev->model) {
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index b4a03d813e00..33219dc4d649 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap)
424 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; 424 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
425} 425}
426 426
427/*
428 * attach_inform()
429 * gets called when a device attaches to the i2c bus
430 * does some basic configuration
431 */
432static int attach_inform(struct i2c_client *client)
433{
434 struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
435 struct cx231xx *dev = bus->dev;
436
437 switch (client->addr << 1) {
438 case 0x8e:
439 {
440 struct IR_i2c *ir = i2c_get_clientdata(client);
441 dprintk1(1, "attach_inform: IR detected (%s).\n",
442 ir->phys);
443 cx231xx_set_ir(dev, ir);
444 break;
445 }
446 break;
447
448 default:
449 break;
450 }
451
452 return 0;
453}
454
455static struct i2c_algorithm cx231xx_algo = { 427static struct i2c_algorithm cx231xx_algo = {
456 .master_xfer = cx231xx_i2c_xfer, 428 .master_xfer = cx231xx_i2c_xfer,
457 .functionality = functionality, 429 .functionality = functionality,
@@ -462,7 +434,6 @@ static struct i2c_adapter cx231xx_adap_template = {
462 .name = "cx231xx", 434 .name = "cx231xx",
463 .id = I2C_HW_B_CX231XX, 435 .id = I2C_HW_B_CX231XX,
464 .algo = &cx231xx_algo, 436 .algo = &cx231xx_algo,
465 .client_register = attach_inform,
466}; 437};
467 438
468static struct i2c_client cx231xx_client_template = { 439static struct i2c_client cx231xx_client_template = {
@@ -537,6 +508,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus)
537 if (0 == bus->i2c_rc) { 508 if (0 == bus->i2c_rc) {
538 if (i2c_scan) 509 if (i2c_scan)
539 cx231xx_do_i2c_scan(dev, &bus->i2c_client); 510 cx231xx_do_i2c_scan(dev, &bus->i2c_client);
511
512 /* Instantiate the IR receiver device, if present */
513 cx231xx_register_i2c_ir(dev);
540 } else 514 } else
541 cx231xx_warn("%s: i2c bus %d register FAILED\n", 515 cx231xx_warn("%s: i2c bus %d register FAILED\n",
542 dev->name, bus->nr); 516 dev->name, bus->nr);
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index 97e304c3c799..48f22fa38e6c 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
36 36
37#define i2cdprintk(fmt, arg...) \ 37#define i2cdprintk(fmt, arg...) \
38 if (ir_debug) { \ 38 if (ir_debug) { \
39 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ 39 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
40 } 40 }
41 41
42#define dprintk(fmt, arg...) \ 42#define dprintk(fmt, arg...) \
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
index 94180526909c..e97b8023a655 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -26,7 +26,6 @@
26#include <linux/bitmap.h> 26#include <linux/bitmap.h>
27#include <linux/usb.h> 27#include <linux/usb.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/version.h>
30#include <linux/mm.h> 29#include <linux/mm.h>
31#include <linux/mutex.h> 30#include <linux/mutex.h>
32 31
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index aa4a23ef491a..e38eb2d425f7 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -738,7 +738,7 @@ extern void cx231xx_card_setup(struct cx231xx *dev);
738extern struct cx231xx_board cx231xx_boards[]; 738extern struct cx231xx_board cx231xx_boards[];
739extern struct usb_device_id cx231xx_id_table[]; 739extern struct usb_device_id cx231xx_id_table[];
740extern const unsigned int cx231xx_bcount; 740extern const unsigned int cx231xx_bcount;
741void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir); 741void cx231xx_register_i2c_ir(struct cx231xx *dev);
742int cx231xx_tuner_callback(void *ptr, int component, int command, int arg); 742int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
743 743
744/* Provided by cx231xx-input.c */ 744/* Provided by cx231xx-input.c */
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index 9a6536998d90..08582e58bdbf 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -312,7 +312,7 @@ static void netup_read_ci_status(struct work_struct *work)
312 "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], 312 "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
313 buf[32]); 313 buf[32]);
314 314
315 if (buf[0] && 1) 315 if (buf[0] & 1)
316 state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | 316 state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
317 DVB_CA_EN50221_POLL_CAM_READY; 317 DVB_CA_EN50221_POLL_CAM_READY;
318 else 318 else
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 6f5df90af93e..2943bfd32a94 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1742,7 +1742,6 @@ static struct video_device *cx23885_video_dev_alloc(
1742 if (NULL == vfd) 1742 if (NULL == vfd)
1743 return NULL; 1743 return NULL;
1744 *vfd = *template; 1744 *vfd = *template;
1745 vfd->minor = -1;
1746 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, 1745 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
1747 type, cx23885_boards[tsport->dev->board].name); 1746 type, cx23885_boards[tsport->dev->board].name);
1748 vfd->parent = &pci->dev; 1747 vfd->parent = &pci->dev;
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 6d6293f7d428..ce29b5e34a11 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -181,6 +181,26 @@ struct cx23885_board cx23885_boards[] = {
181 .portb = CX23885_MPEG_DVB, 181 .portb = CX23885_MPEG_DVB,
182 .portc = CX23885_MPEG_DVB, 182 .portc = CX23885_MPEG_DVB,
183 }, 183 },
184 [CX23885_BOARD_HAUPPAUGE_HVR1270] = {
185 .name = "Hauppauge WinTV-HVR1270",
186 .portc = CX23885_MPEG_DVB,
187 },
188 [CX23885_BOARD_HAUPPAUGE_HVR1275] = {
189 .name = "Hauppauge WinTV-HVR1275",
190 .portc = CX23885_MPEG_DVB,
191 },
192 [CX23885_BOARD_HAUPPAUGE_HVR1255] = {
193 .name = "Hauppauge WinTV-HVR1255",
194 .portc = CX23885_MPEG_DVB,
195 },
196 [CX23885_BOARD_HAUPPAUGE_HVR1210] = {
197 .name = "Hauppauge WinTV-HVR1210",
198 .portc = CX23885_MPEG_DVB,
199 },
200 [CX23885_BOARD_MYGICA_X8506] = {
201 .name = "Mygica X8506 DMB-TH",
202 .portb = CX23885_MPEG_DVB,
203 },
184}; 204};
185const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 205const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
186 206
@@ -280,6 +300,30 @@ struct cx23885_subid cx23885_subids[] = {
280 .subvendor = 0x1b55, 300 .subvendor = 0x1b55,
281 .subdevice = 0x2a2c, 301 .subdevice = 0x2a2c,
282 .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, 302 .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
303 }, {
304 .subvendor = 0x0070,
305 .subdevice = 0x2211,
306 .card = CX23885_BOARD_HAUPPAUGE_HVR1270,
307 }, {
308 .subvendor = 0x0070,
309 .subdevice = 0x2215,
310 .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
311 }, {
312 .subvendor = 0x0070,
313 .subdevice = 0x2251,
314 .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
315 }, {
316 .subvendor = 0x0070,
317 .subdevice = 0x2291,
318 .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
319 }, {
320 .subvendor = 0x0070,
321 .subdevice = 0x2295,
322 .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
323 }, {
324 .subvendor = 0x14f1,
325 .subdevice = 0x8651,
326 .card = CX23885_BOARD_MYGICA_X8506,
283 }, 327 },
284}; 328};
285const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 329const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -321,6 +365,42 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
321 365
322 /* Make sure we support the board model */ 366 /* Make sure we support the board model */
323 switch (tv.model) { 367 switch (tv.model) {
368 case 22001:
369 /* WinTV-HVR1270 (PCIe, Retail, half height)
370 * ATSC/QAM and basic analog, IR Blast */
371 case 22009:
372 /* WinTV-HVR1210 (PCIe, Retail, half height)
373 * DVB-T and basic analog, IR Blast */
374 case 22011:
375 /* WinTV-HVR1270 (PCIe, Retail, half height)
376 * ATSC/QAM and basic analog, IR Recv */
377 case 22019:
378 /* WinTV-HVR1210 (PCIe, Retail, half height)
379 * DVB-T and basic analog, IR Recv */
380 case 22021:
381 /* WinTV-HVR1275 (PCIe, Retail, half height)
382 * ATSC/QAM and basic analog, IR Recv */
383 case 22029:
384 /* WinTV-HVR1210 (PCIe, Retail, half height)
385 * DVB-T and basic analog, IR Recv */
386 case 22101:
387 /* WinTV-HVR1270 (PCIe, Retail, full height)
388 * ATSC/QAM and basic analog, IR Blast */
389 case 22109:
390 /* WinTV-HVR1210 (PCIe, Retail, full height)
391 * DVB-T and basic analog, IR Blast */
392 case 22111:
393 /* WinTV-HVR1270 (PCIe, Retail, full height)
394 * ATSC/QAM and basic analog, IR Recv */
395 case 22119:
396 /* WinTV-HVR1210 (PCIe, Retail, full height)
397 * DVB-T and basic analog, IR Recv */
398 case 22121:
399 /* WinTV-HVR1275 (PCIe, Retail, full height)
400 * ATSC/QAM and basic analog, IR Recv */
401 case 22129:
402 /* WinTV-HVR1210 (PCIe, Retail, full height)
403 * DVB-T and basic analog, IR Recv */
324 case 71009: 404 case 71009:
325 /* WinTV-HVR1200 (PCIe, Retail, full height) 405 /* WinTV-HVR1200 (PCIe, Retail, full height)
326 * DVB-T and basic analog */ 406 * DVB-T and basic analog */
@@ -619,6 +699,30 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
619 /* enable irq */ 699 /* enable irq */
620 cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ 700 cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
621 break; 701 break;
702 case CX23885_BOARD_HAUPPAUGE_HVR1270:
703 case CX23885_BOARD_HAUPPAUGE_HVR1275:
704 case CX23885_BOARD_HAUPPAUGE_HVR1255:
705 case CX23885_BOARD_HAUPPAUGE_HVR1210:
706 /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */
707 /* GPIO-6 I2C Gate which can isolate the demod from the bus */
708 /* GPIO-9 Demod reset */
709
710 /* Put the parts into reset and back */
711 cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1);
712 cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5);
713 cx23885_gpio_clear(dev, GPIO_9);
714 mdelay(20);
715 cx23885_gpio_set(dev, GPIO_9);
716 break;
717 case CX23885_BOARD_MYGICA_X8506:
718 /* GPIO-1 reset XC5000 */
719 /* GPIO-2 reset LGS8GL5 */
720 cx_set(GP0_IO, 0x00060000);
721 cx_clear(GP0_IO, 0x00000006);
722 mdelay(100);
723 cx_set(GP0_IO, 0x00060006);
724 mdelay(100);
725 break;
622 } 726 }
623} 727}
624 728
@@ -631,6 +735,10 @@ int cx23885_ir_init(struct cx23885_dev *dev)
631 case CX23885_BOARD_HAUPPAUGE_HVR1800: 735 case CX23885_BOARD_HAUPPAUGE_HVR1800:
632 case CX23885_BOARD_HAUPPAUGE_HVR1200: 736 case CX23885_BOARD_HAUPPAUGE_HVR1200:
633 case CX23885_BOARD_HAUPPAUGE_HVR1400: 737 case CX23885_BOARD_HAUPPAUGE_HVR1400:
738 case CX23885_BOARD_HAUPPAUGE_HVR1270:
739 case CX23885_BOARD_HAUPPAUGE_HVR1275:
740 case CX23885_BOARD_HAUPPAUGE_HVR1255:
741 case CX23885_BOARD_HAUPPAUGE_HVR1210:
634 /* FIXME: Implement me */ 742 /* FIXME: Implement me */
635 break; 743 break;
636 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: 744 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -666,6 +774,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
666 case CX23885_BOARD_HAUPPAUGE_HVR1800lp: 774 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
667 case CX23885_BOARD_HAUPPAUGE_HVR1200: 775 case CX23885_BOARD_HAUPPAUGE_HVR1200:
668 case CX23885_BOARD_HAUPPAUGE_HVR1700: 776 case CX23885_BOARD_HAUPPAUGE_HVR1700:
777 case CX23885_BOARD_HAUPPAUGE_HVR1270:
778 case CX23885_BOARD_HAUPPAUGE_HVR1275:
779 case CX23885_BOARD_HAUPPAUGE_HVR1255:
780 case CX23885_BOARD_HAUPPAUGE_HVR1210:
669 if (dev->i2c_bus[0].i2c_rc == 0) 781 if (dev->i2c_bus[0].i2c_rc == 0)
670 hauppauge_eeprom(dev, eeprom+0xc0); 782 hauppauge_eeprom(dev, eeprom+0xc0);
671 break; 783 break;
@@ -714,6 +826,11 @@ void cx23885_card_setup(struct cx23885_dev *dev)
714 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 826 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
715 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 827 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
716 break; 828 break;
829 case CX23885_BOARD_MYGICA_X8506:
830 ts1->gen_ctrl_val = 0x5; /* Parallel */
831 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
832 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
833 break;
717 case CX23885_BOARD_HAUPPAUGE_HVR1250: 834 case CX23885_BOARD_HAUPPAUGE_HVR1250:
718 case CX23885_BOARD_HAUPPAUGE_HVR1500: 835 case CX23885_BOARD_HAUPPAUGE_HVR1500:
719 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 836 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -723,6 +840,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
723 case CX23885_BOARD_HAUPPAUGE_HVR1400: 840 case CX23885_BOARD_HAUPPAUGE_HVR1400:
724 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 841 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
725 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 842 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
843 case CX23885_BOARD_HAUPPAUGE_HVR1270:
844 case CX23885_BOARD_HAUPPAUGE_HVR1275:
845 case CX23885_BOARD_HAUPPAUGE_HVR1255:
846 case CX23885_BOARD_HAUPPAUGE_HVR1210:
726 default: 847 default:
727 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 848 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
728 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 849 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index beda42925ce7..bf7bb1c412fb 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1700,9 +1700,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1700 } 1700 }
1701 1701
1702 if (cx23885_boards[dev->board].cimax > 0 && 1702 if (cx23885_boards[dev->board].cimax > 0 &&
1703 ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1))) 1703 ((pci_status & PCI_MSK_GPIO0) ||
1704 /* handled += cx23885_irq_gpio(dev, pci_status); */ 1704 (pci_status & PCI_MSK_GPIO1))) {
1705 handled += netup_ci_slot_status(dev, pci_status); 1705
1706 if (cx23885_boards[dev->board].cimax > 0)
1707 handled += netup_ci_slot_status(dev, pci_status);
1708
1709 }
1706 1710
1707 if (ts1_status) { 1711 if (ts1_status) {
1708 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 1712 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
@@ -1729,6 +1733,88 @@ out:
1729 return IRQ_RETVAL(handled); 1733 return IRQ_RETVAL(handled);
1730} 1734}
1731 1735
1736static inline int encoder_on_portb(struct cx23885_dev *dev)
1737{
1738 return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
1739}
1740
1741static inline int encoder_on_portc(struct cx23885_dev *dev)
1742{
1743 return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER;
1744}
1745
1746/* Mask represents 32 different GPIOs, GPIO's are split into multiple
1747 * registers depending on the board configuration (and whether the
1748 * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will
1749 * be pushed into the correct hardware register, regardless of the
1750 * physical location. Certain registers are shared so we sanity check
1751 * and report errors if we think we're tampering with a GPIo that might
1752 * be assigned to the encoder (and used for the host bus).
1753 *
1754 * GPIO 2 thru 0 - On the cx23885 bridge
1755 * GPIO 18 thru 3 - On the cx23417 host bus interface
1756 * GPIO 23 thru 19 - On the cx25840 a/v core
1757 */
1758void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask)
1759{
1760 if (mask & 0x7)
1761 cx_set(GP0_IO, mask & 0x7);
1762
1763 if (mask & 0x0007fff8) {
1764 if (encoder_on_portb(dev) || encoder_on_portc(dev))
1765 printk(KERN_ERR
1766 "%s: Setting GPIO on encoder ports\n",
1767 dev->name);
1768 cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3);
1769 }
1770
1771 /* TODO: 23-19 */
1772 if (mask & 0x00f80000)
1773 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1774}
1775
1776void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
1777{
1778 if (mask & 0x00000007)
1779 cx_clear(GP0_IO, mask & 0x7);
1780
1781 if (mask & 0x0007fff8) {
1782 if (encoder_on_portb(dev) || encoder_on_portc(dev))
1783 printk(KERN_ERR
1784 "%s: Clearing GPIO moving on encoder ports\n",
1785 dev->name);
1786 cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3);
1787 }
1788
1789 /* TODO: 23-19 */
1790 if (mask & 0x00f80000)
1791 printk(KERN_INFO "%s: Unsupported\n", dev->name);
1792}
1793
1794void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
1795{
1796 if ((mask & 0x00000007) && asoutput)
1797 cx_set(GP0_IO, (mask & 0x7) << 16);
1798 else if ((mask & 0x00000007) && !asoutput)
1799 cx_clear(GP0_IO, (mask & 0x7) << 16);
1800
1801 if (mask & 0x0007fff8) {
1802 if (encoder_on_portb(dev) || encoder_on_portc(dev))
1803 printk(KERN_ERR
1804 "%s: Enabling GPIO on encoder ports\n",
1805 dev->name);
1806 }
1807
1808 /* MC417_OEN is active low for output, write 1 for an input */
1809 if ((mask & 0x0007fff8) && asoutput)
1810 cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3);
1811
1812 else if ((mask & 0x0007fff8) && !asoutput)
1813 cx_set(MC417_OEN, (mask & 0x7fff8) >> 3);
1814
1815 /* TODO: 23-19 */
1816}
1817
1732static int __devinit cx23885_initdev(struct pci_dev *pci_dev, 1818static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
1733 const struct pci_device_id *pci_id) 1819 const struct pci_device_id *pci_id)
1734{ 1820{
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 1dc070da8652..e236df23370e 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -49,8 +49,10 @@
49#include "lnbh24.h" 49#include "lnbh24.h"
50#include "cx24116.h" 50#include "cx24116.h"
51#include "cimax2.h" 51#include "cimax2.h"
52#include "lgs8gxx.h"
52#include "netup-eeprom.h" 53#include "netup-eeprom.h"
53#include "netup-init.h" 54#include "netup-init.h"
55#include "lgdt3305.h"
54 56
55static unsigned int debug; 57static unsigned int debug;
56 58
@@ -122,7 +124,22 @@ static struct tda10048_config hauppauge_hvr1200_config = {
122 .demod_address = 0x10 >> 1, 124 .demod_address = 0x10 >> 1,
123 .output_mode = TDA10048_SERIAL_OUTPUT, 125 .output_mode = TDA10048_SERIAL_OUTPUT,
124 .fwbulkwritelen = TDA10048_BULKWRITE_200, 126 .fwbulkwritelen = TDA10048_BULKWRITE_200,
125 .inversion = TDA10048_INVERSION_ON 127 .inversion = TDA10048_INVERSION_ON,
128 .dtv6_if_freq_khz = TDA10048_IF_3300,
129 .dtv7_if_freq_khz = TDA10048_IF_3800,
130 .dtv8_if_freq_khz = TDA10048_IF_4300,
131 .clk_freq_khz = TDA10048_CLK_16000,
132};
133
134static struct tda10048_config hauppauge_hvr1210_config = {
135 .demod_address = 0x10 >> 1,
136 .output_mode = TDA10048_SERIAL_OUTPUT,
137 .fwbulkwritelen = TDA10048_BULKWRITE_200,
138 .inversion = TDA10048_INVERSION_ON,
139 .dtv6_if_freq_khz = TDA10048_IF_3300,
140 .dtv7_if_freq_khz = TDA10048_IF_3500,
141 .dtv8_if_freq_khz = TDA10048_IF_4000,
142 .clk_freq_khz = TDA10048_CLK_16000,
126}; 143};
127 144
128static struct s5h1409_config hauppauge_ezqam_config = { 145static struct s5h1409_config hauppauge_ezqam_config = {
@@ -194,6 +211,16 @@ static struct s5h1411_config dvico_s5h1411_config = {
194 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 211 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
195}; 212};
196 213
214static struct s5h1411_config hcw_s5h1411_config = {
215 .output_mode = S5H1411_SERIAL_OUTPUT,
216 .gpio = S5H1411_GPIO_OFF,
217 .vsb_if = S5H1411_IF_44000,
218 .qam_if = S5H1411_IF_4000,
219 .inversion = S5H1411_INVERSION_ON,
220 .status_mode = S5H1411_DEMODLOCKING,
221 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
222};
223
197static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { 224static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
198 .i2c_address = 0x61, 225 .i2c_address = 0x61,
199 .if_khz = 5380, 226 .if_khz = 5380,
@@ -224,6 +251,32 @@ static struct tda18271_config hauppauge_hvr1200_tuner_config = {
224 .gate = TDA18271_GATE_ANALOG, 251 .gate = TDA18271_GATE_ANALOG,
225}; 252};
226 253
254static struct tda18271_config hauppauge_hvr1210_tuner_config = {
255 .gate = TDA18271_GATE_DIGITAL,
256};
257
258static struct tda18271_std_map hauppauge_hvr127x_std_map = {
259 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
260 .if_lvl = 1, .rfagc_top = 0x58 },
261 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
262 .if_lvl = 1, .rfagc_top = 0x58 },
263};
264
265static struct tda18271_config hauppauge_hvr127x_config = {
266 .std_map = &hauppauge_hvr127x_std_map,
267};
268
269static struct lgdt3305_config hauppauge_lgdt3305_config = {
270 .i2c_addr = 0x0e,
271 .mpeg_mode = LGDT3305_MPEG_SERIAL,
272 .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
273 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
274 .deny_i2c_rptr = 1,
275 .spectral_inversion = 1,
276 .qam_if_khz = 4000,
277 .vsb_if_khz = 3250,
278};
279
227static struct dibx000_agc_config xc3028_agc_config = { 280static struct dibx000_agc_config xc3028_agc_config = {
228 BAND_VHF | BAND_UHF, /* band_caps */ 281 BAND_VHF | BAND_UHF, /* band_caps */
229 282
@@ -368,10 +421,29 @@ static struct cx24116_config dvbworld_cx24116_config = {
368 .demod_address = 0x05, 421 .demod_address = 0x05,
369}; 422};
370 423
424static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = {
425 .prod = LGS8GXX_PROD_LGS8GL5,
426 .demod_address = 0x19,
427 .serial_ts = 0,
428 .ts_clk_pol = 1,
429 .ts_clk_gated = 1,
430 .if_clk_freq = 30400, /* 30.4 MHz */
431 .if_freq = 5380, /* 5.38 MHz */
432 .if_neg_center = 1,
433 .ext_adc = 0,
434 .adc_signed = 0,
435 .if_neg_edge = 0,
436};
437
438static struct xc5000_config mygica_x8506_xc5000_config = {
439 .i2c_address = 0x61,
440 .if_khz = 5380,
441};
442
371static int dvb_register(struct cx23885_tsport *port) 443static int dvb_register(struct cx23885_tsport *port)
372{ 444{
373 struct cx23885_dev *dev = port->dev; 445 struct cx23885_dev *dev = port->dev;
374 struct cx23885_i2c *i2c_bus = NULL; 446 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
375 struct videobuf_dvb_frontend *fe0; 447 struct videobuf_dvb_frontend *fe0;
376 int ret; 448 int ret;
377 449
@@ -396,6 +468,29 @@ static int dvb_register(struct cx23885_tsport *port)
396 &hauppauge_generic_tunerconfig, 0); 468 &hauppauge_generic_tunerconfig, 0);
397 } 469 }
398 break; 470 break;
471 case CX23885_BOARD_HAUPPAUGE_HVR1270:
472 case CX23885_BOARD_HAUPPAUGE_HVR1275:
473 i2c_bus = &dev->i2c_bus[0];
474 fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
475 &hauppauge_lgdt3305_config,
476 &i2c_bus->i2c_adap);
477 if (fe0->dvb.frontend != NULL) {
478 dvb_attach(tda18271_attach, fe0->dvb.frontend,
479 0x60, &dev->i2c_bus[1].i2c_adap,
480 &hauppauge_hvr127x_config);
481 }
482 break;
483 case CX23885_BOARD_HAUPPAUGE_HVR1255:
484 i2c_bus = &dev->i2c_bus[0];
485 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
486 &hcw_s5h1411_config,
487 &i2c_bus->i2c_adap);
488 if (fe0->dvb.frontend != NULL) {
489 dvb_attach(tda18271_attach, fe0->dvb.frontend,
490 0x60, &dev->i2c_bus[1].i2c_adap,
491 &hauppauge_tda18271_config);
492 }
493 break;
399 case CX23885_BOARD_HAUPPAUGE_HVR1800: 494 case CX23885_BOARD_HAUPPAUGE_HVR1800:
400 i2c_bus = &dev->i2c_bus[0]; 495 i2c_bus = &dev->i2c_bus[0];
401 switch (alt_tuner) { 496 switch (alt_tuner) {
@@ -496,6 +591,17 @@ static int dvb_register(struct cx23885_tsport *port)
496 &hauppauge_hvr1200_tuner_config); 591 &hauppauge_hvr1200_tuner_config);
497 } 592 }
498 break; 593 break;
594 case CX23885_BOARD_HAUPPAUGE_HVR1210:
595 i2c_bus = &dev->i2c_bus[0];
596 fe0->dvb.frontend = dvb_attach(tda10048_attach,
597 &hauppauge_hvr1210_config,
598 &i2c_bus->i2c_adap);
599 if (fe0->dvb.frontend != NULL) {
600 dvb_attach(tda18271_attach, fe0->dvb.frontend,
601 0x60, &dev->i2c_bus[1].i2c_adap,
602 &hauppauge_hvr1210_tuner_config);
603 }
604 break;
499 case CX23885_BOARD_HAUPPAUGE_HVR1400: 605 case CX23885_BOARD_HAUPPAUGE_HVR1400:
500 i2c_bus = &dev->i2c_bus[0]; 606 i2c_bus = &dev->i2c_bus[0];
501 fe0->dvb.frontend = dvb_attach(dib7000p_attach, 607 fe0->dvb.frontend = dvb_attach(dib7000p_attach,
@@ -659,6 +765,19 @@ static int dvb_register(struct cx23885_tsport *port)
659 break; 765 break;
660 } 766 }
661 break; 767 break;
768 case CX23885_BOARD_MYGICA_X8506:
769 i2c_bus = &dev->i2c_bus[0];
770 i2c_bus2 = &dev->i2c_bus[1];
771 fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
772 &mygica_x8506_lgs8gl5_config,
773 &i2c_bus->i2c_adap);
774 if (fe0->dvb.frontend != NULL) {
775 dvb_attach(xc5000_attach,
776 fe0->dvb.frontend,
777 &i2c_bus2->i2c_adap,
778 &mygica_x8506_xc5000_config);
779 }
780 break;
662 default: 781 default:
663 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 782 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
664 " isn't supported yet\n", 783 " isn't supported yet\n",
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 3421bd12056a..384dec34134f 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -357,6 +357,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
357 printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", 357 printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
358 dev->name, bus->nr); 358 dev->name, bus->nr);
359 359
360 /* Instantiate the IR receiver device, if present */
361 if (0 == bus->i2c_rc) {
362 struct i2c_board_info info;
363 const unsigned short addr_list[] = {
364 0x6b, I2C_CLIENT_END
365 };
366
367 memset(&info, 0, sizeof(struct i2c_board_info));
368 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
369 i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
370 }
371
360 return bus->i2c_rc; 372 return bus->i2c_rc;
361} 373}
362 374
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 68068c6d0987..66bbd2e71105 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -796,6 +796,7 @@ static unsigned int video_poll(struct file *file,
796{ 796{
797 struct cx23885_fh *fh = file->private_data; 797 struct cx23885_fh *fh = file->private_data;
798 struct cx23885_buffer *buf; 798 struct cx23885_buffer *buf;
799 unsigned int rc = POLLERR;
799 800
800 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 801 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
801 if (!res_get(fh->dev, fh, RESOURCE_VBI)) 802 if (!res_get(fh->dev, fh, RESOURCE_VBI))
@@ -803,23 +804,28 @@ static unsigned int video_poll(struct file *file,
803 return videobuf_poll_stream(file, &fh->vbiq, wait); 804 return videobuf_poll_stream(file, &fh->vbiq, wait);
804 } 805 }
805 806
807 mutex_lock(&fh->vidq.vb_lock);
806 if (res_check(fh, RESOURCE_VIDEO)) { 808 if (res_check(fh, RESOURCE_VIDEO)) {
807 /* streaming capture */ 809 /* streaming capture */
808 if (list_empty(&fh->vidq.stream)) 810 if (list_empty(&fh->vidq.stream))
809 return POLLERR; 811 goto done;
810 buf = list_entry(fh->vidq.stream.next, 812 buf = list_entry(fh->vidq.stream.next,
811 struct cx23885_buffer, vb.stream); 813 struct cx23885_buffer, vb.stream);
812 } else { 814 } else {
813 /* read() capture */ 815 /* read() capture */
814 buf = (struct cx23885_buffer *)fh->vidq.read_buf; 816 buf = (struct cx23885_buffer *)fh->vidq.read_buf;
815 if (NULL == buf) 817 if (NULL == buf)
816 return POLLERR; 818 goto done;
817 } 819 }
818 poll_wait(file, &buf->vb.done, wait); 820 poll_wait(file, &buf->vb.done, wait);
819 if (buf->vb.state == VIDEOBUF_DONE || 821 if (buf->vb.state == VIDEOBUF_DONE ||
820 buf->vb.state == VIDEOBUF_ERROR) 822 buf->vb.state == VIDEOBUF_ERROR)
821 return POLLIN|POLLRDNORM; 823 rc = POLLIN|POLLRDNORM;
822 return 0; 824 else
825 rc = 0;
826done:
827 mutex_unlock(&fh->vidq.vb_lock);
828 return rc;
823} 829}
824 830
825static int video_release(struct file *file) 831static int video_release(struct file *file)
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 85642831ea8e..1a2ac518a3f1 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -71,6 +71,22 @@
71#define CX23885_BOARD_TEVII_S470 15 71#define CX23885_BOARD_TEVII_S470 15
72#define CX23885_BOARD_DVBWORLD_2005 16 72#define CX23885_BOARD_DVBWORLD_2005 16
73#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 73#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17
74#define CX23885_BOARD_HAUPPAUGE_HVR1270 18
75#define CX23885_BOARD_HAUPPAUGE_HVR1275 19
76#define CX23885_BOARD_HAUPPAUGE_HVR1255 20
77#define CX23885_BOARD_HAUPPAUGE_HVR1210 21
78#define CX23885_BOARD_MYGICA_X8506 22
79
80#define GPIO_0 0x00000001
81#define GPIO_1 0x00000002
82#define GPIO_2 0x00000004
83#define GPIO_3 0x00000008
84#define GPIO_4 0x00000010
85#define GPIO_5 0x00000020
86#define GPIO_6 0x00000040
87#define GPIO_7 0x00000080
88#define GPIO_8 0x00000100
89#define GPIO_9 0x00000200
74 90
75/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ 91/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
76#define CX23885_NORMS (\ 92#define CX23885_NORMS (\
@@ -422,6 +438,11 @@ extern int cx23885_restart_queue(struct cx23885_tsport *port,
422extern void cx23885_wakeup(struct cx23885_tsport *port, 438extern void cx23885_wakeup(struct cx23885_tsport *port,
423 struct cx23885_dmaqueue *q, u32 count); 439 struct cx23885_dmaqueue *q, u32 count);
424 440
441extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
442extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
443extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
444 int asoutput);
445
425 446
426/* ----------------------------------------------------------- */ 447/* ----------------------------------------------------------- */
427/* cx23885-cards.c */ 448/* cx23885-cards.c */
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index b06b1275a9ec..5b7e26761f0a 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -1,5 +1,5 @@
1cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \ 1cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
2 cx88-input.o 2 cx88-dsp.o cx88-input.o
3cx8800-objs := cx88-video.o cx88-vbi.o 3cx8800-objs := cx88-video.o cx88-vbi.o
4cx8802-objs := cx88-mpeg.o 4cx8802-objs := cx88-mpeg.o
5 5
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 0ccdf36626e3..5a67445dd6ed 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -871,7 +871,7 @@ static struct pci_driver cx88_audio_pci_driver = {
871 .name = "cx88_audio", 871 .name = "cx88_audio",
872 .id_table = cx88_audio_pci_tbl, 872 .id_table = cx88_audio_pci_tbl,
873 .probe = cx88_audio_initdev, 873 .probe = cx88_audio_initdev,
874 .remove = cx88_audio_finidev, 874 .remove = __devexit_p(cx88_audio_finidev),
875}; 875};
876 876
877/**************************************************************************** 877/****************************************************************************
@@ -881,7 +881,7 @@ static struct pci_driver cx88_audio_pci_driver = {
881/* 881/*
882 * module init 882 * module init
883 */ 883 */
884static int cx88_audio_init(void) 884static int __init cx88_audio_init(void)
885{ 885{
886 printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", 886 printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n",
887 (CX88_VERSION_CODE >> 16) & 0xff, 887 (CX88_VERSION_CODE >> 16) & 0xff,
@@ -897,9 +897,8 @@ static int cx88_audio_init(void)
897/* 897/*
898 * module remove 898 * module remove
899 */ 899 */
900static void cx88_audio_fini(void) 900static void __exit cx88_audio_fini(void)
901{ 901{
902
903 pci_unregister_driver(&cx88_audio_pci_driver); 902 pci_unregister_driver(&cx88_audio_pci_driver);
904} 903}
905 904
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 6bbbfc66bb4b..94b7a52629d0 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1969,6 +1969,54 @@ static const struct cx88_board cx88_boards[] = {
1969 }, 1969 },
1970 .mpeg = CX88_MPEG_DVB, 1970 .mpeg = CX88_MPEG_DVB,
1971 }, 1971 },
1972 [CX88_BOARD_HAUPPAUGE_IRONLY] = {
1973 .name = "Hauppauge WinTV-IR Only",
1974 .tuner_type = UNSET,
1975 .radio_type = UNSET,
1976 .tuner_addr = ADDR_UNSET,
1977 .radio_addr = ADDR_UNSET,
1978 },
1979 [CX88_BOARD_WINFAST_DTV1800H] = {
1980 .name = "Leadtek WinFast DTV1800 Hybrid",
1981 .tuner_type = TUNER_XC2028,
1982 .radio_type = TUNER_XC2028,
1983 .tuner_addr = 0x61,
1984 .radio_addr = 0x61,
1985 /*
1986 * GPIO setting
1987 *
1988 * 2: mute (0=off,1=on)
1989 * 12: tuner reset pin
1990 * 13: audio source (0=tuner audio,1=line in)
1991 * 14: FM (0=on,1=off ???)
1992 */
1993 .input = {{
1994 .type = CX88_VMUX_TELEVISION,
1995 .vmux = 0,
1996 .gpio0 = 0x0400, /* pin 2 = 0 */
1997 .gpio1 = 0x6040, /* pin 13 = 0, pin 14 = 1 */
1998 .gpio2 = 0x0000,
1999 }, {
2000 .type = CX88_VMUX_COMPOSITE1,
2001 .vmux = 1,
2002 .gpio0 = 0x0400, /* pin 2 = 0 */
2003 .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
2004 .gpio2 = 0x0000,
2005 }, {
2006 .type = CX88_VMUX_SVIDEO,
2007 .vmux = 2,
2008 .gpio0 = 0x0400, /* pin 2 = 0 */
2009 .gpio1 = 0x6060, /* pin 13 = 1, pin 14 = 1 */
2010 .gpio2 = 0x0000,
2011 } },
2012 .radio = {
2013 .type = CX88_RADIO,
2014 .gpio0 = 0x0400, /* pin 2 = 0 */
2015 .gpio1 = 0x6000, /* pin 13 = 0, pin 14 = 0 */
2016 .gpio2 = 0x0000,
2017 },
2018 .mpeg = CX88_MPEG_DVB,
2019 },
1972}; 2020};
1973 2021
1974/* ------------------------------------------------------------------ */ 2022/* ------------------------------------------------------------------ */
@@ -2382,6 +2430,14 @@ static const struct cx88_subid cx88_subids[] = {
2382 .subvendor = 0x153b, 2430 .subvendor = 0x153b,
2383 .subdevice = 0x1177, 2431 .subdevice = 0x1177,
2384 .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII, 2432 .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
2433 }, {
2434 .subvendor = 0x0070,
2435 .subdevice = 0x9290,
2436 .card = CX88_BOARD_HAUPPAUGE_IRONLY,
2437 }, {
2438 .subvendor = 0x107d,
2439 .subdevice = 0x6654,
2440 .card = CX88_BOARD_WINFAST_DTV1800H,
2385 }, 2441 },
2386}; 2442};
2387 2443
@@ -2448,6 +2504,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2448 case 90500: /* Nova-T-PCI (oem) */ 2504 case 90500: /* Nova-T-PCI (oem) */
2449 case 90501: /* Nova-T-PCI (oem/IR) */ 2505 case 90501: /* Nova-T-PCI (oem/IR) */
2450 case 92000: /* Nova-SE2 (OEM, No Video or IR) */ 2506 case 92000: /* Nova-SE2 (OEM, No Video or IR) */
2507 case 92900: /* WinTV-IROnly (No analog or digital Video inputs) */
2451 case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ 2508 case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
2452 case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ 2509 case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
2453 case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */ 2510 case 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
@@ -2579,6 +2636,23 @@ static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
2579 return -EINVAL; 2636 return -EINVAL;
2580} 2637}
2581 2638
2639static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core,
2640 int command, int arg)
2641{
2642 switch (command) {
2643 case XC2028_TUNER_RESET:
2644 /* GPIO 12 (xc3028 tuner reset) */
2645 cx_set(MO_GP1_IO, 0x1010);
2646 mdelay(50);
2647 cx_clear(MO_GP1_IO, 0x10);
2648 mdelay(50);
2649 cx_set(MO_GP1_IO, 0x10);
2650 mdelay(50);
2651 return 0;
2652 }
2653 return -EINVAL;
2654}
2655
2582/* ------------------------------------------------------------------- */ 2656/* ------------------------------------------------------------------- */
2583/* some Divco specific stuff */ 2657/* some Divco specific stuff */
2584static int cx88_pv_8000gt_callback(struct cx88_core *core, 2658static int cx88_pv_8000gt_callback(struct cx88_core *core,
@@ -2651,6 +2725,8 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
2651 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 2725 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2652 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 2726 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2653 return cx88_dvico_xc2028_callback(core, command, arg); 2727 return cx88_dvico_xc2028_callback(core, command, arg);
2728 case CX88_BOARD_WINFAST_DTV1800H:
2729 return cx88_xc3028_winfast1800h_callback(core, command, arg);
2654 } 2730 }
2655 2731
2656 switch (command) { 2732 switch (command) {
@@ -2690,10 +2766,22 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core,
2690 switch (core->boardnr) { 2766 switch (core->boardnr) {
2691 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 2767 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
2692 if (command == 0) { /* This is the reset command from xc5000 */ 2768 if (command == 0) { /* This is the reset command from xc5000 */
2693 /* Reset XC5000 tuner via SYS_RSTO_pin */ 2769
2694 cx_write(MO_SRST_IO, 0); 2770 /* djh - According to the engineer at PCTV Systems,
2695 msleep(10); 2771 the xc5000 reset pin is supposed to be on GPIO12.
2696 cx_write(MO_SRST_IO, 1); 2772 However, despite three nights of effort, pulling
2773 that GPIO low didn't reset the xc5000. While
2774 pulling MO_SRST_IO low does reset the xc5000, this
2775 also resets in the s5h1409 being reset as well.
2776 This causes tuning to always fail since the internal
2777 state of the s5h1409 does not match the driver's
2778 state. Given that the only two conditions in which
2779 the driver performs a reset is during firmware load
2780 and powering down the chip, I am taking out the
2781 reset. We know that the chip is being reset
2782 when the cx88 comes online, and not being able to
2783 do power management for this board is worse than
2784 not having any tuning at all. */
2697 return 0; 2785 return 0;
2698 } else { 2786 } else {
2699 err_printk(core, "xc5000: unknown tuner " 2787 err_printk(core, "xc5000: unknown tuner "
@@ -2825,6 +2913,16 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
2825 cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ 2913 cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
2826 udelay(1000); 2914 udelay(1000);
2827 break; 2915 break;
2916
2917 case CX88_BOARD_WINFAST_DTV1800H:
2918 /* GPIO 12 (xc3028 tuner reset) */
2919 cx_set(MO_GP1_IO, 0x1010);
2920 mdelay(50);
2921 cx_clear(MO_GP1_IO, 0x10);
2922 mdelay(50);
2923 cx_set(MO_GP1_IO, 0x10);
2924 mdelay(50);
2925 break;
2828 } 2926 }
2829} 2927}
2830 2928
@@ -2845,6 +2943,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
2845 core->i2c_algo.udelay = 16; 2943 core->i2c_algo.udelay = 16;
2846 break; 2944 break;
2847 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 2945 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2946 case CX88_BOARD_WINFAST_DTV1800H:
2848 ctl->demod = XC3028_FE_ZARLINK456; 2947 ctl->demod = XC3028_FE_ZARLINK456;
2849 break; 2948 break;
2850 case CX88_BOARD_KWORLD_ATSC_120: 2949 case CX88_BOARD_KWORLD_ATSC_120:
@@ -2907,6 +3006,7 @@ static void cx88_card_setup(struct cx88_core *core)
2907 case CX88_BOARD_HAUPPAUGE_HVR1300: 3006 case CX88_BOARD_HAUPPAUGE_HVR1300:
2908 case CX88_BOARD_HAUPPAUGE_HVR4000: 3007 case CX88_BOARD_HAUPPAUGE_HVR4000:
2909 case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 3008 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
3009 case CX88_BOARD_HAUPPAUGE_IRONLY:
2910 if (0 == core->i2c_rc) 3010 if (0 == core->i2c_rc)
2911 hauppauge_eeprom(core, eeprom); 3011 hauppauge_eeprom(core, eeprom);
2912 break; 3012 break;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 0e149b22bd19..cf634606ba9a 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -231,7 +231,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
231 * can use the whole SDRAM for the DMA fifos. To simplify things, we 231 * can use the whole SDRAM for the DMA fifos. To simplify things, we
232 * use a static memory layout. That surely will waste memory in case 232 * use a static memory layout. That surely will waste memory in case
233 * we don't use all DMA channels at the same time (which will be the 233 * we don't use all DMA channels at the same time (which will be the
234 * case most of the time). But that still gives us enougth FIFO space 234 * case most of the time). But that still gives us enough FIFO space
235 * to be able to deal with insane long pci latencies ... 235 * to be able to deal with insane long pci latencies ...
236 * 236 *
237 * FIFO space allocations: 237 * FIFO space allocations:
@@ -241,6 +241,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
241 * channel 24 (vbi) - 4.0k 241 * channel 24 (vbi) - 4.0k
242 * channels 25+26 (audio) - 4.0k 242 * channels 25+26 (audio) - 4.0k
243 * channel 28 (mpeg) - 4.0k 243 * channel 28 (mpeg) - 4.0k
244 * channel 27 (audio rds)- 3.0k
244 * TOTAL = 29.0k 245 * TOTAL = 29.0k
245 * 246 *
246 * Every channel has 160 bytes control data (64 bytes instruction 247 * Every channel has 160 bytes control data (64 bytes instruction
@@ -337,6 +338,18 @@ struct sram_channel cx88_sram_channels[] = {
337 .cnt1_reg = MO_DMA28_CNT1, 338 .cnt1_reg = MO_DMA28_CNT1,
338 .cnt2_reg = MO_DMA28_CNT2, 339 .cnt2_reg = MO_DMA28_CNT2,
339 }, 340 },
341 [SRAM_CH27] = {
342 .name = "audio rds",
343 .cmds_start = 0x1801C0,
344 .ctrl_start = 0x180860,
345 .cdt = 0x180860 + 64,
346 .fifo_start = 0x187400,
347 .fifo_size = 0x000C00,
348 .ptr1_reg = MO_DMA27_PTR1,
349 .ptr2_reg = MO_DMA27_PTR2,
350 .cnt1_reg = MO_DMA27_CNT1,
351 .cnt2_reg = MO_DMA27_CNT2,
352 },
340}; 353};
341 354
342int cx88_sram_channel_setup(struct cx88_core *core, 355int cx88_sram_channel_setup(struct cx88_core *core,
@@ -598,6 +611,7 @@ int cx88_reset(struct cx88_core *core)
598 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); 611 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
599 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); 612 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
600 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); 613 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
614 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
601 615
602 /* misc init ... */ 616 /* misc init ... */
603 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable 617 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
@@ -796,6 +810,8 @@ int cx88_start_audio_dma(struct cx88_core *core)
796 /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ 810 /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
797 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; 811 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
798 812
813 int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES;
814
799 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */ 815 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
800 if (cx_read(MO_AUD_DMACNTRL) & 0x10) 816 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
801 return 0; 817 return 0;
@@ -803,12 +819,14 @@ int cx88_start_audio_dma(struct cx88_core *core)
803 /* setup fifo + format */ 819 /* setup fifo + format */
804 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); 820 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
805 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); 821 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
822 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
823 rds_bpl, 0);
806 824
807 cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ 825 cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
808 cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */ 826 cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
809 827
810 /* start dma */ 828 /* enable Up, Down and Audio RDS fifo */
811 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ 829 cx_write(MO_AUD_DMACNTRL, 0x0007);
812 830
813 return 0; 831 return 0;
814} 832}
@@ -1010,7 +1028,6 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
1010 if (NULL == vfd) 1028 if (NULL == vfd)
1011 return NULL; 1029 return NULL;
1012 *vfd = *template; 1030 *vfd = *template;
1013 vfd->minor = -1;
1014 vfd->v4l2_dev = &core->v4l2_dev; 1031 vfd->v4l2_dev = &core->v4l2_dev;
1015 vfd->parent = &pci->dev; 1032 vfd->parent = &pci->dev;
1016 vfd->release = video_device_release; 1033 vfd->release = video_device_release;
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
new file mode 100644
index 000000000000..3e5eaf3fe2a6
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-dsp.c
@@ -0,0 +1,312 @@
1/*
2 *
3 * Stereo and SAP detection for cx88
4 *
5 * Copyright (c) 2009 Marton Balint <cus@fazekas.hu>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/jiffies.h>
25#include <asm/div64.h>
26
27#include "cx88.h"
28#include "cx88-reg.h"
29
30#define INT_PI ((s32)(3.141592653589 * 32768.0))
31
32#define compat_remainder(a, b) \
33 ((float)(((s32)((a)*100))%((s32)((b)*100)))/100.0)
34
35#define baseband_freq(carrier, srate, tone) ((s32)( \
36 (compat_remainder(carrier + tone, srate)) / srate * 2 * INT_PI))
37
38/* We calculate the baseband frequencies of the carrier and the pilot tones
39 * based on the the sampling rate of the audio rds fifo. */
40
41#define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0)
42#define FREQ_A2_DUAL baseband_freq(54687.5, 2689.36, 274.1)
43#define FREQ_A2_STEREO baseband_freq(54687.5, 2689.36, 117.5)
44
45/* The frequencies below are from the reference driver. They probably need
46 * further adjustments, because they are not tested at all. You may even need
47 * to play a bit with the registers of the chip to select the proper signal
48 * for the input of the audio rds fifo, and measure it's sampling rate to
49 * calculate the proper baseband frequencies... */
50
51#define FREQ_A2M_CARRIER ((s32)(2.114516 * 32768.0))
52#define FREQ_A2M_DUAL ((s32)(2.754916 * 32768.0))
53#define FREQ_A2M_STEREO ((s32)(2.462326 * 32768.0))
54
55#define FREQ_EIAJ_CARRIER ((s32)(1.963495 * 32768.0)) /* 5pi/8 */
56#define FREQ_EIAJ_DUAL ((s32)(2.562118 * 32768.0))
57#define FREQ_EIAJ_STEREO ((s32)(2.601053 * 32768.0))
58
59#define FREQ_BTSC_DUAL ((s32)(1.963495 * 32768.0)) /* 5pi/8 */
60#define FREQ_BTSC_DUAL_REF ((s32)(1.374446 * 32768.0)) /* 7pi/16 */
61
62#define FREQ_BTSC_SAP ((s32)(2.471532 * 32768.0))
63#define FREQ_BTSC_SAP_REF ((s32)(1.730072 * 32768.0))
64
65/* The spectrum of the signal should be empty between these frequencies. */
66#define FREQ_NOISE_START ((s32)(0.100000 * 32768.0))
67#define FREQ_NOISE_END ((s32)(1.200000 * 32768.0))
68
69static unsigned int dsp_debug;
70module_param(dsp_debug, int, 0644);
71MODULE_PARM_DESC(dsp_debug, "enable audio dsp debug messages");
72
73#define dprintk(level, fmt, arg...) if (dsp_debug >= level) \
74 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
75
76static s32 int_cos(u32 x)
77{
78 u32 t2, t4, t6, t8;
79 s32 ret;
80 u16 period = x / INT_PI;
81 if (period % 2)
82 return -int_cos(x - INT_PI);
83 x = x % INT_PI;
84 if (x > INT_PI/2)
85 return -int_cos(INT_PI/2 - (x % (INT_PI/2)));
86 /* Now x is between 0 and INT_PI/2.
87 * To calculate cos(x) we use it's Taylor polinom. */
88 t2 = x*x/32768/2;
89 t4 = t2*x/32768*x/32768/3/4;
90 t6 = t4*x/32768*x/32768/5/6;
91 t8 = t6*x/32768*x/32768/7/8;
92 ret = 32768-t2+t4-t6+t8;
93 return ret;
94}
95
96static u32 int_goertzel(s16 x[], u32 N, u32 freq)
97{
98 /* We use the Goertzel algorithm to determine the power of the
99 * given frequency in the signal */
100 s32 s_prev = 0;
101 s32 s_prev2 = 0;
102 s32 coeff = 2*int_cos(freq);
103 u32 i;
104
105 u64 tmp;
106 u32 divisor;
107
108 for (i = 0; i < N; i++) {
109 s32 s = x[i] + ((s64)coeff*s_prev/32768) - s_prev2;
110 s_prev2 = s_prev;
111 s_prev = s;
112 }
113
114 tmp = (s64)s_prev2 * s_prev2 + (s64)s_prev * s_prev -
115 (s64)coeff * s_prev2 * s_prev / 32768;
116
117 /* XXX: N must be low enough so that N*N fits in s32.
118 * Else we need two divisions. */
119 divisor = N * N;
120 do_div(tmp, divisor);
121
122 return (u32) tmp;
123}
124
125static u32 freq_magnitude(s16 x[], u32 N, u32 freq)
126{
127 u32 sum = int_goertzel(x, N, freq);
128 return (u32)int_sqrt(sum);
129}
130
131static u32 noise_magnitude(s16 x[], u32 N, u32 freq_start, u32 freq_end)
132{
133 int i;
134 u32 sum = 0;
135 u32 freq_step;
136 int samples = 5;
137
138 if (N > 192) {
139 /* The last 192 samples are enough for noise detection */
140 x += (N-192);
141 N = 192;
142 }
143
144 freq_step = (freq_end - freq_start) / (samples - 1);
145
146 for (i = 0; i < samples; i++) {
147 sum += int_goertzel(x, N, freq_start);
148 freq_start += freq_step;
149 }
150
151 return (u32)int_sqrt(sum / samples);
152}
153
154static s32 detect_a2_a2m_eiaj(struct cx88_core *core, s16 x[], u32 N)
155{
156 s32 carrier, stereo, dual, noise;
157 s32 carrier_freq, stereo_freq, dual_freq;
158 s32 ret;
159
160 switch (core->tvaudio) {
161 case WW_BG:
162 case WW_DK:
163 carrier_freq = FREQ_A2_CARRIER;
164 stereo_freq = FREQ_A2_STEREO;
165 dual_freq = FREQ_A2_DUAL;
166 break;
167 case WW_M:
168 carrier_freq = FREQ_A2M_CARRIER;
169 stereo_freq = FREQ_A2M_STEREO;
170 dual_freq = FREQ_A2M_DUAL;
171 break;
172 case WW_EIAJ:
173 carrier_freq = FREQ_EIAJ_CARRIER;
174 stereo_freq = FREQ_EIAJ_STEREO;
175 dual_freq = FREQ_EIAJ_DUAL;
176 break;
177 default:
178 printk(KERN_WARNING "%s/0: unsupported audio mode %d for %s\n",
179 core->name, core->tvaudio, __func__);
180 return UNSET;
181 }
182
183 carrier = freq_magnitude(x, N, carrier_freq);
184 stereo = freq_magnitude(x, N, stereo_freq);
185 dual = freq_magnitude(x, N, dual_freq);
186 noise = noise_magnitude(x, N, FREQ_NOISE_START, FREQ_NOISE_END);
187
188 dprintk(1, "detect a2/a2m/eiaj: carrier=%d, stereo=%d, dual=%d, "
189 "noise=%d\n", carrier, stereo, dual, noise);
190
191 if (stereo > dual)
192 ret = V4L2_TUNER_SUB_STEREO;
193 else
194 ret = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
195
196 if (core->tvaudio == WW_EIAJ) {
197 /* EIAJ checks may need adjustments */
198 if ((carrier > max(stereo, dual)*2) &&
199 (carrier < max(stereo, dual)*6) &&
200 (carrier > 20 && carrier < 200) &&
201 (max(stereo, dual) > min(stereo, dual))) {
202 /* For EIAJ the carrier is always present,
203 so we probably don't need noise detection */
204 return ret;
205 }
206 } else {
207 if ((carrier > max(stereo, dual)*2) &&
208 (carrier < max(stereo, dual)*8) &&
209 (carrier > 20 && carrier < 200) &&
210 (noise < 10) &&
211 (max(stereo, dual) > min(stereo, dual)*2)) {
212 return ret;
213 }
214 }
215 return V4L2_TUNER_SUB_MONO;
216}
217
218static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N)
219{
220 s32 sap_ref = freq_magnitude(x, N, FREQ_BTSC_SAP_REF);
221 s32 sap = freq_magnitude(x, N, FREQ_BTSC_SAP);
222 s32 dual_ref = freq_magnitude(x, N, FREQ_BTSC_DUAL_REF);
223 s32 dual = freq_magnitude(x, N, FREQ_BTSC_DUAL);
224 dprintk(1, "detect btsc: dual_ref=%d, dual=%d, sap_ref=%d, sap=%d"
225 "\n", dual_ref, dual, sap_ref, sap);
226 /* FIXME: Currently not supported */
227 return UNSET;
228}
229
230static s16 *read_rds_samples(struct cx88_core *core, u32 *N)
231{
232 struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27];
233 s16 *samples;
234
235 unsigned int i;
236 unsigned int bpl = srch->fifo_size/AUD_RDS_LINES;
237 unsigned int spl = bpl/4;
238 unsigned int sample_count = spl*(AUD_RDS_LINES-1);
239
240 u32 current_address = cx_read(srch->ptr1_reg);
241 u32 offset = (current_address - srch->fifo_start + bpl);
242
243 dprintk(1, "read RDS samples: current_address=%08x (offset=%08x), "
244 "sample_count=%d, aud_intstat=%08x\n", current_address,
245 current_address - srch->fifo_start, sample_count,
246 cx_read(MO_AUD_INTSTAT));
247
248 samples = kmalloc(sizeof(s16)*sample_count, GFP_KERNEL);
249 if (!samples)
250 return NULL;
251
252 *N = sample_count;
253
254 for (i = 0; i < sample_count; i++) {
255 offset = offset % (AUD_RDS_LINES*bpl);
256 samples[i] = cx_read(srch->fifo_start + offset);
257 offset += 4;
258 }
259
260 if (dsp_debug >= 2) {
261 dprintk(2, "RDS samples dump: ");
262 for (i = 0; i < sample_count; i++)
263 printk("%hd ", samples[i]);
264 printk(".\n");
265 }
266
267 return samples;
268}
269
270s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core)
271{
272 s16 *samples;
273 u32 N = 0;
274 s32 ret = UNSET;
275
276 /* If audio RDS fifo is disabled, we can't read the samples */
277 if (!(cx_read(MO_AUD_DMACNTRL) & 0x04))
278 return ret;
279 if (!(cx_read(AUD_CTL) & EN_FMRADIO_EN_RDS))
280 return ret;
281
282 /* Wait at least 500 ms after an audio standard change */
283 if (time_before(jiffies, core->last_change + msecs_to_jiffies(500)))
284 return ret;
285
286 samples = read_rds_samples(core, &N);
287
288 if (!samples)
289 return ret;
290
291 switch (core->tvaudio) {
292 case WW_BG:
293 case WW_DK:
294 ret = detect_a2_a2m_eiaj(core, samples, N);
295 break;
296 case WW_BTSC:
297 ret = detect_btsc(core, samples, N);
298 break;
299 }
300
301 kfree(samples);
302
303 if (UNSET != ret)
304 dprintk(1, "stereo/sap detection result:%s%s%s\n",
305 (ret & V4L2_TUNER_SUB_MONO) ? " mono" : "",
306 (ret & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
307 (ret & V4L2_TUNER_SUB_LANG2) ? " dual" : "");
308
309 return ret;
310}
311EXPORT_SYMBOL(cx88_dsp_detect_stereo_sap);
312
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9389cf290c1b..c44e87600219 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1014,6 +1014,7 @@ static int dvb_register(struct cx8802_dev *dev)
1014 } 1014 }
1015 break; 1015 break;
1016 case CX88_BOARD_PINNACLE_HYBRID_PCTV: 1016 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1017 case CX88_BOARD_WINFAST_DTV1800H:
1017 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1018 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1018 &cx88_pinnacle_hybrid_pctv, 1019 &cx88_pinnacle_hybrid_pctv,
1019 &core->i2c_adap); 1020 &core->i2c_adap);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 996b4ed5a4fc..ee1ca39db06a 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -180,6 +180,19 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
180 do_i2c_scan(core->name,&core->i2c_client); 180 do_i2c_scan(core->name,&core->i2c_client);
181 } else 181 } else
182 printk("%s: i2c register FAILED\n", core->name); 182 printk("%s: i2c register FAILED\n", core->name);
183
184 /* Instantiate the IR receiver device, if present */
185 if (0 == core->i2c_rc) {
186 struct i2c_board_info info;
187 const unsigned short addr_list[] = {
188 0x18, 0x6b, 0x71,
189 I2C_CLIENT_END
190 };
191
192 memset(&info, 0, sizeof(struct i2c_board_info));
193 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
194 i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
195 }
183 return core->i2c_rc; 196 return core->i2c_rc;
184} 197}
185 198
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index ec05312a9b62..d91f5c51206d 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -91,6 +91,8 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
91 gpio=(gpio & 0x7fd) + (auxgpio & 0xef); 91 gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
92 break; 92 break;
93 case CX88_BOARD_WINFAST_DTV1000: 93 case CX88_BOARD_WINFAST_DTV1000:
94 case CX88_BOARD_WINFAST_DTV1800H:
95 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
94 gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); 96 gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
95 auxgpio = gpio; 97 auxgpio = gpio;
96 break; 98 break;
@@ -217,11 +219,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
217 case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 219 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
218 case CX88_BOARD_PCHDTV_HD3000: 220 case CX88_BOARD_PCHDTV_HD3000:
219 case CX88_BOARD_PCHDTV_HD5500: 221 case CX88_BOARD_PCHDTV_HD5500:
222 case CX88_BOARD_HAUPPAUGE_IRONLY:
220 ir_codes = ir_codes_hauppauge_new; 223 ir_codes = ir_codes_hauppauge_new;
221 ir_type = IR_TYPE_RC5; 224 ir_type = IR_TYPE_RC5;
222 ir->sampling = 1; 225 ir->sampling = 1;
223 break; 226 break;
224 case CX88_BOARD_WINFAST_DTV2000H: 227 case CX88_BOARD_WINFAST_DTV2000H:
228 case CX88_BOARD_WINFAST_DTV1800H:
225 ir_codes = ir_codes_winfast; 229 ir_codes = ir_codes_winfast;
226 ir->gpio_addr = MO_GP0_IO; 230 ir->gpio_addr = MO_GP0_IO;
227 ir->mask_keycode = 0x8f8; 231 ir->mask_keycode = 0x8f8;
@@ -230,6 +234,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
230 break; 234 break;
231 case CX88_BOARD_WINFAST2000XP_EXPERT: 235 case CX88_BOARD_WINFAST2000XP_EXPERT:
232 case CX88_BOARD_WINFAST_DTV1000: 236 case CX88_BOARD_WINFAST_DTV1000:
237 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
233 ir_codes = ir_codes_winfast; 238 ir_codes = ir_codes_winfast;
234 ir->gpio_addr = MO_GP0_IO; 239 ir->gpio_addr = MO_GP0_IO;
235 ir->mask_keycode = 0x8f8; 240 ir->mask_keycode = 0x8f8;
@@ -459,6 +464,7 @@ void cx88_ir_irq(struct cx88_core *core)
459 case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 464 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
460 case CX88_BOARD_PCHDTV_HD3000: 465 case CX88_BOARD_PCHDTV_HD3000:
461 case CX88_BOARD_PCHDTV_HD5500: 466 case CX88_BOARD_PCHDTV_HD5500:
467 case CX88_BOARD_HAUPPAUGE_IRONLY:
462 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 468 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
463 ir_dprintk("biphase decoded: %x\n", ircode); 469 ir_dprintk("biphase decoded: %x\n", ircode);
464 /* 470 /*
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 7dd506b987fe..e8316cf7f32f 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -163,6 +163,8 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
163 /* unmute */ 163 /* unmute */
164 volume = cx_sread(SHADOW_AUD_VOL_CTL); 164 volume = cx_sread(SHADOW_AUD_VOL_CTL);
165 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); 165 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
166
167 core->last_change = jiffies;
166} 168}
167 169
168/* ----------------------------------------------------------- */ 170/* ----------------------------------------------------------- */
@@ -745,6 +747,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
745 break; 747 break;
746 case WW_BG: 748 case WW_BG:
747 case WW_DK: 749 case WW_DK:
750 case WW_M:
748 case WW_I: 751 case WW_I:
749 case WW_L: 752 case WW_L:
750 /* prepare all dsp registers */ 753 /* prepare all dsp registers */
@@ -756,6 +759,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
756 if (0 == cx88_detect_nicam(core)) { 759 if (0 == cx88_detect_nicam(core)) {
757 /* fall back to fm / am mono */ 760 /* fall back to fm / am mono */
758 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 761 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
762 core->audiomode_current = V4L2_TUNER_MODE_MONO;
759 core->use_nicam = 0; 763 core->use_nicam = 0;
760 } else { 764 } else {
761 core->use_nicam = 1; 765 core->use_nicam = 1;
@@ -787,6 +791,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
787void cx88_newstation(struct cx88_core *core) 791void cx88_newstation(struct cx88_core *core)
788{ 792{
789 core->audiomode_manual = UNSET; 793 core->audiomode_manual = UNSET;
794 core->last_change = jiffies;
790} 795}
791 796
792void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) 797void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
@@ -805,12 +810,50 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
805 aud_ctl_names[cx_read(AUD_CTL) & 63]); 810 aud_ctl_names[cx_read(AUD_CTL) & 63]);
806 core->astat = reg; 811 core->astat = reg;
807 812
808/* TODO 813 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
809 Reading from AUD_STATUS is not enough 814 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
810 for auto-detecting sap/dual-fm/nicam. 815 t->rxsubchans = UNSET;
811 Add some code here later. 816 t->audmode = V4L2_TUNER_MODE_MONO;
812*/ 817
818 switch (mode) {
819 case 0:
820 t->audmode = V4L2_TUNER_MODE_STEREO;
821 break;
822 case 1:
823 t->audmode = V4L2_TUNER_MODE_LANG2;
824 break;
825 case 2:
826 t->audmode = V4L2_TUNER_MODE_MONO;
827 break;
828 case 3:
829 t->audmode = V4L2_TUNER_MODE_SAP;
830 break;
831 }
813 832
833 switch (core->tvaudio) {
834 case WW_BTSC:
835 case WW_BG:
836 case WW_DK:
837 case WW_M:
838 case WW_EIAJ:
839 if (!core->use_nicam) {
840 t->rxsubchans = cx88_dsp_detect_stereo_sap(core);
841 break;
842 }
843 break;
844 default:
845 /* nothing */
846 break;
847 }
848
849 /* If software stereo detection is not supported... */
850 if (UNSET == t->rxsubchans) {
851 t->rxsubchans = V4L2_TUNER_SUB_MONO;
852 /* If the hardware itself detected stereo, also return
853 stereo as an available subchannel */
854 if (V4L2_TUNER_MODE_STEREO == t->audmode)
855 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
856 }
814 return; 857 return;
815} 858}
816 859
@@ -847,6 +890,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
847 break; 890 break;
848 case WW_BG: 891 case WW_BG:
849 case WW_DK: 892 case WW_DK:
893 case WW_M:
850 case WW_I: 894 case WW_I:
851 case WW_L: 895 case WW_L:
852 if (1 == core->use_nicam) { 896 if (1 == core->use_nicam) {
@@ -872,20 +916,18 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
872 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 916 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
873 } else { 917 } else {
874 /* TODO: Add A2 autodection */ 918 /* TODO: Add A2 autodection */
919 mask = 0x3f;
875 switch (mode) { 920 switch (mode) {
876 case V4L2_TUNER_MODE_MONO: 921 case V4L2_TUNER_MODE_MONO:
877 case V4L2_TUNER_MODE_LANG1: 922 case V4L2_TUNER_MODE_LANG1:
878 set_audio_standard_A2(core, 923 ctl = EN_A2_FORCE_MONO1;
879 EN_A2_FORCE_MONO1);
880 break; 924 break;
881 case V4L2_TUNER_MODE_LANG2: 925 case V4L2_TUNER_MODE_LANG2:
882 set_audio_standard_A2(core, 926 ctl = EN_A2_FORCE_MONO2;
883 EN_A2_FORCE_MONO2);
884 break; 927 break;
885 case V4L2_TUNER_MODE_STEREO: 928 case V4L2_TUNER_MODE_STEREO:
886 case V4L2_TUNER_MODE_LANG1_LANG2: 929 case V4L2_TUNER_MODE_LANG1_LANG2:
887 set_audio_standard_A2(core, 930 ctl = EN_A2_FORCE_STEREO;
888 EN_A2_FORCE_STEREO);
889 break; 931 break;
890 } 932 }
891 } 933 }
@@ -932,24 +974,39 @@ int cx88_audio_thread(void *data)
932 break; 974 break;
933 try_to_freeze(); 975 try_to_freeze();
934 976
935 /* just monitor the audio status for now ... */ 977 switch (core->tvaudio) {
936 memset(&t, 0, sizeof(t)); 978 case WW_BG:
937 cx88_get_stereo(core, &t); 979 case WW_DK:
938 980 case WW_M:
939 if (UNSET != core->audiomode_manual) 981 case WW_I:
940 /* manually set, don't do anything. */ 982 case WW_L:
941 continue; 983 if (core->use_nicam)
942 984 goto hw_autodetect;
943 /* monitor signal */ 985
944 if (t.rxsubchans & V4L2_TUNER_SUB_STEREO) 986 /* just monitor the audio status for now ... */
945 mode = V4L2_TUNER_MODE_STEREO; 987 memset(&t, 0, sizeof(t));
946 else 988 cx88_get_stereo(core, &t);
947 mode = V4L2_TUNER_MODE_MONO; 989
948 if (mode == core->audiomode_current) 990 if (UNSET != core->audiomode_manual)
949 continue; 991 /* manually set, don't do anything. */
950 992 continue;
951 /* automatically switch to best available mode */ 993
952 cx88_set_stereo(core, mode, 0); 994 /* monitor signal and set stereo if available */
995 if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
996 mode = V4L2_TUNER_MODE_STEREO;
997 else
998 mode = V4L2_TUNER_MODE_MONO;
999 if (mode == core->audiomode_current)
1000 continue;
1001 /* automatically switch to best available mode */
1002 cx88_set_stereo(core, mode, 0);
1003 break;
1004 default:
1005hw_autodetect:
1006 /* stereo autodetection is supported by hardware so
1007 we don't need to do it manually. Do nothing. */
1008 break;
1009 }
953 } 1010 }
954 1011
955 dprintk("cx88: tvaudio thread exiting\n"); 1012 dprintk("cx88: tvaudio thread exiting\n");
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index b993d42fe73c..0ccac702bea4 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -869,6 +869,7 @@ video_poll(struct file *file, struct poll_table_struct *wait)
869{ 869{
870 struct cx8800_fh *fh = file->private_data; 870 struct cx8800_fh *fh = file->private_data;
871 struct cx88_buffer *buf; 871 struct cx88_buffer *buf;
872 unsigned int rc = POLLERR;
872 873
873 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 874 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
874 if (!res_get(fh->dev,fh,RESOURCE_VBI)) 875 if (!res_get(fh->dev,fh,RESOURCE_VBI))
@@ -876,22 +877,27 @@ video_poll(struct file *file, struct poll_table_struct *wait)
876 return videobuf_poll_stream(file, &fh->vbiq, wait); 877 return videobuf_poll_stream(file, &fh->vbiq, wait);
877 } 878 }
878 879
880 mutex_lock(&fh->vidq.vb_lock);
879 if (res_check(fh,RESOURCE_VIDEO)) { 881 if (res_check(fh,RESOURCE_VIDEO)) {
880 /* streaming capture */ 882 /* streaming capture */
881 if (list_empty(&fh->vidq.stream)) 883 if (list_empty(&fh->vidq.stream))
882 return POLLERR; 884 goto done;
883 buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); 885 buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream);
884 } else { 886 } else {
885 /* read() capture */ 887 /* read() capture */
886 buf = (struct cx88_buffer*)fh->vidq.read_buf; 888 buf = (struct cx88_buffer*)fh->vidq.read_buf;
887 if (NULL == buf) 889 if (NULL == buf)
888 return POLLERR; 890 goto done;
889 } 891 }
890 poll_wait(file, &buf->vb.done, wait); 892 poll_wait(file, &buf->vb.done, wait);
891 if (buf->vb.state == VIDEOBUF_DONE || 893 if (buf->vb.state == VIDEOBUF_DONE ||
892 buf->vb.state == VIDEOBUF_ERROR) 894 buf->vb.state == VIDEOBUF_ERROR)
893 return POLLIN|POLLRDNORM; 895 rc = POLLIN|POLLRDNORM;
894 return 0; 896 else
897 rc = 0;
898done:
899 mutex_unlock(&fh->vidq.vb_lock);
900 return rc;
895} 901}
896 902
897static int video_release(struct file *file) 903static int video_release(struct file *file)
@@ -926,8 +932,10 @@ static int video_release(struct file *file)
926 file->private_data = NULL; 932 file->private_data = NULL;
927 kfree(fh); 933 kfree(fh);
928 934
935 mutex_lock(&dev->core->lock);
929 if(atomic_dec_and_test(&dev->core->users)) 936 if(atomic_dec_and_test(&dev->core->users))
930 call_all(dev->core, tuner, s_standby); 937 call_all(dev->core, tuner, s_standby);
938 mutex_unlock(&dev->core->lock);
931 939
932 return 0; 940 return 0;
933} 941}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 7724d168fc04..9d83762163f5 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -65,6 +65,8 @@
65#define VBI_LINE_COUNT 17 65#define VBI_LINE_COUNT 17
66#define VBI_LINE_LENGTH 2048 66#define VBI_LINE_LENGTH 2048
67 67
68#define AUD_RDS_LINES 4
69
68/* need "shadow" registers for some write-only ones ... */ 70/* need "shadow" registers for some write-only ones ... */
69#define SHADOW_AUD_VOL_CTL 1 71#define SHADOW_AUD_VOL_CTL 1
70#define SHADOW_AUD_BAL_CTL 2 72#define SHADOW_AUD_BAL_CTL 2
@@ -132,6 +134,7 @@ struct cx88_ctrl {
132#define SRAM_CH25 4 /* audio */ 134#define SRAM_CH25 4 /* audio */
133#define SRAM_CH26 5 135#define SRAM_CH26 5
134#define SRAM_CH28 6 /* mpeg */ 136#define SRAM_CH28 6 /* mpeg */
137#define SRAM_CH27 7 /* audio rds */
135/* more */ 138/* more */
136 139
137struct sram_channel { 140struct sram_channel {
@@ -232,6 +235,8 @@ extern struct sram_channel cx88_sram_channels[];
232#define CX88_BOARD_TBS_8910 77 235#define CX88_BOARD_TBS_8910 77
233#define CX88_BOARD_PROF_6200 78 236#define CX88_BOARD_PROF_6200 78
234#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 237#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
238#define CX88_BOARD_HAUPPAUGE_IRONLY 80
239#define CX88_BOARD_WINFAST_DTV1800H 81
235 240
236enum cx88_itype { 241enum cx88_itype {
237 CX88_VMUX_COMPOSITE1 = 1, 242 CX88_VMUX_COMPOSITE1 = 1,
@@ -350,6 +355,7 @@ struct cx88_core {
350 u32 input; 355 u32 input;
351 u32 astat; 356 u32 astat;
352 u32 use_nicam; 357 u32 use_nicam;
358 unsigned long last_change;
353 359
354 /* IR remote control state */ 360 /* IR remote control state */
355 struct cx88_IR *ir; 361 struct cx88_IR *ir;
@@ -652,6 +658,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
652#define WW_I2SPT 8 658#define WW_I2SPT 8
653#define WW_FM 9 659#define WW_FM 9
654#define WW_I2SADC 10 660#define WW_I2SADC 10
661#define WW_M 11
655 662
656void cx88_set_tvaudio(struct cx88_core *core); 663void cx88_set_tvaudio(struct cx88_core *core);
657void cx88_newstation(struct cx88_core *core); 664void cx88_newstation(struct cx88_core *core);
@@ -665,6 +672,11 @@ struct cx8802_dev *cx8802_get_device(int minor);
665struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); 672struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
666 673
667/* ----------------------------------------------------------- */ 674/* ----------------------------------------------------------- */
675/* cx88-dsp.c */
676
677s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core);
678
679/* ----------------------------------------------------------- */
668/* cx88-input.c */ 680/* cx88-input.c */
669 681
670int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); 682int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 0131322475bf..7bd8a70f0a0b 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -339,6 +339,11 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
339 mutex_lock(&dev->lock); 339 mutex_lock(&dev->lock);
340 dev->adev.users--; 340 dev->adev.users--;
341 em28xx_audio_analog_set(dev); 341 em28xx_audio_analog_set(dev);
342 if (substream->runtime->dma_area) {
343 dprintk("freeing\n");
344 vfree(substream->runtime->dma_area);
345 substream->runtime->dma_area = NULL;
346 }
342 mutex_unlock(&dev->lock); 347 mutex_unlock(&dev->lock);
343 348
344 return 0; 349 return 0;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7c70738479dd..00cc791a9e44 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -49,6 +49,11 @@ static unsigned int disable_ir;
49module_param(disable_ir, int, 0444); 49module_param(disable_ir, int, 0444);
50MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); 50MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
51 51
52static unsigned int disable_usb_speed_check;
53module_param(disable_usb_speed_check, int, 0444);
54MODULE_PARM_DESC(disable_usb_speed_check,
55 "override min bandwidth requirement of 480M bps");
56
52static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 57static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
53module_param_array(card, int, NULL, 0444); 58module_param_array(card, int, NULL, 0444);
54MODULE_PARM_DESC(card, "card type"); 59MODULE_PARM_DESC(card, "card type");
@@ -104,6 +109,24 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
104/* Board - EM2870 Kworld 355u 109/* Board - EM2870 Kworld 355u
105 Analog - No input analog */ 110 Analog - No input analog */
106 111
112/* Board - EM2882 Kworld 315U digital */
113static struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
114 {EM28XX_R08_GPIO, 0xff, 0xff, 10},
115 {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
116 {EM2880_R04_GPO, 0x04, 0xff, 10},
117 {EM2880_R04_GPO, 0x0c, 0xff, 10},
118 {EM28XX_R08_GPIO, 0x7e, 0xff, 10},
119 { -1, -1, -1, -1},
120};
121
122static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = {
123 {EM2880_R04_GPO, 0x08, 0xff, 10},
124 {EM2880_R04_GPO, 0x0c, 0xff, 10},
125 {EM2880_R04_GPO, 0x08, 0xff, 10},
126 {EM2880_R04_GPO, 0x0c, 0xff, 10},
127 { -1, -1, -1, -1},
128};
129
107static struct em28xx_reg_seq kworld_330u_analog[] = { 130static struct em28xx_reg_seq kworld_330u_analog[] = {
108 {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, 131 {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
109 {EM2880_R04_GPO, 0x00, 0xff, 10}, 132 {EM2880_R04_GPO, 0x00, 0xff, 10},
@@ -140,6 +163,16 @@ static struct em28xx_reg_seq compro_mute_gpio[] = {
140 { -1, -1, -1, -1}, 163 { -1, -1, -1, -1},
141}; 164};
142 165
166/* Terratec AV350 */
167static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
168 {EM28XX_R08_GPIO, 0xff, 0x7f, 10},
169 { -1, -1, -1, -1},
170};
171
172static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
173 {EM28XX_R08_GPIO, 0xff, 0xff, 10},
174 { -1, -1, -1, -1},
175};
143/* 176/*
144 * Board definitions 177 * Board definitions
145 */ 178 */
@@ -992,16 +1025,17 @@ struct em28xx_board em28xx_boards[] = {
992 .amux = EM28XX_AMUX_LINE_IN, 1025 .amux = EM28XX_AMUX_LINE_IN,
993 } }, 1026 } },
994 }, 1027 },
995 [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { 1028 [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = {
996 .name = "PointNix Intra-Oral Camera", 1029 .name = "EM2860/SAA711X Reference Design",
997 .has_snapshot_button = 1, 1030 .has_snapshot_button = 1,
998 .tda9887_conf = TDA9887_PRESENT,
999 .tuner_type = TUNER_ABSENT, 1031 .tuner_type = TUNER_ABSENT,
1000 .decoder = EM28XX_SAA711X, 1032 .decoder = EM28XX_SAA711X,
1001 .input = { { 1033 .input = { {
1002 .type = EM28XX_VMUX_SVIDEO, 1034 .type = EM28XX_VMUX_SVIDEO,
1003 .vmux = SAA7115_SVIDEO3, 1035 .vmux = SAA7115_SVIDEO3,
1004 .amux = EM28XX_AMUX_VIDEO, 1036 }, {
1037 .type = EM28XX_VMUX_COMPOSITE1,
1038 .vmux = SAA7115_COMPOSITE0,
1005 } }, 1039 } },
1006 }, 1040 },
1007 [EM2880_BOARD_MSI_DIGIVOX_AD] = { 1041 [EM2880_BOARD_MSI_DIGIVOX_AD] = {
@@ -1095,6 +1129,63 @@ struct em28xx_board em28xx_boards[] = {
1095 .gpio = default_analog, 1129 .gpio = default_analog,
1096 } }, 1130 } },
1097 }, 1131 },
1132 [EM2882_BOARD_KWORLD_ATSC_315U] = {
1133 .name = "KWorld ATSC 315U HDTV TV Box",
1134 .valid = EM28XX_BOARD_NOT_VALIDATED,
1135 .tuner_type = TUNER_THOMSON_DTT761X,
1136 .tuner_gpio = em2882_kworld_315u_tuner_gpio,
1137 .tda9887_conf = TDA9887_PRESENT,
1138 .decoder = EM28XX_SAA711X,
1139 .has_dvb = 1,
1140 .dvb_gpio = em2882_kworld_315u_digital,
1141 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1142 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE,
1143 /* Analog mode - still not ready */
1144 /*.input = { {
1145 .type = EM28XX_VMUX_TELEVISION,
1146 .vmux = SAA7115_COMPOSITE2,
1147 .amux = EM28XX_AMUX_VIDEO,
1148 .gpio = em2882_kworld_315u_analog,
1149 .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
1150 }, {
1151 .type = EM28XX_VMUX_COMPOSITE1,
1152 .vmux = SAA7115_COMPOSITE0,
1153 .amux = EM28XX_AMUX_LINE_IN,
1154 .gpio = em2882_kworld_315u_analog1,
1155 .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
1156 }, {
1157 .type = EM28XX_VMUX_SVIDEO,
1158 .vmux = SAA7115_SVIDEO3,
1159 .amux = EM28XX_AMUX_LINE_IN,
1160 .gpio = em2882_kworld_315u_analog1,
1161 .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
1162 } }, */
1163 },
1164 [EM2880_BOARD_EMPIRE_DUAL_TV] = {
1165 .name = "Empire dual TV",
1166 .tuner_type = TUNER_XC2028,
1167 .tuner_gpio = default_tuner_gpio,
1168 .has_dvb = 1,
1169 .dvb_gpio = default_digital,
1170 .mts_firmware = 1,
1171 .decoder = EM28XX_TVP5150,
1172 .input = { {
1173 .type = EM28XX_VMUX_TELEVISION,
1174 .vmux = TVP5150_COMPOSITE0,
1175 .amux = EM28XX_AMUX_VIDEO,
1176 .gpio = default_analog,
1177 }, {
1178 .type = EM28XX_VMUX_COMPOSITE1,
1179 .vmux = TVP5150_COMPOSITE1,
1180 .amux = EM28XX_AMUX_LINE_IN,
1181 .gpio = default_analog,
1182 }, {
1183 .type = EM28XX_VMUX_SVIDEO,
1184 .vmux = TVP5150_SVIDEO,
1185 .amux = EM28XX_AMUX_LINE_IN,
1186 .gpio = default_analog,
1187 } },
1188 },
1098 [EM2881_BOARD_DNT_DA2_HYBRID] = { 1189 [EM2881_BOARD_DNT_DA2_HYBRID] = {
1099 .name = "DNT DA2 Hybrid", 1190 .name = "DNT DA2 Hybrid",
1100 .valid = EM28XX_BOARD_NOT_VALIDATED, 1191 .valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -1322,6 +1413,42 @@ struct em28xx_board em28xx_boards[] = {
1322 .amux = EM28XX_AMUX_VIDEO, 1413 .amux = EM28XX_AMUX_VIDEO,
1323 } }, 1414 } },
1324 }, 1415 },
1416 [EM2860_BOARD_TERRATEC_GRABBY] = {
1417 .name = "Terratec Grabby",
1418 .vchannels = 2,
1419 .tuner_type = TUNER_ABSENT,
1420 .decoder = EM28XX_SAA711X,
1421 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1422 .input = { {
1423 .type = EM28XX_VMUX_COMPOSITE1,
1424 .vmux = SAA7115_COMPOSITE0,
1425 .amux = EM28XX_AMUX_VIDEO2,
1426 }, {
1427 .type = EM28XX_VMUX_SVIDEO,
1428 .vmux = SAA7115_SVIDEO3,
1429 .amux = EM28XX_AMUX_VIDEO2,
1430 } },
1431 },
1432 [EM2860_BOARD_TERRATEC_AV350] = {
1433 .name = "Terratec AV350",
1434 .vchannels = 2,
1435 .tuner_type = TUNER_ABSENT,
1436 .decoder = EM28XX_TVP5150,
1437 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1438 .mute_gpio = terratec_av350_mute_gpio,
1439 .input = { {
1440 .type = EM28XX_VMUX_COMPOSITE1,
1441 .vmux = TVP5150_COMPOSITE1,
1442 .amux = EM28XX_AUDIO_SRC_LINE,
1443 .gpio = terratec_av350_unmute_gpio,
1444
1445 }, {
1446 .type = EM28XX_VMUX_SVIDEO,
1447 .vmux = TVP5150_SVIDEO,
1448 .amux = EM28XX_AUDIO_SRC_LINE,
1449 .gpio = terratec_av350_unmute_gpio,
1450 } },
1451 },
1325}; 1452};
1326const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1453const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1327 1454
@@ -1355,6 +1482,8 @@ struct usb_device_id em28xx_id_table[] = {
1355 .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, 1482 .driver_info = EM2880_BOARD_KWORLD_DVB_305U },
1356 { USB_DEVICE(0xeb1a, 0xe310), 1483 { USB_DEVICE(0xeb1a, 0xe310),
1357 .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, 1484 .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
1485 { USB_DEVICE(0xeb1a, 0xa313),
1486 .driver_info = EM2882_BOARD_KWORLD_ATSC_315U },
1358 { USB_DEVICE(0xeb1a, 0xa316), 1487 { USB_DEVICE(0xeb1a, 0xa316),
1359 .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, 1488 .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
1360 { USB_DEVICE(0xeb1a, 0xe320), 1489 { USB_DEVICE(0xeb1a, 0xe320),
@@ -1385,6 +1514,10 @@ struct usb_device_id em28xx_id_table[] = {
1385 .driver_info = EM2870_BOARD_TERRATEC_XS }, 1514 .driver_info = EM2870_BOARD_TERRATEC_XS },
1386 { USB_DEVICE(0x0ccd, 0x0047), 1515 { USB_DEVICE(0x0ccd, 0x0047),
1387 .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, 1516 .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
1517 { USB_DEVICE(0x0ccd, 0x0084),
1518 .driver_info = EM2860_BOARD_TERRATEC_AV350 },
1519 { USB_DEVICE(0x0ccd, 0x0096),
1520 .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
1388 { USB_DEVICE(0x185b, 0x2870), 1521 { USB_DEVICE(0x185b, 0x2870),
1389 .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, 1522 .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
1390 { USB_DEVICE(0x185b, 0x2041), 1523 { USB_DEVICE(0x185b, 0x2041),
@@ -1437,13 +1570,14 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1437 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, 1570 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
1438 {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, 1571 {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
1439 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, 1572 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
1573 {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
1440}; 1574};
1441 1575
1442/* I2C devicelist hash table for devices with generic USB IDs */ 1576/* I2C devicelist hash table for devices with generic USB IDs */
1443static struct em28xx_hash_table em28xx_i2c_hash[] = { 1577static struct em28xx_hash_table em28xx_i2c_hash[] = {
1444 {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, 1578 {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
1445 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, 1579 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
1446 {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, 1580 {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
1447 {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, 1581 {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
1448}; 1582};
1449 1583
@@ -1619,6 +1753,17 @@ void em28xx_pre_card_setup(struct em28xx *dev)
1619 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); 1753 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1620 break; 1754 break;
1621 1755
1756 case EM2882_BOARD_KWORLD_ATSC_315U:
1757 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
1758 msleep(10);
1759 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
1760 msleep(10);
1761 em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
1762 msleep(10);
1763 em28xx_write_reg(dev, EM2880_R04_GPO, 0x08);
1764 msleep(10);
1765 break;
1766
1622 case EM2860_BOARD_KAIOMY_TVNPC_U2: 1767 case EM2860_BOARD_KAIOMY_TVNPC_U2:
1623 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); 1768 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
1624 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); 1769 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
@@ -1664,6 +1809,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
1664 ctl->mts = em28xx_boards[dev->model].mts_firmware; 1809 ctl->mts = em28xx_boards[dev->model].mts_firmware;
1665 1810
1666 switch (dev->model) { 1811 switch (dev->model) {
1812 case EM2880_BOARD_EMPIRE_DUAL_TV:
1667 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 1813 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
1668 ctl->demod = XC3028_FE_ZARLINK456; 1814 ctl->demod = XC3028_FE_ZARLINK456;
1669 break; 1815 break;
@@ -1835,12 +1981,20 @@ static int em28xx_hint_board(struct em28xx *dev)
1835} 1981}
1836 1982
1837/* ----------------------------------------------------------------------- */ 1983/* ----------------------------------------------------------------------- */
1838void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) 1984void em28xx_register_i2c_ir(struct em28xx *dev)
1839{ 1985{
1840 if (disable_ir) { 1986 struct i2c_board_info info;
1841 ir->get_key = NULL; 1987 struct IR_i2c_init_data init_data;
1842 return ; 1988 const unsigned short addr_list[] = {
1843 } 1989 0x30, 0x47, I2C_CLIENT_END
1990 };
1991
1992 if (disable_ir)
1993 return;
1994
1995 memset(&info, 0, sizeof(struct i2c_board_info));
1996 memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
1997 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
1844 1998
1845 /* detect & configure */ 1999 /* detect & configure */
1846 switch (dev->model) { 2000 switch (dev->model) {
@@ -1850,22 +2004,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
1850 break; 2004 break;
1851 case (EM2800_BOARD_TERRATEC_CINERGY_200): 2005 case (EM2800_BOARD_TERRATEC_CINERGY_200):
1852 case (EM2820_BOARD_TERRATEC_CINERGY_250): 2006 case (EM2820_BOARD_TERRATEC_CINERGY_250):
1853 ir->ir_codes = ir_codes_em_terratec; 2007 init_data.ir_codes = ir_codes_em_terratec;
1854 ir->get_key = em28xx_get_key_terratec; 2008 init_data.get_key = em28xx_get_key_terratec;
1855 snprintf(ir->c.name, sizeof(ir->c.name), 2009 init_data.name = "i2c IR (EM28XX Terratec)";
1856 "i2c IR (EM28XX Terratec)");
1857 break; 2010 break;
1858 case (EM2820_BOARD_PINNACLE_USB_2): 2011 case (EM2820_BOARD_PINNACLE_USB_2):
1859 ir->ir_codes = ir_codes_pinnacle_grey; 2012 init_data.ir_codes = ir_codes_pinnacle_grey;
1860 ir->get_key = em28xx_get_key_pinnacle_usb_grey; 2013 init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
1861 snprintf(ir->c.name, sizeof(ir->c.name), 2014 init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
1862 "i2c IR (EM28XX Pinnacle PCTV)");
1863 break; 2015 break;
1864 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): 2016 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
1865 ir->ir_codes = ir_codes_hauppauge_new; 2017 init_data.ir_codes = ir_codes_hauppauge_new;
1866 ir->get_key = em28xx_get_key_em_haup; 2018 init_data.get_key = em28xx_get_key_em_haup;
1867 snprintf(ir->c.name, sizeof(ir->c.name), 2019 init_data.name = "i2c IR (EM2840 Hauppauge)";
1868 "i2c IR (EM2840 Hauppauge)");
1869 break; 2020 break;
1870 case (EM2820_BOARD_MSI_VOX_USB_2): 2021 case (EM2820_BOARD_MSI_VOX_USB_2):
1871 break; 2022 break;
@@ -1876,6 +2027,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
1876 case (EM2800_BOARD_GRABBEEX_USB2800): 2027 case (EM2800_BOARD_GRABBEEX_USB2800):
1877 break; 2028 break;
1878 } 2029 }
2030
2031 if (init_data.name)
2032 info.platform_data = &init_data;
2033 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
1879} 2034}
1880 2035
1881void em28xx_card_setup(struct em28xx *dev) 2036void em28xx_card_setup(struct em28xx *dev)
@@ -1886,6 +2041,9 @@ void em28xx_card_setup(struct em28xx *dev)
1886 if (em28xx_boards[dev->model].tuner_addr) 2041 if (em28xx_boards[dev->model].tuner_addr)
1887 dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; 2042 dev->tuner_addr = em28xx_boards[dev->model].tuner_addr;
1888 2043
2044 if (em28xx_boards[dev->model].tda9887_conf)
2045 dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
2046
1889 /* request some modules */ 2047 /* request some modules */
1890 switch (dev->model) { 2048 switch (dev->model) {
1891 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: 2049 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
@@ -1915,6 +2073,12 @@ void em28xx_card_setup(struct em28xx *dev)
1915#endif 2073#endif
1916 break; 2074 break;
1917 } 2075 }
2076 case EM2882_BOARD_KWORLD_ATSC_315U:
2077 em28xx_write_reg(dev, 0x0d, 0x42);
2078 msleep(10);
2079 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
2080 msleep(10);
2081 break;
1918 case EM2820_BOARD_KWORLD_PVRTV2800RF: 2082 case EM2820_BOARD_KWORLD_PVRTV2800RF:
1919 /* GPIO enables sound on KWORLD PVR TV 2800RF */ 2083 /* GPIO enables sound on KWORLD PVR TV 2800RF */
1920 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); 2084 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
@@ -2279,6 +2443,20 @@ static int em28xx_usb_probe(struct usb_interface *interface,
2279 ifnum, 2443 ifnum,
2280 interface->altsetting->desc.bInterfaceNumber); 2444 interface->altsetting->desc.bInterfaceNumber);
2281 2445
2446 /*
2447 * Make sure we have 480 Mbps of bandwidth, otherwise things like
2448 * video stream wouldn't likely work, since 12 Mbps is generally
2449 * not enough even for most Digital TV streams.
2450 */
2451 if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
2452 printk(DRIVER_NAME ": Device initialization failed.\n");
2453 printk(DRIVER_NAME ": Device must be connected to a high-speed"
2454 " USB 2.0 port.\n");
2455 em28xx_devused &= ~(1<<nr);
2456 retval = -ENODEV;
2457 goto err;
2458 }
2459
2282 if (nr >= EM28XX_MAXBOARDS) { 2460 if (nr >= EM28XX_MAXBOARDS) {
2283 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", 2461 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
2284 EM28XX_MAXBOARDS); 2462 EM28XX_MAXBOARDS);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 192b76cdd5d7..c8d7ce8fbd36 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -500,18 +500,21 @@ int em28xx_audio_setup(struct em28xx *dev)
500 500
501 /* See how this device is configured */ 501 /* See how this device is configured */
502 cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); 502 cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
503 if (cfg < 0) 503 em28xx_info("Config register raw data: 0x%02x\n", cfg);
504 if (cfg < 0) {
505 /* Register read error? */
504 cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ 506 cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */
505 else 507 } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) {
506 em28xx_info("Config register raw data: 0x%02x\n", cfg); 508 /* The device doesn't have vendor audio at all */
507 509 dev->has_alsa_audio = 0;
508 if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 510 dev->audio_mode.has_audio = 0;
509 EM28XX_CHIPCFG_I2S_3_SAMPRATES) { 511 return 0;
512 } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
513 EM28XX_CHIPCFG_I2S_3_SAMPRATES) {
510 em28xx_info("I2S Audio (3 sample rates)\n"); 514 em28xx_info("I2S Audio (3 sample rates)\n");
511 dev->audio_mode.i2s_3rates = 1; 515 dev->audio_mode.i2s_3rates = 1;
512 } 516 } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
513 if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 517 EM28XX_CHIPCFG_I2S_5_SAMPRATES) {
514 EM28XX_CHIPCFG_I2S_5_SAMPRATES) {
515 em28xx_info("I2S Audio (5 sample rates)\n"); 518 em28xx_info("I2S Audio (5 sample rates)\n");
516 dev->audio_mode.i2s_5rates = 1; 519 dev->audio_mode.i2s_5rates = 1;
517 } 520 }
@@ -938,7 +941,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
938 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, 941 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
939 GFP_KERNEL); 942 GFP_KERNEL);
940 if (!dev->isoc_ctl.transfer_buffer) { 943 if (!dev->isoc_ctl.transfer_buffer) {
941 em28xx_errdev("cannot allocate memory for usbtransfer\n"); 944 em28xx_errdev("cannot allocate memory for usb transfer\n");
942 kfree(dev->isoc_ctl.urb); 945 kfree(dev->isoc_ctl.urb);
943 return -ENOMEM; 946 return -ENOMEM;
944 } 947 }
@@ -1012,6 +1015,41 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
1012} 1015}
1013EXPORT_SYMBOL_GPL(em28xx_init_isoc); 1016EXPORT_SYMBOL_GPL(em28xx_init_isoc);
1014 1017
1018/* Determine the packet size for the DVB stream for the given device
1019 (underlying value programmed into the eeprom) */
1020int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
1021{
1022 unsigned int chip_cfg2;
1023 unsigned int packet_size = 564;
1024
1025 if (dev->chip_id == CHIP_ID_EM2874) {
1026 /* FIXME - for now assume 564 like it was before, but the
1027 em2874 code should be added to return the proper value... */
1028 packet_size = 564;
1029 } else {
1030 /* TS max packet size stored in bits 1-0 of R01 */
1031 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
1032 switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) {
1033 case EM28XX_CHIPCFG2_TS_PACKETSIZE_188:
1034 packet_size = 188;
1035 break;
1036 case EM28XX_CHIPCFG2_TS_PACKETSIZE_376:
1037 packet_size = 376;
1038 break;
1039 case EM28XX_CHIPCFG2_TS_PACKETSIZE_564:
1040 packet_size = 564;
1041 break;
1042 case EM28XX_CHIPCFG2_TS_PACKETSIZE_752:
1043 packet_size = 752;
1044 break;
1045 }
1046 }
1047
1048 em28xx_coredbg("dvb max packet size=%d\n", packet_size);
1049 return packet_size;
1050}
1051EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize);
1052
1015/* 1053/*
1016 * em28xx_wake_i2c() 1054 * em28xx_wake_i2c()
1017 * configure i2c attached devices 1055 * configure i2c attached devices
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index fcd25511209b..563dd2b1c8e9 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -25,6 +25,8 @@
25#include "em28xx.h" 25#include "em28xx.h"
26#include <media/v4l2-common.h> 26#include <media/v4l2-common.h>
27#include <media/videobuf-vmalloc.h> 27#include <media/videobuf-vmalloc.h>
28#include <media/tuner.h>
29#include "tuner-simple.h"
28 30
29#include "lgdt330x.h" 31#include "lgdt330x.h"
30#include "zl10353.h" 32#include "zl10353.h"
@@ -46,7 +48,6 @@ if (debug >= level) \
46} while (0) 48} while (0)
47 49
48#define EM28XX_DVB_NUM_BUFS 5 50#define EM28XX_DVB_NUM_BUFS 5
49#define EM28XX_DVB_MAX_PACKETSIZE 564
50#define EM28XX_DVB_MAX_PACKETS 64 51#define EM28XX_DVB_MAX_PACKETS 64
51 52
52struct em28xx_dvb { 53struct em28xx_dvb {
@@ -142,14 +143,17 @@ static int start_streaming(struct em28xx_dvb *dvb)
142{ 143{
143 int rc; 144 int rc;
144 struct em28xx *dev = dvb->adapter.priv; 145 struct em28xx *dev = dvb->adapter.priv;
146 int max_dvb_packet_size;
145 147
146 usb_set_interface(dev->udev, 0, 1); 148 usb_set_interface(dev->udev, 0, 1);
147 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 149 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
148 if (rc < 0) 150 if (rc < 0)
149 return rc; 151 return rc;
150 152
153 max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
154
151 return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, 155 return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS,
152 EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, 156 EM28XX_DVB_NUM_BUFS, max_dvb_packet_size,
153 dvb_isoc_copy); 157 dvb_isoc_copy);
154} 158}
155 159
@@ -431,6 +435,7 @@ static int dvb_init(struct em28xx *dev)
431 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 435 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
432 case EM2880_BOARD_TERRATEC_HYBRID_XS: 436 case EM2880_BOARD_TERRATEC_HYBRID_XS:
433 case EM2880_BOARD_KWORLD_DVB_310U: 437 case EM2880_BOARD_KWORLD_DVB_310U:
438 case EM2880_BOARD_EMPIRE_DUAL_TV:
434 dvb->frontend = dvb_attach(zl10353_attach, 439 dvb->frontend = dvb_attach(zl10353_attach,
435 &em28xx_zl10353_with_xc3028, 440 &em28xx_zl10353_with_xc3028,
436 &dev->i2c_adap); 441 &dev->i2c_adap);
@@ -448,6 +453,18 @@ static int dvb_init(struct em28xx *dev)
448 goto out_free; 453 goto out_free;
449 } 454 }
450 break; 455 break;
456 case EM2882_BOARD_KWORLD_ATSC_315U:
457 dvb->frontend = dvb_attach(lgdt330x_attach,
458 &em2880_lgdt3303_dev,
459 &dev->i2c_adap);
460 if (dvb->frontend != NULL) {
461 if (!dvb_attach(simple_tuner_attach, dvb->frontend,
462 &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
463 result = -EINVAL;
464 goto out_free;
465 }
466 }
467 break;
451 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 468 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
452#ifdef EM28XX_DRX397XD_SUPPORT 469#ifdef EM28XX_DRX397XD_SUPPORT
453 /* We don't have the config structure properly populated, so 470 /* We don't have the config structure properly populated, so
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index f0bf1d960c75..2c86fcf089f5 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap)
451 return I2C_FUNC_SMBUS_EMUL; 451 return I2C_FUNC_SMBUS_EMUL;
452} 452}
453 453
454/*
455 * attach_inform()
456 * gets called when a device attaches to the i2c bus
457 * does some basic configuration
458 */
459static int attach_inform(struct i2c_client *client)
460{
461 struct em28xx *dev = client->adapter->algo_data;
462 struct IR_i2c *ir = i2c_get_clientdata(client);
463
464 switch (client->addr << 1) {
465 case 0x60:
466 case 0x8e:
467 dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
468 em28xx_set_ir(dev, ir);
469 break;
470 }
471
472 return 0;
473}
474
475static struct i2c_algorithm em28xx_algo = { 454static struct i2c_algorithm em28xx_algo = {
476 .master_xfer = em28xx_i2c_xfer, 455 .master_xfer = em28xx_i2c_xfer,
477 .functionality = functionality, 456 .functionality = functionality,
@@ -482,7 +461,6 @@ static struct i2c_adapter em28xx_adap_template = {
482 .name = "em28xx", 461 .name = "em28xx",
483 .id = I2C_HW_B_EM28XX, 462 .id = I2C_HW_B_EM28XX,
484 .algo = &em28xx_algo, 463 .algo = &em28xx_algo,
485 .client_register = attach_inform,
486}; 464};
487 465
488static struct i2c_client em28xx_client_template = { 466static struct i2c_client em28xx_client_template = {
@@ -575,6 +553,9 @@ int em28xx_i2c_register(struct em28xx *dev)
575 if (i2c_scan) 553 if (i2c_scan)
576 em28xx_do_i2c_scan(dev); 554 em28xx_do_i2c_scan(dev);
577 555
556 /* Instantiate the IR receiver device, if present */
557 em28xx_register_i2c_ir(dev);
558
578 return 0; 559 return 0;
579} 560}
580 561
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index a5abfd7a19f5..7a0fe3816e3d 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
40 40
41#define i2cdprintk(fmt, arg...) \ 41#define i2cdprintk(fmt, arg...) \
42 if (ir_debug) { \ 42 if (ir_debug) { \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ 43 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
44 } 44 }
45 45
46#define dprintk(fmt, arg...) \ 46#define dprintk(fmt, arg...) \
@@ -85,7 +85,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
85 unsigned char b; 85 unsigned char b;
86 86
87 /* poll IR chip */ 87 /* poll IR chip */
88 if (1 != i2c_master_recv(&ir->c, &b, 1)) { 88 if (1 != i2c_master_recv(ir->c, &b, 1)) {
89 i2cdprintk("read error\n"); 89 i2cdprintk("read error\n");
90 return -EIO; 90 return -EIO;
91 } 91 }
@@ -114,7 +114,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
114 unsigned char code; 114 unsigned char code;
115 115
116 /* poll IR chip */ 116 /* poll IR chip */
117 if (2 != i2c_master_recv(&ir->c, buf, 2)) 117 if (2 != i2c_master_recv(ir->c, buf, 2))
118 return -EIO; 118 return -EIO;
119 119
120 /* Does eliminate repeated parity code */ 120 /* Does eliminate repeated parity code */
@@ -147,7 +147,7 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
147 147
148 /* poll IR chip */ 148 /* poll IR chip */
149 149
150 if (3 != i2c_master_recv(&ir->c, buf, 3)) { 150 if (3 != i2c_master_recv(ir->c, buf, 3)) {
151 i2cdprintk("read error\n"); 151 i2cdprintk("read error\n");
152 return -EIO; 152 return -EIO;
153 } 153 }
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 24e39c56811e..a2676d63cfd0 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -27,6 +27,22 @@
27#define EM28XX_CHIPCFG_AC97 0x10 27#define EM28XX_CHIPCFG_AC97 0x10
28#define EM28XX_CHIPCFG_AUDIOMASK 0x30 28#define EM28XX_CHIPCFG_AUDIOMASK 0x30
29 29
30#define EM28XX_R01_CHIPCFG2 0x01
31
32/* em28xx Chip Configuration 2 0x01 */
33#define EM28XX_CHIPCFG2_TS_PRESENT 0x10
34#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */
35#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00
36#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04
37#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08
38#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c
39#define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */
40#define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00
41#define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01
42#define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02
43#define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03
44
45
30 /* GPIO/GPO registers */ 46 /* GPIO/GPO registers */
31#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ 47#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
32#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ 48#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 4c4e58004f54..8bf81be1da61 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -58,7 +58,7 @@
58#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 58#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16
59#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 59#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17
60#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 60#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18
61#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 61#define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19
62#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 62#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20
63#define EM2800_BOARD_GRABBEEX_USB2800 21 63#define EM2800_BOARD_GRABBEEX_USB2800 21
64#define EM2750_BOARD_UNKNOWN 22 64#define EM2750_BOARD_UNKNOWN 22
@@ -102,6 +102,10 @@
102#define EM2860_BOARD_KAIOMY_TVNPC_U2 63 102#define EM2860_BOARD_KAIOMY_TVNPC_U2 63
103#define EM2860_BOARD_EASYCAP 64 103#define EM2860_BOARD_EASYCAP 64
104#define EM2820_BOARD_IODATA_GVMVP_SZ 65 104#define EM2820_BOARD_IODATA_GVMVP_SZ 65
105#define EM2880_BOARD_EMPIRE_DUAL_TV 66
106#define EM2860_BOARD_TERRATEC_GRABBY 67
107#define EM2860_BOARD_TERRATEC_AV350 68
108#define EM2882_BOARD_KWORLD_ATSC_315U 69
105 109
106/* Limits minimum and default number of buffers */ 110/* Limits minimum and default number of buffers */
107#define EM28XX_MIN_BUF 4 111#define EM28XX_MIN_BUF 4
@@ -615,6 +619,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
615 int num_bufs, int max_pkt_size, 619 int num_bufs, int max_pkt_size,
616 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); 620 int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
617void em28xx_uninit_isoc(struct em28xx *dev); 621void em28xx_uninit_isoc(struct em28xx *dev);
622int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
618int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 623int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
619int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); 624int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
620void em28xx_wake_i2c(struct em28xx *dev); 625void em28xx_wake_i2c(struct em28xx *dev);
@@ -639,7 +644,7 @@ extern void em28xx_card_setup(struct em28xx *dev);
639extern struct em28xx_board em28xx_boards[]; 644extern struct em28xx_board em28xx_boards[];
640extern struct usb_device_id em28xx_id_table[]; 645extern struct usb_device_id em28xx_id_table[];
641extern const unsigned int em28xx_bcount; 646extern const unsigned int em28xx_bcount;
642void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); 647void em28xx_register_i2c_ir(struct em28xx *dev);
643int em28xx_tuner_callback(void *ptr, int component, int command, int arg); 648int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
644void em28xx_release_resources(struct em28xx *dev); 649void em28xx_release_resources(struct em28xx *dev);
645 650
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 00e6863ed666..480ec5c87d0e 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -168,6 +168,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
168 168
169 cam->cam_mode = fpix_mode; 169 cam->cam_mode = fpix_mode;
170 cam->nmodes = 1; 170 cam->nmodes = 1;
171 cam->bulk = 1;
171 cam->bulk_size = FPIX_MAX_TRANSFER; 172 cam->bulk_size = FPIX_MAX_TRANSFER;
172 173
173 INIT_WORK(&dev->work_struct, dostream); 174 INIT_WORK(&dev->work_struct, dostream);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index a2741d7dccfe..f7e0355ad644 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Main USB camera driver 2 * Main USB camera driver
3 * 3 *
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr)
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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 7 * under the terms of the GNU General Public License as published by the
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) 50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0)
51 51
52#ifdef GSPCA_DEBUG 52#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 53int gspca_debug = D_ERR | D_PROBE;
@@ -441,7 +441,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
441 * look for an input transfer endpoint in an alternate setting 441 * look for an input transfer endpoint in an alternate setting
442 */ 442 */
443static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, 443static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
444 __u8 xfer) 444 int xfer)
445{ 445{
446 struct usb_host_endpoint *ep; 446 struct usb_host_endpoint *ep;
447 int i, attr; 447 int i, attr;
@@ -449,7 +449,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
449 for (i = 0; i < alt->desc.bNumEndpoints; i++) { 449 for (i = 0; i < alt->desc.bNumEndpoints; i++) {
450 ep = &alt->endpoint[i]; 450 ep = &alt->endpoint[i];
451 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 451 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
452 if (attr == xfer) 452 if (attr == xfer
453 && ep->desc.wMaxPacketSize != 0)
453 return ep; 454 return ep;
454 } 455 }
455 return NULL; 456 return NULL;
@@ -467,37 +468,28 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
467{ 468{
468 struct usb_interface *intf; 469 struct usb_interface *intf;
469 struct usb_host_endpoint *ep; 470 struct usb_host_endpoint *ep;
470 int i, ret; 471 int xfer, i, ret;
471 472
472 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 473 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
473 ep = NULL; 474 ep = NULL;
475 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
476 : USB_ENDPOINT_XFER_ISOC;
474 i = gspca_dev->alt; /* previous alt setting */ 477 i = gspca_dev->alt; /* previous alt setting */
475
476 /* try isoc */
477 while (--i >= 0) { 478 while (--i >= 0) {
478 ep = alt_xfer(&intf->altsetting[i], 479 ep = alt_xfer(&intf->altsetting[i], xfer);
479 USB_ENDPOINT_XFER_ISOC);
480 if (ep) 480 if (ep)
481 break; 481 break;
482 } 482 }
483
484 /* if no isoc, try bulk (alt 0 only) */
485 if (ep == NULL) { 483 if (ep == NULL) {
486 ep = alt_xfer(&intf->altsetting[0], 484 err("no transfer endpoint found");
487 USB_ENDPOINT_XFER_BULK); 485 return NULL;
488 if (ep == NULL) {
489 err("no transfer endpoint found");
490 return NULL;
491 }
492 i = 0;
493 gspca_dev->bulk = 1;
494 } 486 }
495 PDEBUG(D_STREAM, "use alt %d ep 0x%02x", 487 PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
496 i, ep->desc.bEndpointAddress); 488 i, ep->desc.bEndpointAddress);
497 if (i > 0) { 489 if (gspca_dev->nbalt > 1) {
498 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 490 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
499 if (ret < 0) { 491 if (ret < 0) {
500 err("set interface err %d", ret); 492 err("set alt %d err %d", i, ret);
501 return NULL; 493 return NULL;
502 } 494 }
503 } 495 }
@@ -517,13 +509,13 @@ static int create_urbs(struct gspca_dev *gspca_dev,
517 /* calculate the packet size and the number of packets */ 509 /* calculate the packet size and the number of packets */
518 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 510 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
519 511
520 if (!gspca_dev->bulk) { /* isoc */ 512 if (!gspca_dev->cam.bulk) { /* isoc */
521 513
522 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ 514 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
523 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 515 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
524 npkt = ISO_MAX_SIZE / psize; 516 npkt = gspca_dev->cam.npkt;
525 if (npkt > ISO_MAX_PKT) 517 if (npkt == 0)
526 npkt = ISO_MAX_PKT; 518 npkt = 32; /* default value */
527 bsize = psize * npkt; 519 bsize = psize * npkt;
528 PDEBUG(D_STREAM, 520 PDEBUG(D_STREAM,
529 "isoc %d pkts size %d = bsize:%d", 521 "isoc %d pkts size %d = bsize:%d",
@@ -617,7 +609,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
617 goto out; 609 goto out;
618 610
619 /* clear the bulk endpoint */ 611 /* clear the bulk endpoint */
620 if (gspca_dev->bulk) 612 if (gspca_dev->cam.bulk)
621 usb_clear_halt(gspca_dev->dev, 613 usb_clear_halt(gspca_dev->dev,
622 gspca_dev->urb[0]->pipe); 614 gspca_dev->urb[0]->pipe);
623 615
@@ -630,7 +622,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
630 gspca_dev->streaming = 1; 622 gspca_dev->streaming = 1;
631 623
632 /* some bulk transfers are started by the subdriver */ 624 /* some bulk transfers are started by the subdriver */
633 if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) 625 if (gspca_dev->cam.bulk && gspca_dev->cam.bulk_nurbs == 0)
634 break; 626 break;
635 627
636 /* submit the URBs */ 628 /* submit the URBs */
@@ -661,6 +653,8 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
661{ 653{
662 int ret; 654 int ret;
663 655
656 if (gspca_dev->alt == 0)
657 return 0;
664 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); 658 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
665 if (ret < 0) 659 if (ret < 0)
666 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); 660 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
@@ -869,6 +863,32 @@ out:
869 return ret; 863 return ret;
870} 864}
871 865
866static int vidioc_enum_framesizes(struct file *file, void *priv,
867 struct v4l2_frmsizeenum *fsize)
868{
869 struct gspca_dev *gspca_dev = priv;
870 int i;
871 __u32 index = 0;
872
873 for (i = 0; i < gspca_dev->cam.nmodes; i++) {
874 if (fsize->pixel_format !=
875 gspca_dev->cam.cam_mode[i].pixelformat)
876 continue;
877
878 if (fsize->index == index) {
879 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
880 fsize->discrete.width =
881 gspca_dev->cam.cam_mode[i].width;
882 fsize->discrete.height =
883 gspca_dev->cam.cam_mode[i].height;
884 return 0;
885 }
886 index++;
887 }
888
889 return -EINVAL;
890}
891
872static void gspca_release(struct video_device *vfd) 892static void gspca_release(struct video_device *vfd)
873{ 893{
874 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); 894 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev);
@@ -989,43 +1009,54 @@ out:
989 return ret; 1009 return ret;
990} 1010}
991 1011
1012static const struct ctrl *get_ctrl(struct gspca_dev *gspca_dev,
1013 int id)
1014{
1015 const struct ctrl *ctrls;
1016 int i;
1017
1018 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
1019 i < gspca_dev->sd_desc->nctrls;
1020 i++, ctrls++) {
1021 if (gspca_dev->ctrl_dis & (1 << i))
1022 continue;
1023 if (id == ctrls->qctrl.id)
1024 return ctrls;
1025 }
1026 return NULL;
1027}
1028
992static int vidioc_queryctrl(struct file *file, void *priv, 1029static int vidioc_queryctrl(struct file *file, void *priv,
993 struct v4l2_queryctrl *q_ctrl) 1030 struct v4l2_queryctrl *q_ctrl)
994{ 1031{
995 struct gspca_dev *gspca_dev = priv; 1032 struct gspca_dev *gspca_dev = priv;
996 int i, ix; 1033 const struct ctrl *ctrls;
1034 int i;
997 u32 id; 1035 u32 id;
998 1036
999 ix = -1; 1037 ctrls = NULL;
1000 id = q_ctrl->id; 1038 id = q_ctrl->id;
1001 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { 1039 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
1002 id &= V4L2_CTRL_ID_MASK; 1040 id &= V4L2_CTRL_ID_MASK;
1003 id++; 1041 id++;
1004 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 1042 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
1005 if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) 1043 if (gspca_dev->ctrl_dis & (1 << i))
1006 continue; 1044 continue;
1007 if (ix < 0) { 1045 if (ctrls->qctrl.id < id)
1008 ix = i;
1009 continue; 1046 continue;
1047 if (ctrls != NULL) {
1048 if (gspca_dev->sd_desc->ctrls[i].qctrl.id
1049 > ctrls->qctrl.id)
1050 continue;
1010 } 1051 }
1011 if (gspca_dev->sd_desc->ctrls[i].qctrl.id 1052 ctrls = &gspca_dev->sd_desc->ctrls[i];
1012 > gspca_dev->sd_desc->ctrls[ix].qctrl.id)
1013 continue;
1014 ix = i;
1015 }
1016 }
1017 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
1018 if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
1019 ix = i;
1020 break;
1021 } 1053 }
1054 } else {
1055 ctrls = get_ctrl(gspca_dev, id);
1022 } 1056 }
1023 if (ix < 0) 1057 if (ctrls == NULL)
1024 return -EINVAL; 1058 return -EINVAL;
1025 memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl, 1059 memcpy(q_ctrl, ctrls, sizeof *q_ctrl);
1026 sizeof *q_ctrl);
1027 if (gspca_dev->ctrl_dis & (1 << ix))
1028 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
1029 return 0; 1060 return 0;
1030} 1061}
1031 1062
@@ -1034,56 +1065,45 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1034{ 1065{
1035 struct gspca_dev *gspca_dev = priv; 1066 struct gspca_dev *gspca_dev = priv;
1036 const struct ctrl *ctrls; 1067 const struct ctrl *ctrls;
1037 int i, ret; 1068 int ret;
1038 1069
1039 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; 1070 ctrls = get_ctrl(gspca_dev, ctrl->id);
1040 i < gspca_dev->sd_desc->nctrls; 1071 if (ctrls == NULL)
1041 i++, ctrls++) { 1072 return -EINVAL;
1042 if (ctrl->id != ctrls->qctrl.id) 1073
1043 continue; 1074 if (ctrl->value < ctrls->qctrl.minimum
1044 if (gspca_dev->ctrl_dis & (1 << i)) 1075 || ctrl->value > ctrls->qctrl.maximum)
1045 return -EINVAL; 1076 return -ERANGE;
1046 if (ctrl->value < ctrls->qctrl.minimum 1077 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
1047 || ctrl->value > ctrls->qctrl.maximum) 1078 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1048 return -ERANGE; 1079 return -ERESTARTSYS;
1049 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); 1080 if (gspca_dev->present)
1050 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 1081 ret = ctrls->set(gspca_dev, ctrl->value);
1051 return -ERESTARTSYS; 1082 else
1052 if (gspca_dev->present) 1083 ret = -ENODEV;
1053 ret = ctrls->set(gspca_dev, ctrl->value); 1084 mutex_unlock(&gspca_dev->usb_lock);
1054 else 1085 return ret;
1055 ret = -ENODEV;
1056 mutex_unlock(&gspca_dev->usb_lock);
1057 return ret;
1058 }
1059 return -EINVAL;
1060} 1086}
1061 1087
1062static int vidioc_g_ctrl(struct file *file, void *priv, 1088static int vidioc_g_ctrl(struct file *file, void *priv,
1063 struct v4l2_control *ctrl) 1089 struct v4l2_control *ctrl)
1064{ 1090{
1065 struct gspca_dev *gspca_dev = priv; 1091 struct gspca_dev *gspca_dev = priv;
1066
1067 const struct ctrl *ctrls; 1092 const struct ctrl *ctrls;
1068 int i, ret; 1093 int ret;
1069 1094
1070 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; 1095 ctrls = get_ctrl(gspca_dev, ctrl->id);
1071 i < gspca_dev->sd_desc->nctrls; 1096 if (ctrls == NULL)
1072 i++, ctrls++) { 1097 return -EINVAL;
1073 if (ctrl->id != ctrls->qctrl.id) 1098
1074 continue; 1099 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1075 if (gspca_dev->ctrl_dis & (1 << i)) 1100 return -ERESTARTSYS;
1076 return -EINVAL; 1101 if (gspca_dev->present)
1077 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 1102 ret = ctrls->get(gspca_dev, &ctrl->value);
1078 return -ERESTARTSYS; 1103 else
1079 if (gspca_dev->present) 1104 ret = -ENODEV;
1080 ret = ctrls->get(gspca_dev, &ctrl->value); 1105 mutex_unlock(&gspca_dev->usb_lock);
1081 else 1106 return ret;
1082 ret = -ENODEV;
1083 mutex_unlock(&gspca_dev->usb_lock);
1084 return ret;
1085 }
1086 return -EINVAL;
1087} 1107}
1088 1108
1089/*fixme: have an audio flag in gspca_dev?*/ 1109/*fixme: have an audio flag in gspca_dev?*/
@@ -1864,6 +1884,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
1864 .vidioc_g_parm = vidioc_g_parm, 1884 .vidioc_g_parm = vidioc_g_parm,
1865 .vidioc_s_parm = vidioc_s_parm, 1885 .vidioc_s_parm = vidioc_s_parm,
1866 .vidioc_s_std = vidioc_s_std, 1886 .vidioc_s_std = vidioc_s_std,
1887 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1867#ifdef CONFIG_VIDEO_V4L1_COMPAT 1888#ifdef CONFIG_VIDEO_V4L1_COMPAT
1868 .vidiocgmbuf = vidiocgmbuf, 1889 .vidiocgmbuf = vidiocgmbuf,
1869#endif 1890#endif
@@ -1943,7 +1964,7 @@ int gspca_dev_probe(struct usb_interface *intf,
1943 1964
1944 /* init video stuff */ 1965 /* init video stuff */
1945 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); 1966 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1946 gspca_dev->vdev.parent = &dev->dev; 1967 gspca_dev->vdev.parent = &intf->dev;
1947 gspca_dev->module = module; 1968 gspca_dev->module = module;
1948 gspca_dev->present = 1; 1969 gspca_dev->present = 1;
1949 ret = video_register_device(&gspca_dev->vdev, 1970 ret = video_register_device(&gspca_dev->vdev,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 58e8ff02136a..bd1faff88644 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -44,8 +44,6 @@ extern int gspca_debug;
44#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ 44#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
45/* image transfers */ 45/* image transfers */
46#define MAX_NURBS 4 /* max number of URBs */ 46#define MAX_NURBS 4 /* max number of URBs */
47#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */
48#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */
49 47
50/* device information - set at probe time */ 48/* device information - set at probe time */
51struct cam { 49struct cam {
@@ -56,6 +54,9 @@ struct cam {
56 * - cannot be > MAX_NURBS 54 * - cannot be > MAX_NURBS
57 * - when 0 and bulk_size != 0 means 55 * - when 0 and bulk_size != 0 means
58 * 1 URB and submit done by subdriver */ 56 * 1 URB and submit done by subdriver */
57 u8 bulk; /* image transfer by 0:isoc / 1:bulk */
58 u8 npkt; /* number of packets in an ISOC message
59 * 0 is the default value: 32 packets */
59 u32 input_flags; /* value for ENUM_INPUT status flags */ 60 u32 input_flags; /* value for ENUM_INPUT status flags */
60}; 61};
61 62
@@ -168,7 +169,6 @@ struct gspca_dev {
168 __u8 iface; /* USB interface number */ 169 __u8 iface; /* USB interface number */
169 __u8 alt; /* USB alternate setting */ 170 __u8 alt; /* USB alternate setting */
170 __u8 nbalt; /* number of USB alternate settings */ 171 __u8 nbalt; /* number of USB alternate settings */
171 u8 bulk; /* image transfer by 0:isoc / 1:bulk */
172}; 172};
173 173
174int gspca_dev_probe(struct usb_interface *intf, 174int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index 9fa3644f4869..bf7a19a1e6d1 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -2,9 +2,10 @@ obj-$(CONFIG_USB_M5602) += gspca_m5602.o
2 2
3gspca_m5602-objs := m5602_core.o \ 3gspca_m5602-objs := m5602_core.o \
4 m5602_ov9650.o \ 4 m5602_ov9650.o \
5 m5602_ov7660.o \
5 m5602_mt9m111.o \ 6 m5602_mt9m111.o \
6 m5602_po1030.o \ 7 m5602_po1030.o \
7 m5602_s5k83a.o \ 8 m5602_s5k83a.o \
8 m5602_s5k4aa.o 9 m5602_s5k4aa.o
9 10
10EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file 11EXTRA_CFLAGS += -Idrivers/media/video/gspca
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 8f1cea6fd3bf..1127a405c9b2 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -45,6 +45,15 @@
45#define M5602_XB_SEN_CLK_DIV 0x15 45#define M5602_XB_SEN_CLK_DIV 0x15
46#define M5602_XB_AUD_CLK_CTRL 0x16 46#define M5602_XB_AUD_CLK_CTRL 0x16
47#define M5602_XB_AUD_CLK_DIV 0x17 47#define M5602_XB_AUD_CLK_DIV 0x17
48#define M5602_OB_AC_LINK_STATE 0x22
49#define M5602_OB_PCM_SLOT_INDEX 0x24
50#define M5602_OB_GPIO_SLOT_INDEX 0x25
51#define M5602_OB_ACRX_STATUS_ADDRESS_H 0x28
52#define M5602_OB_ACRX_STATUS_DATA_L 0x29
53#define M5602_OB_ACRX_STATUS_DATA_H 0x2a
54#define M5602_OB_ACTX_COMMAND_ADDRESS 0x31
55#define M5602_OB_ACRX_COMMAND_DATA_L 0x32
56#define M5602_OB_ACTX_COMMAND_DATA_H 0X33
48#define M5602_XB_DEVCTR1 0x41 57#define M5602_XB_DEVCTR1 0x41
49#define M5602_XB_EPSETR0 0x42 58#define M5602_XB_EPSETR0 0x42
50#define M5602_XB_EPAFCTR 0x47 59#define M5602_XB_EPAFCTR 0x47
@@ -77,7 +86,18 @@
77#define M5602_XB_GPIO_EN_L 0x75 86#define M5602_XB_GPIO_EN_L 0x75
78#define M5602_XB_GPIO_DAT 0x76 87#define M5602_XB_GPIO_DAT 0x76
79#define M5602_XB_GPIO_DIR 0x77 88#define M5602_XB_GPIO_DIR 0x77
80#define M5602_XB_MISC_CTL 0x70 89#define M5602_XB_SEN_CLK_CONTROL 0x80
90#define M5602_XB_SEN_CLK_DIVISION 0x81
91#define M5602_XB_CPR_CLK_CONTROL 0x82
92#define M5602_XB_CPR_CLK_DIVISION 0x83
93#define M5602_XB_MCU_CLK_CONTROL 0x84
94#define M5602_XB_MCU_CLK_DIVISION 0x85
95#define M5602_XB_DCT_CLK_CONTROL 0x86
96#define M5602_XB_DCT_CLK_DIVISION 0x87
97#define M5602_XB_EC_CLK_CONTROL 0x88
98#define M5602_XB_EC_CLK_DIVISION 0x89
99#define M5602_XB_LBUF_CLK_CONTROL 0x8a
100#define M5602_XB_LBUF_CLK_DIVISION 0x8b
81 101
82#define I2C_BUSY 0x80 102#define I2C_BUSY 0x80
83 103
@@ -128,10 +148,10 @@ struct sd {
128}; 148};
129 149
130int m5602_read_bridge( 150int m5602_read_bridge(
131 struct sd *sd, u8 address, u8 *i2c_data); 151 struct sd *sd, const u8 address, u8 *i2c_data);
132 152
133int m5602_write_bridge( 153int m5602_write_bridge(
134 struct sd *sd, u8 address, u8 i2c_data); 154 struct sd *sd, const u8 address, const u8 i2c_data);
135 155
136int m5602_write_sensor(struct sd *sd, const u8 address, 156int m5602_write_sensor(struct sd *sd, const u8 address,
137 u8 *i2c_data, const u8 len); 157 u8 *i2c_data, const u8 len);
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 1aac2985fee6..8a5bba16ff32 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20#include "m5602_ov7660.h"
20#include "m5602_mt9m111.h" 21#include "m5602_mt9m111.h"
21#include "m5602_po1030.h" 22#include "m5602_po1030.h"
22#include "m5602_s5k83a.h" 23#include "m5602_s5k83a.h"
@@ -35,7 +36,7 @@ static const __devinitdata struct usb_device_id m5602_table[] = {
35MODULE_DEVICE_TABLE(usb, m5602_table); 36MODULE_DEVICE_TABLE(usb, m5602_table);
36 37
37/* Reads a byte from the m5602 */ 38/* Reads a byte from the m5602 */
38int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) 39int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
39{ 40{
40 int err; 41 int err;
41 struct usb_device *udev = sd->gspca_dev.dev; 42 struct usb_device *udev = sd->gspca_dev.dev;
@@ -56,7 +57,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
56} 57}
57 58
58/* Writes a byte to to the m5602 */ 59/* Writes a byte to to the m5602 */
59int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) 60int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
60{ 61{
61 int err; 62 int err;
62 struct usb_device *udev = sd->gspca_dev.dev; 63 struct usb_device *udev = sd->gspca_dev.dev;
@@ -80,6 +81,17 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
80 return (err < 0) ? err : 0; 81 return (err < 0) ? err : 0;
81} 82}
82 83
84int m5602_wait_for_i2c(struct sd *sd)
85{
86 int err;
87 u8 data;
88
89 do {
90 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data);
91 } while ((data & I2C_BUSY) && !err);
92 return err;
93}
94
83int m5602_read_sensor(struct sd *sd, const u8 address, 95int m5602_read_sensor(struct sd *sd, const u8 address,
84 u8 *i2c_data, const u8 len) 96 u8 *i2c_data, const u8 len)
85{ 97{
@@ -88,9 +100,7 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
88 if (!len || len > sd->sensor->i2c_regW) 100 if (!len || len > sd->sensor->i2c_regW)
89 return -EINVAL; 101 return -EINVAL;
90 102
91 do { 103 err = m5602_wait_for_i2c(sd);
92 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
93 } while ((*i2c_data & I2C_BUSY) && !err);
94 if (err < 0) 104 if (err < 0)
95 return err; 105 return err;
96 106
@@ -103,21 +113,25 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
103 if (err < 0) 113 if (err < 0)
104 return err; 114 return err;
105 115
116 /* Sensors with registers that are of only
117 one byte width are differently read */
118
119 /* FIXME: This works with the ov9650, but has issues with the po1030 */
106 if (sd->sensor->i2c_regW == 1) { 120 if (sd->sensor->i2c_regW == 1) {
107 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len); 121 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1);
108 if (err < 0) 122 if (err < 0)
109 return err; 123 return err;
110 124
111 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); 125 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
112 if (err < 0)
113 return err;
114 } else { 126 } else {
115 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); 127 err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
116 if (err < 0)
117 return err;
118 } 128 }
119 129
120 for (i = 0; (i < len) && !err; i++) { 130 for (i = 0; (i < len) && !err; i++) {
131 err = m5602_wait_for_i2c(sd);
132 if (err < 0)
133 return err;
134
121 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); 135 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
122 136
123 PDEBUG(D_CONF, "Reading sensor register " 137 PDEBUG(D_CONF, "Reading sensor register "
@@ -206,6 +220,11 @@ static int m5602_probe_sensor(struct sd *sd)
206 if (!sd->sensor->probe(sd)) 220 if (!sd->sensor->probe(sd))
207 return 0; 221 return 0;
208 222
223 /* Try the ov7660 */
224 sd->sensor = &ov7660;
225 if (!sd->sensor->probe(sd))
226 return 0;
227
209 /* Try the s5k83a */ 228 /* Try the s5k83a */
210 sd->sensor = &s5k83a; 229 sd->sensor = &s5k83a;
211 if (!sd->sensor->probe(sd)) 230 if (!sd->sensor->probe(sd))
@@ -409,8 +428,9 @@ MODULE_DESCRIPTION(DRIVER_DESC);
409MODULE_LICENSE("GPL"); 428MODULE_LICENSE("GPL");
410module_param(force_sensor, int, S_IRUGO | S_IWUSR); 429module_param(force_sensor, int, S_IRUGO | S_IWUSR);
411MODULE_PARM_DESC(force_sensor, 430MODULE_PARM_DESC(force_sensor,
412 "force detection of sensor, " 431 "forces detection of a sensor, "
413 "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, 4 = MT9M111, 5 = PO1030"); 432 "1 = OV9650, 2 = S5K83A, 3 = S5K4AA, "
433 "4 = MT9M111, 5 = PO1030, 6 = OV7660");
414 434
415module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); 435module_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
416MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); 436MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 7d3f9e348ef4..8d071dff6944 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,23 @@
18 18
19#include "m5602_mt9m111.h" 19#include "m5602_mt9m111.h"
20 20
21static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
22static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
23static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
24static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
25static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
26static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
27static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
28 __s32 val);
29static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
30 __s32 *val);
31static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
32static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
33static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
34static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
35static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
36static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
37
21static struct v4l2_pix_format mt9m111_modes[] = { 38static struct v4l2_pix_format mt9m111_modes[] = {
22 { 39 {
23 640, 40 640,
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
32}; 49};
33 50
34const static struct ctrl mt9m111_ctrls[] = { 51const static struct ctrl mt9m111_ctrls[] = {
52#define VFLIP_IDX 0
35 { 53 {
36 { 54 {
37 .id = V4L2_CID_VFLIP, 55 .id = V4L2_CID_VFLIP,
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = {
44 }, 62 },
45 .set = mt9m111_set_vflip, 63 .set = mt9m111_set_vflip,
46 .get = mt9m111_get_vflip 64 .get = mt9m111_get_vflip
47 }, { 65 },
66#define HFLIP_IDX 1
67 {
48 { 68 {
49 .id = V4L2_CID_HFLIP, 69 .id = V4L2_CID_HFLIP,
50 .type = V4L2_CTRL_TYPE_BOOLEAN, 70 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = {
56 }, 76 },
57 .set = mt9m111_set_hflip, 77 .set = mt9m111_set_hflip,
58 .get = mt9m111_get_hflip 78 .get = mt9m111_get_hflip
59 }, { 79 },
80#define GAIN_IDX 2
81 {
60 { 82 {
61 .id = V4L2_CID_GAIN, 83 .id = V4L2_CID_GAIN,
62 .type = V4L2_CTRL_TYPE_INTEGER, 84 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = {
64 .minimum = 0, 86 .minimum = 0,
65 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, 87 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
66 .step = 1, 88 .step = 1,
67 .default_value = DEFAULT_GAIN, 89 .default_value = MT9M111_DEFAULT_GAIN,
68 .flags = V4L2_CTRL_FLAG_SLIDER 90 .flags = V4L2_CTRL_FLAG_SLIDER
69 }, 91 },
70 .set = mt9m111_set_gain, 92 .set = mt9m111_set_gain,
71 .get = mt9m111_get_gain 93 .get = mt9m111_get_gain
72 } 94 },
95#define AUTO_WHITE_BALANCE_IDX 3
96 {
97 {
98 .id = V4L2_CID_AUTO_WHITE_BALANCE,
99 .type = V4L2_CTRL_TYPE_BOOLEAN,
100 .name = "auto white balance",
101 .minimum = 0,
102 .maximum = 1,
103 .step = 1,
104 .default_value = 0,
105 },
106 .set = mt9m111_set_auto_white_balance,
107 .get = mt9m111_get_auto_white_balance
108 },
109#define GREEN_BALANCE_IDX 4
110 {
111 {
112 .id = M5602_V4L2_CID_GREEN_BALANCE,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "green balance",
115 .minimum = 0x00,
116 .maximum = 0x7ff,
117 .step = 0x1,
118 .default_value = MT9M111_GREEN_GAIN_DEFAULT,
119 .flags = V4L2_CTRL_FLAG_SLIDER
120 },
121 .set = mt9m111_set_green_balance,
122 .get = mt9m111_get_green_balance
123 },
124#define BLUE_BALANCE_IDX 5
125 {
126 {
127 .id = V4L2_CID_BLUE_BALANCE,
128 .type = V4L2_CTRL_TYPE_INTEGER,
129 .name = "blue balance",
130 .minimum = 0x00,
131 .maximum = 0x7ff,
132 .step = 0x1,
133 .default_value = MT9M111_BLUE_GAIN_DEFAULT,
134 .flags = V4L2_CTRL_FLAG_SLIDER
135 },
136 .set = mt9m111_set_blue_balance,
137 .get = mt9m111_get_blue_balance
138 },
139#define RED_BALANCE_IDX 5
140 {
141 {
142 .id = V4L2_CID_RED_BALANCE,
143 .type = V4L2_CTRL_TYPE_INTEGER,
144 .name = "red balance",
145 .minimum = 0x00,
146 .maximum = 0x7ff,
147 .step = 0x1,
148 .default_value = MT9M111_RED_GAIN_DEFAULT,
149 .flags = V4L2_CTRL_FLAG_SLIDER
150 },
151 .set = mt9m111_set_red_balance,
152 .get = mt9m111_get_red_balance
153 },
73}; 154};
74 155
75
76static void mt9m111_dump_registers(struct sd *sd); 156static void mt9m111_dump_registers(struct sd *sd);
77 157
78int mt9m111_probe(struct sd *sd) 158int mt9m111_probe(struct sd *sd)
79{ 159{
80 u8 data[2] = {0x00, 0x00}; 160 u8 data[2] = {0x00, 0x00};
81 int i; 161 int i;
162 s32 *sensor_settings;
82 163
83 if (force_sensor) { 164 if (force_sensor) {
84 if (force_sensor == MT9M111_SENSOR) { 165 if (force_sensor == MT9M111_SENSOR) {
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd)
117 return -ENODEV; 198 return -ENODEV;
118 199
119sensor_found: 200sensor_found:
201 sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
202 GFP_KERNEL);
203 if (!sensor_settings)
204 return -ENOMEM;
205
120 sd->gspca_dev.cam.cam_mode = mt9m111_modes; 206 sd->gspca_dev.cam.cam_mode = mt9m111_modes;
121 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); 207 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
122 sd->desc->ctrls = mt9m111_ctrls; 208 sd->desc->ctrls = mt9m111_ctrls;
123 sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); 209 sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
210
211 for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
212 sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
213 sd->sensor_priv = sensor_settings;
214
124 return 0; 215 return 0;
125} 216}
126 217
127int mt9m111_init(struct sd *sd) 218int mt9m111_init(struct sd *sd)
128{ 219{
129 int i, err = 0; 220 int i, err = 0;
221 s32 *sensor_settings = sd->sensor_priv;
130 222
131 /* Init the sensor */ 223 /* Init the sensor */
132 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { 224 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd)
147 if (dump_sensor) 239 if (dump_sensor)
148 mt9m111_dump_registers(sd); 240 mt9m111_dump_registers(sd);
149 241
150 return (err < 0) ? err : 0; 242 err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
243 if (err < 0)
244 return err;
245
246 err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
247 if (err < 0)
248 return err;
249
250 err = mt9m111_set_green_balance(&sd->gspca_dev,
251 sensor_settings[GREEN_BALANCE_IDX]);
252 if (err < 0)
253 return err;
254
255 err = mt9m111_set_blue_balance(&sd->gspca_dev,
256 sensor_settings[BLUE_BALANCE_IDX]);
257 if (err < 0)
258 return err;
259
260 err = mt9m111_set_red_balance(&sd->gspca_dev,
261 sensor_settings[RED_BALANCE_IDX]);
262 if (err < 0)
263 return err;
264
265 return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
151} 266}
152 267
153int mt9m111_power_down(struct sd *sd) 268int mt9m111_start(struct sd *sd)
154{ 269{
155 return 0; 270 int i, err = 0;
271 u8 data[2];
272 struct cam *cam = &sd->gspca_dev.cam;
273 s32 *sensor_settings = sd->sensor_priv;
274
275 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
276 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
277
278 for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
279 if (start_mt9m111[i][0] == BRIDGE) {
280 err = m5602_write_bridge(sd,
281 start_mt9m111[i][1],
282 start_mt9m111[i][2]);
283 } else {
284 data[0] = start_mt9m111[i][2];
285 data[1] = start_mt9m111[i][3];
286 err = m5602_write_sensor(sd,
287 start_mt9m111[i][1], data, 2);
288 }
289 }
290 if (err < 0)
291 return err;
292
293 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
294 if (err < 0)
295 return err;
296
297 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
298 if (err < 0)
299 return err;
300
301 for (i = 0; i < 2 && !err; i++)
302 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
303 if (err < 0)
304 return err;
305
306 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
307 if (err < 0)
308 return err;
309
310 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
311 if (err < 0)
312 return err;
313
314 for (i = 0; i < 2 && !err; i++)
315 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
316 if (err < 0)
317 return err;
318
319 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
320 (width >> 8) & 0xff);
321 if (err < 0)
322 return err;
323
324 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
325 if (err < 0)
326 return err;
327
328 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
329 if (err < 0)
330 return err;
331
332 switch (width) {
333 case 640:
334 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
335 data[0] = MT9M111_RMB_OVER_SIZED;
336 data[1] = MT9M111_RMB_ROW_SKIP_2X |
337 MT9M111_RMB_COLUMN_SKIP_2X |
338 (sensor_settings[VFLIP_IDX] << 0) |
339 (sensor_settings[HFLIP_IDX] << 1);
340
341 err = m5602_write_sensor(sd,
342 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
343 break;
344
345 case 320:
346 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
347 data[0] = MT9M111_RMB_OVER_SIZED;
348 data[1] = MT9M111_RMB_ROW_SKIP_4X |
349 MT9M111_RMB_COLUMN_SKIP_4X |
350 (sensor_settings[VFLIP_IDX] << 0) |
351 (sensor_settings[HFLIP_IDX] << 1);
352 err = m5602_write_sensor(sd,
353 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
354 break;
355 }
356 return err;
156} 357}
157 358
158int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 359void mt9m111_disconnect(struct sd *sd)
360{
361 sd->sensor = NULL;
362 kfree(sd->sensor_priv);
363}
364
365static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
159{ 366{
160 int err;
161 u8 data[2] = {0x00, 0x00};
162 struct sd *sd = (struct sd *) gspca_dev; 367 struct sd *sd = (struct sd *) gspca_dev;
368 s32 *sensor_settings = sd->sensor_priv;
163 369
164 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 370 *val = sensor_settings[VFLIP_IDX];
165 data, 2);
166 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
167 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 371 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
168 372
169 return err; 373 return 0;
170} 374}
171 375
172int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 376static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
173{ 377{
174 int err; 378 int err;
175 u8 data[2] = {0x00, 0x00}; 379 u8 data[2] = {0x00, 0x00};
176 struct sd *sd = (struct sd *) gspca_dev; 380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
177 382
178 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 383 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
179 384
385 sensor_settings[VFLIP_IDX] = val;
386
387 /* The mt9m111 is flipped by default */
388 val = !val;
389
180 /* Set the correct page map */ 390 /* Set the correct page map */
181 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 391 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
182 if (err < 0) 392 if (err < 0)
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
186 if (err < 0) 396 if (err < 0)
187 return err; 397 return err;
188 398
189 data[0] = (data[0] & 0xfe) | val; 399 data[1] = (data[1] & 0xfe) | val;
190 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 400 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
191 data, 2); 401 data, 2);
192 return err; 402 return err;
193} 403}
194 404
195int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 405static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
196{ 406{
197 int err;
198 u8 data[2] = {0x00, 0x00};
199 struct sd *sd = (struct sd *) gspca_dev; 407 struct sd *sd = (struct sd *) gspca_dev;
408 s32 *sensor_settings = sd->sensor_priv;
200 409
201 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 410 *val = sensor_settings[HFLIP_IDX];
202 data, 2);
203 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
204 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 411 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
205 412
206 return err; 413 return 0;
207} 414}
208 415
209int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 416static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
210{ 417{
211 int err; 418 int err;
212 u8 data[2] = {0x00, 0x00}; 419 u8 data[2] = {0x00, 0x00};
213 struct sd *sd = (struct sd *) gspca_dev; 420 struct sd *sd = (struct sd *) gspca_dev;
421 s32 *sensor_settings = sd->sensor_priv;
214 422
215 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 423 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
216 424
425 sensor_settings[HFLIP_IDX] = val;
426
427 /* The mt9m111 is flipped by default */
428 val = !val;
429
217 /* Set the correct page map */ 430 /* Set the correct page map */
218 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 431 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
219 if (err < 0) 432 if (err < 0)
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
223 if (err < 0) 436 if (err < 0)
224 return err; 437 return err;
225 438
226 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); 439 data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
227 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 440 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
228 data, 2); 441 data, 2);
229 return err; 442 return err;
230} 443}
231 444
232int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 445static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
233{ 446{
234 int err, tmp;
235 u8 data[2] = {0x00, 0x00};
236 struct sd *sd = (struct sd *) gspca_dev; 447 struct sd *sd = (struct sd *) gspca_dev;
448 s32 *sensor_settings = sd->sensor_priv;
237 449
238 err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); 450 *val = sensor_settings[GAIN_IDX];
239 tmp = ((data[1] << 8) | data[0]); 451 PDEBUG(D_V4L2, "Read gain %d", *val);
240 452
241 *val = ((tmp & (1 << 10)) * 2) | 453 return 0;
242 ((tmp & (1 << 9)) * 2) | 454}
243 ((tmp & (1 << 8)) * 2) |
244 (tmp & 0x7f);
245 455
246 PDEBUG(D_V4L2, "Read gain %d", *val); 456static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
457 __s32 val)
458{
459 struct sd *sd = (struct sd *) gspca_dev;
460 s32 *sensor_settings = sd->sensor_priv;
461 int err;
462 u8 data[2];
463
464 err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
465 if (err < 0)
466 return err;
467
468 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
469 data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
247 470
471 err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
472
473 PDEBUG(D_V4L2, "Set auto white balance %d", val);
248 return err; 474 return err;
249} 475}
250 476
251int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 477static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
478 __s32 *val) {
479 struct sd *sd = (struct sd *) gspca_dev;
480 s32 *sensor_settings = sd->sensor_priv;
481
482 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
483 PDEBUG(D_V4L2, "Read auto white balance %d", *val);
484 return 0;
485}
486
487static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
252{ 488{
253 int err, tmp; 489 int err, tmp;
254 u8 data[2] = {0x00, 0x00}; 490 u8 data[2] = {0x00, 0x00};
255 struct sd *sd = (struct sd *) gspca_dev; 491 struct sd *sd = (struct sd *) gspca_dev;
492 s32 *sensor_settings = sd->sensor_priv;
493
494 sensor_settings[GAIN_IDX] = val;
256 495
257 /* Set the correct page map */ 496 /* Set the correct page map */
258 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 497 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
275 else 514 else
276 tmp = val; 515 tmp = val;
277 516
278 data[1] = (tmp & 0xff00) >> 8; 517 data[1] = (tmp & 0xff);
279 data[0] = (tmp & 0xff); 518 data[0] = (tmp & 0xff00) >> 8;
280 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 519 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
281 data[1], data[0]); 520 data[1], data[0]);
282 521
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
286 return err; 525 return err;
287} 526}
288 527
528static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
529{
530 int err;
531 u8 data[2];
532 struct sd *sd = (struct sd *) gspca_dev;
533 s32 *sensor_settings = sd->sensor_priv;
534
535 sensor_settings[GREEN_BALANCE_IDX] = val;
536 data[1] = (val & 0xff);
537 data[0] = (val & 0xff00) >> 8;
538
539 PDEBUG(D_V4L2, "Set green balance %d", val);
540 err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
541 data, 2);
542 if (err < 0)
543 return err;
544
545 return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
546 data, 2);
547}
548
549static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
550{
551 struct sd *sd = (struct sd *) gspca_dev;
552 s32 *sensor_settings = sd->sensor_priv;
553
554 *val = sensor_settings[GREEN_BALANCE_IDX];
555 PDEBUG(D_V4L2, "Read green balance %d", *val);
556 return 0;
557}
558
559static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
560{
561 u8 data[2];
562 struct sd *sd = (struct sd *) gspca_dev;
563 s32 *sensor_settings = sd->sensor_priv;
564
565 sensor_settings[BLUE_BALANCE_IDX] = val;
566 data[1] = (val & 0xff);
567 data[0] = (val & 0xff00) >> 8;
568
569 PDEBUG(D_V4L2, "Set blue balance %d", val);
570
571 return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
572 data, 2);
573}
574
575static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
576{
577 struct sd *sd = (struct sd *) gspca_dev;
578 s32 *sensor_settings = sd->sensor_priv;
579
580 *val = sensor_settings[BLUE_BALANCE_IDX];
581 PDEBUG(D_V4L2, "Read blue balance %d", *val);
582 return 0;
583}
584
585static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
586{
587 u8 data[2];
588 struct sd *sd = (struct sd *) gspca_dev;
589 s32 *sensor_settings = sd->sensor_priv;
590
591 sensor_settings[RED_BALANCE_IDX] = val;
592 data[1] = (val & 0xff);
593 data[0] = (val & 0xff00) >> 8;
594
595 PDEBUG(D_V4L2, "Set red balance %d", val);
596
597 return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
598 data, 2);
599}
600
601static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
602{
603 struct sd *sd = (struct sd *) gspca_dev;
604 s32 *sensor_settings = sd->sensor_priv;
605
606 *val = sensor_settings[RED_BALANCE_IDX];
607 PDEBUG(D_V4L2, "Read red balance %d", *val);
608 return 0;
609}
610
289static void mt9m111_dump_registers(struct sd *sd) 611static void mt9m111_dump_registers(struct sd *sd)
290{ 612{
291 u8 address, value[2] = {0x00, 0x00}; 613 u8 address, value[2] = {0x00, 0x00};
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 00c6db02bdb7..b3de77823091 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -37,7 +37,6 @@
37#define MT9M111_SC_VBLANK_CONTEXT_A 0x08 37#define MT9M111_SC_VBLANK_CONTEXT_A 0x08
38#define MT9M111_SC_SHUTTER_WIDTH 0x09 38#define MT9M111_SC_SHUTTER_WIDTH 0x09
39#define MT9M111_SC_ROW_SPEED 0x0a 39#define MT9M111_SC_ROW_SPEED 0x0a
40
41#define MT9M111_SC_EXTRA_DELAY 0x0b 40#define MT9M111_SC_EXTRA_DELAY 0x0b
42#define MT9M111_SC_SHUTTER_DELAY 0x0c 41#define MT9M111_SC_SHUTTER_DELAY 0x0c
43#define MT9M111_SC_RESET 0x0d 42#define MT9M111_SC_RESET 0x0d
@@ -50,9 +49,6 @@
50#define MT9M111_SC_GREEN_2_GAIN 0x2e 49#define MT9M111_SC_GREEN_2_GAIN 0x2e
51#define MT9M111_SC_GLOBAL_GAIN 0x2f 50#define MT9M111_SC_GLOBAL_GAIN 0x2f
52 51
53#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
54#define MT9M111_RMB_MIRROR_COLS (1 << 1)
55
56#define MT9M111_CONTEXT_CONTROL 0xc8 52#define MT9M111_CONTEXT_CONTROL 0xc8
57#define MT9M111_PAGE_MAP 0xf0 53#define MT9M111_PAGE_MAP 0xf0
58#define MT9M111_BYTEWISE_ADDRESS 0xf1 54#define MT9M111_BYTEWISE_ADDRESS 0xf1
@@ -74,8 +70,37 @@
74#define MT9M111_COLORPIPE 0x01 70#define MT9M111_COLORPIPE 0x01
75#define MT9M111_CAMERA_CONTROL 0x02 71#define MT9M111_CAMERA_CONTROL 0x02
76 72
73#define MT9M111_RESET (1 << 0)
74#define MT9M111_RESTART (1 << 1)
75#define MT9M111_ANALOG_STANDBY (1 << 2)
76#define MT9M111_CHIP_ENABLE (1 << 3)
77#define MT9M111_CHIP_DISABLE (0 << 3)
78#define MT9M111_OUTPUT_DISABLE (1 << 4)
79#define MT9M111_SHOW_BAD_FRAMES (1 << 0)
80#define MT9M111_RESTART_BAD_FRAMES (1 << 1)
81#define MT9M111_SYNCHRONIZE_CHANGES (1 << 7)
82
83#define MT9M111_RMB_OVER_SIZED (1 << 0)
84#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
85#define MT9M111_RMB_MIRROR_COLS (1 << 1)
86#define MT9M111_RMB_ROW_SKIP_2X (1 << 2)
87#define MT9M111_RMB_COLUMN_SKIP_2X (1 << 3)
88#define MT9M111_RMB_ROW_SKIP_4X (1 << 4)
89#define MT9M111_RMB_COLUMN_SKIP_4X (1 << 5)
90
91#define MT9M111_COLOR_MATRIX_BYPASS (1 << 4)
92#define MT9M111_SEL_CONTEXT_B (1 << 3)
93
94#define MT9M111_TRISTATE_PIN_IN_STANDBY (1 << 1)
95#define MT9M111_SOC_SOFT_STANDBY (1 << 0)
96
97#define MT9M111_2D_DEFECT_CORRECTION_ENABLE (1 << 0)
98
77#define INITIAL_MAX_GAIN 64 99#define INITIAL_MAX_GAIN 64
78#define DEFAULT_GAIN 283 100#define MT9M111_DEFAULT_GAIN 283
101#define MT9M111_GREEN_GAIN_DEFAULT 0x20
102#define MT9M111_BLUE_GAIN_DEFAULT 0x20
103#define MT9M111_RED_GAIN_DEFAULT 0x20
79 104
80/*****************************************************************************/ 105/*****************************************************************************/
81 106
@@ -85,16 +110,10 @@ extern int dump_sensor;
85 110
86int mt9m111_probe(struct sd *sd); 111int mt9m111_probe(struct sd *sd);
87int mt9m111_init(struct sd *sd); 112int mt9m111_init(struct sd *sd);
88int mt9m111_power_down(struct sd *sd); 113int mt9m111_start(struct sd *sd);
114void mt9m111_disconnect(struct sd *sd);
89 115
90int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 116static const struct m5602_sensor mt9m111 = {
91int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
92int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
93int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
94int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
95int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
96
97const static struct m5602_sensor mt9m111 = {
98 .name = "MT9M111", 117 .name = "MT9M111",
99 118
100 .i2c_slave_id = 0xba, 119 .i2c_slave_id = 0xba,
@@ -102,7 +121,8 @@ const static struct m5602_sensor mt9m111 = {
102 121
103 .probe = mt9m111_probe, 122 .probe = mt9m111_probe,
104 .init = mt9m111_init, 123 .init = mt9m111_init,
105 .power_down = mt9m111_power_down 124 .disconnect = mt9m111_disconnect,
125 .start = mt9m111_start,
106}; 126};
107 127
108static const unsigned char preinit_mt9m111[][4] = 128static const unsigned char preinit_mt9m111[][4] =
@@ -117,7 +137,14 @@ static const unsigned char preinit_mt9m111[][4] =
117 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, 137 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
118 138
119 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, 139 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
120 {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7}, 140 {SENSOR, MT9M111_SC_RESET,
141 MT9M111_RESET |
142 MT9M111_RESTART |
143 MT9M111_ANALOG_STANDBY |
144 MT9M111_CHIP_DISABLE,
145 MT9M111_SHOW_BAD_FRAMES |
146 MT9M111_RESTART_BAD_FRAMES |
147 MT9M111_SYNCHRONIZE_CHANGES},
121 148
122 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00}, 149 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
123 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, 150 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
@@ -145,731 +172,42 @@ static const unsigned char init_mt9m111[][4] =
145 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 172 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
146 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 173 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
147 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 174 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
148 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
149 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
150 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
151 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00}, 175 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
152 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
153 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
154
155 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
156 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
157 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
158 {SENSOR, MT9M111_SC_RESET, 0xff, 0xde},
159 {SENSOR, MT9M111_SC_RESET, 0xff, 0xff},
160 {SENSOR, MT9M111_SC_RESET, 0xff, 0xf7},
161 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
162 176
163 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
164
165 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0xff, 0xff},
166
167 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
168 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
169 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
170 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
171 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
172 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
173 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
174 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
175 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
176 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
179 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
180 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
181 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
182 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, 177 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
186 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, 178 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
187 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
188
189 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
190 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
191 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
192 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
193 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
194 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
195 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
196 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
197 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
198 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
199 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
200 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
201 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
202 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
203 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
204 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
205
206 {SENSOR, 0xcd, 0x00, 0x0e},
207 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
208 {SENSOR, 0xd0, 0x00, 0x40},
209 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
210 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
211 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
212 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
213 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
214 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
215 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
216 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
217 {SENSOR, 0x33, 0x03, 0x49},
218 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
219
220 {SENSOR, 0x33, 0x03, 0x49},
221 {SENSOR, 0x34, 0xc0, 0x19},
222 {SENSOR, 0x3f, 0x20, 0x20},
223 {SENSOR, 0x40, 0x20, 0x20},
224 {SENSOR, 0x5a, 0xc0, 0x0a},
225 {SENSOR, 0x70, 0x7b, 0x0a},
226 {SENSOR, 0x71, 0xff, 0x00},
227 {SENSOR, 0x72, 0x19, 0x0e},
228 {SENSOR, 0x73, 0x18, 0x0f},
229 {SENSOR, 0x74, 0x57, 0x32},
230 {SENSOR, 0x75, 0x56, 0x34},
231 {SENSOR, 0x76, 0x73, 0x35},
232 {SENSOR, 0x77, 0x30, 0x12},
233 {SENSOR, 0x78, 0x79, 0x02},
234 {SENSOR, 0x79, 0x75, 0x06},
235 {SENSOR, 0x7a, 0x77, 0x0a},
236 {SENSOR, 0x7b, 0x78, 0x09},
237 {SENSOR, 0x7c, 0x7d, 0x06},
238 {SENSOR, 0x7d, 0x31, 0x10},
239 {SENSOR, 0x7e, 0x00, 0x7e},
240 {SENSOR, 0x80, 0x59, 0x04},
241 {SENSOR, 0x81, 0x59, 0x04},
242 {SENSOR, 0x82, 0x57, 0x0a},
243 {SENSOR, 0x83, 0x58, 0x0b},
244 {SENSOR, 0x84, 0x47, 0x0c},
245 {SENSOR, 0x85, 0x48, 0x0e},
246 {SENSOR, 0x86, 0x5b, 0x02},
247 {SENSOR, 0x87, 0x00, 0x5c},
248 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
249 {SENSOR, 0x60, 0x00, 0x80},
250 {SENSOR, 0x61, 0x00, 0x00},
251 {SENSOR, 0x62, 0x00, 0x00},
252 {SENSOR, 0x63, 0x00, 0x00},
253 {SENSOR, 0x64, 0x00, 0x00},
254
255 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
256 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
257 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
258 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
259 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
260 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
261 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
262 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
263 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
264 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
265 {SENSOR, 0x30, 0x04, 0x00},
266
267 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
268 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
269 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
270 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
271 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
272 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
273 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
274 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
275 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
276 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
277 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
278 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
279 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
280 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
281 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
282 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
283 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
284 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
285 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
286 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
287 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
288 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
289 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
290 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
291 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
292 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
293 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
294
295 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
296 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
297 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
298 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
299 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
300 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
301 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
302 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
303 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
304 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
305 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
306 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
307 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
308 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
309 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
310 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
311 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
312 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
313 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
314 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
315 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
316 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
317 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
318 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
319
320 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
321 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
322 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
323 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
324 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
325 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
326 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
327 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
328 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
329 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
330 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00}, 179 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
331 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
332 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00}, 180 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
333 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
334 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
335 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00}, 181 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
336 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
337 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
338 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
339 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
340 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
341 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
342 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
343 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
344 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
345 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
346 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
347 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
348 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
349 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
350
351 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
352 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
353 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
354 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
355 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
356 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
357 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
358 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
359 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
360 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
361 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
362 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
363 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
364 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
365 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
366
367 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
368 {SENSOR, 0xcd, 0x00, 0x0e},
369 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
370 {SENSOR, 0xd0, 0x00, 0x40},
371 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
372 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
373 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
374 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
375 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
376 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
377 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
378 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
379 {SENSOR, 0x33, 0x03, 0x49},
380 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
381
382 {SENSOR, 0x33, 0x03, 0x49},
383 {SENSOR, 0x34, 0xc0, 0x19},
384 {SENSOR, 0x3f, 0x20, 0x20},
385 {SENSOR, 0x40, 0x20, 0x20},
386 {SENSOR, 0x5a, 0xc0, 0x0a},
387 {SENSOR, 0x70, 0x7b, 0x0a},
388 {SENSOR, 0x71, 0xff, 0x00},
389 {SENSOR, 0x72, 0x19, 0x0e},
390 {SENSOR, 0x73, 0x18, 0x0f},
391 {SENSOR, 0x74, 0x57, 0x32},
392 {SENSOR, 0x75, 0x56, 0x34},
393 {SENSOR, 0x76, 0x73, 0x35},
394 {SENSOR, 0x77, 0x30, 0x12},
395 {SENSOR, 0x78, 0x79, 0x02},
396 {SENSOR, 0x79, 0x75, 0x06},
397 {SENSOR, 0x7a, 0x77, 0x0a},
398 {SENSOR, 0x7b, 0x78, 0x09},
399 {SENSOR, 0x7c, 0x7d, 0x06},
400 {SENSOR, 0x7d, 0x31, 0x10},
401 {SENSOR, 0x7e, 0x00, 0x7e},
402 {SENSOR, 0x80, 0x59, 0x04},
403 {SENSOR, 0x81, 0x59, 0x04},
404 {SENSOR, 0x82, 0x57, 0x0a},
405 {SENSOR, 0x83, 0x58, 0x0b},
406 {SENSOR, 0x84, 0x47, 0x0c},
407 {SENSOR, 0x85, 0x48, 0x0e},
408 {SENSOR, 0x86, 0x5b, 0x02},
409 {SENSOR, 0x87, 0x00, 0x5c},
410 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
411 {SENSOR, 0x60, 0x00, 0x80},
412 {SENSOR, 0x61, 0x00, 0x00},
413 {SENSOR, 0x62, 0x00, 0x00},
414 {SENSOR, 0x63, 0x00, 0x00},
415 {SENSOR, 0x64, 0x00, 0x00},
416
417 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
418 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
419 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
420 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
421 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
422 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
423 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
424 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
425 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
426 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
427 {SENSOR, 0x30, 0x04, 0x00},
428
429 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
430 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
431 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
432 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
433 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
434 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
435 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
436 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
437 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
438 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
439 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
440 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
441 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
442 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
443 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
444 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
445 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
446 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
447 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
448 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
449 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
450 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
451 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
452 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
453 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
454 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
455 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
456 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
457 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
458
459 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
460 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
461 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
462 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
463 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
464 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
465 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
466
467 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
468 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
469 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
470 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
471 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
472 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
473 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00}, 182 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
474 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
475 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
476 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00}, 183 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
477 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
478 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
479 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
480 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
481 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
482 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
483 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
484 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
485 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00}, 184 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
486 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00}, 185 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
487 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
488 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
489 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}, 186 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
490 187
491 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
492 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
493 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
494 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29}, 188 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
495 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, 189 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
496 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08}, 190 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
497 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01}, 191 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
498 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10}, 192 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
193 MT9M111_CP_OPERATING_MODE_CTL},
499 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a}, 194 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
500 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01}, 195 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
501 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01}, 196 MT9M111_2D_DEFECT_CORRECTION_ENABLE},
197 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
198 MT9M111_2D_DEFECT_CORRECTION_ENABLE},
502 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00}, 199 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
503 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00}, 200 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
504 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00}, 201 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
505 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00}, 202 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
506
507 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
508 {SENSOR, 0xcd, 0x00, 0x0e}, 203 {SENSOR, 0xcd, 0x00, 0x0e},
509 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
510 {SENSOR, 0xd0, 0x00, 0x40}, 204 {SENSOR, 0xd0, 0x00, 0x40},
511 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
512 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
513 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
514 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
515 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
516 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
517 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
518 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
519 {SENSOR, 0x33, 0x03, 0x49},
520 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
521
522 {SENSOR, 0x33, 0x03, 0x49},
523 {SENSOR, 0x34, 0xc0, 0x19},
524 {SENSOR, 0x3f, 0x20, 0x20},
525 {SENSOR, 0x40, 0x20, 0x20},
526 {SENSOR, 0x5a, 0xc0, 0x0a},
527 {SENSOR, 0x70, 0x7b, 0x0a},
528 {SENSOR, 0x71, 0xff, 0x00},
529 {SENSOR, 0x72, 0x19, 0x0e},
530 {SENSOR, 0x73, 0x18, 0x0f},
531 {SENSOR, 0x74, 0x57, 0x32},
532 {SENSOR, 0x75, 0x56, 0x34},
533 {SENSOR, 0x76, 0x73, 0x35},
534 {SENSOR, 0x77, 0x30, 0x12},
535 {SENSOR, 0x78, 0x79, 0x02},
536 {SENSOR, 0x79, 0x75, 0x06},
537 {SENSOR, 0x7a, 0x77, 0x0a},
538 {SENSOR, 0x7b, 0x78, 0x09},
539 {SENSOR, 0x7c, 0x7d, 0x06},
540 {SENSOR, 0x7d, 0x31, 0x10},
541 {SENSOR, 0x7e, 0x00, 0x7e},
542 {SENSOR, 0x80, 0x59, 0x04},
543 {SENSOR, 0x81, 0x59, 0x04},
544 {SENSOR, 0x82, 0x57, 0x0a},
545 {SENSOR, 0x83, 0x58, 0x0b},
546 {SENSOR, 0x84, 0x47, 0x0c},
547 {SENSOR, 0x85, 0x48, 0x0e},
548 {SENSOR, 0x86, 0x5b, 0x02},
549 {SENSOR, 0x87, 0x00, 0x5c},
550 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
551 {SENSOR, 0x60, 0x00, 0x80},
552 {SENSOR, 0x61, 0x00, 0x00},
553 {SENSOR, 0x62, 0x00, 0x00},
554 {SENSOR, 0x63, 0x00, 0x00},
555 {SENSOR, 0x64, 0x00, 0x00},
556 205
557 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
558 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x18},
559 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x04},
560 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x08},
561 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x38},
562 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
563 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x38},
564 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
565 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x03},
566 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x03},
567 {SENSOR, 0x30, 0x04, 0x00},
568
569 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
570 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
571 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
572 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
573 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
574 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
575 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
576 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
577 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
578 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
579 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
580 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
581 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
582 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
583 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
584 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
585 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
586 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
587 {BRIDGE, M5602_XB_HSYNC_PARA, 0x07, 0x00},
588 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
589 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
590 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00},
591 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
592 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0xf4},
593 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xea},
594 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
595 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
596 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
597 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
598 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
599 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
600 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
601 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
602 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
603 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
604 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
605 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
606 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
607 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
608 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
609 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
610 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
611 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
612 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
613 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
614 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
615 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
616 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
617 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
618 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
619 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
620 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
621 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
622 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
623 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
624 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
625 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
626 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
627 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
628 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
629 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
630 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
631 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
632 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
633 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
634 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
635 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
636 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
637 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
638 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
639 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
640 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
641 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
642 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
643 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
644 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
645 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
646 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
647 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
648 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
649 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
650 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
651 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
652 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
653 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
654 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
655 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
656 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
657
658 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
659 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
660 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
661 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
662 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
663 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
664 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
665 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
666 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
667 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
668
669 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
670 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
671 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
672 {SENSOR, 0xcd, 0x00, 0x0e},
673 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
674 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
675 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
676 {SENSOR, 0xd0, 0x00, 0x40},
677 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02}, 206 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
678 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00}, 207 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
679 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
680 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
681 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
682 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
683 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
684 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
685 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
686 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03}, 208 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
687 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
688 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
689 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
690 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
691 {SENSOR, 0x33, 0x03, 0x49},
692 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
693 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
694 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
695
696 {SENSOR, 0x33, 0x03, 0x49},
697 {SENSOR, 0x34, 0xc0, 0x19},
698 {SENSOR, 0x3f, 0x20, 0x20},
699 {SENSOR, 0x40, 0x20, 0x20},
700 {SENSOR, 0x5a, 0xc0, 0x0a},
701 {SENSOR, 0x70, 0x7b, 0x0a},
702 {SENSOR, 0x71, 0xff, 0x00},
703 {SENSOR, 0x72, 0x19, 0x0e},
704 {SENSOR, 0x73, 0x18, 0x0f},
705 {SENSOR, 0x74, 0x57, 0x32},
706 {SENSOR, 0x75, 0x56, 0x34},
707 {SENSOR, 0x76, 0x73, 0x35},
708 {SENSOR, 0x77, 0x30, 0x12},
709 {SENSOR, 0x78, 0x79, 0x02},
710 {SENSOR, 0x79, 0x75, 0x06},
711 {SENSOR, 0x7a, 0x77, 0x0a},
712 {SENSOR, 0x7b, 0x78, 0x09},
713 {SENSOR, 0x7c, 0x7d, 0x06},
714 {SENSOR, 0x7d, 0x31, 0x10},
715 {SENSOR, 0x7e, 0x00, 0x7e},
716 {SENSOR, 0x80, 0x59, 0x04},
717 {SENSOR, 0x81, 0x59, 0x04},
718 {SENSOR, 0x82, 0x57, 0x0a},
719 {SENSOR, 0x83, 0x58, 0x0b},
720 {SENSOR, 0x84, 0x47, 0x0c},
721 {SENSOR, 0x85, 0x48, 0x0e},
722 {SENSOR, 0x86, 0x5b, 0x02},
723 {SENSOR, 0x87, 0x00, 0x5c},
724 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08},
725 {SENSOR, 0x60, 0x00, 0x80},
726 {SENSOR, 0x61, 0x00, 0x00},
727 {SENSOR, 0x62, 0x00, 0x00},
728 {SENSOR, 0x63, 0x00, 0x00},
729 {SENSOR, 0x64, 0x00, 0x00},
730 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d},
731 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12},
732 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00},
733 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10},
734 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60},
735 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11},
736 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60},
737 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11},
738 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f},
739 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
740 {SENSOR, 0x30, 0x04, 0x00},
741
742 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
743 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
744 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
745 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
746 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
747 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
748 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
749 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
750 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
751 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
752 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
753 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
754 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe3, 0x00},
755 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
756 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
757 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
758 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
759 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
760 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
761 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
762 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
763 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
764 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
765 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
766
767 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
768 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
769 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x00, 0xe6},
770 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
771 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
772 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
773 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
774 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
775 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
776 {SENSOR, MT9M111_SC_RESET, 0x00, 0x09},
777 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
778 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
779 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
780 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
781 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
782 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
783 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
784 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
785 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
786 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
787 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
788 {SENSOR, MT9M111_SC_RESET, 0x00, 0x0c},
789 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
790 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
791 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
792 {SENSOR, MT9M111_SC_RESET, 0x00, 0x04},
793 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
794 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
795 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xb3, 0x00},
796 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
797 {SENSOR, MT9M111_CP_GLOBAL_CLK_CONTROL, 0x00, 0x03},
798 209
799 {BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
800 {BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
801 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
802 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
803 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
804 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
805 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
806 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
807 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04, 0x00},
808 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
809 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
810 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
811 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
812 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
813 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
814 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
815 {BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
816 {BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
817 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
818 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
819 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
820 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
821 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
822 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
823 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
824 {SENSOR, MT9M111_SC_RESET, 0x00, 0x05},
825 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00}, 210 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
826 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
827 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
828 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
829 {SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
830 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
831 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
832 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x0d, 0x00},
833 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
834 {SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
835 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
836 {SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00, 0x10},
837 {SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
838 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00, 0x01},
839 {SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00, 0x01},
840 {SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
841 {SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
842 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
843 {SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
844
845 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
846 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xcd, 0x00},
847 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
848 {SENSOR, 0xcd, 0x00, 0x0e},
849 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
850 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0xd0, 0x00},
851 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
852 {SENSOR, 0xd0, 0x00, 0x40},
853 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
854 {SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
855 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
856 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
857 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
858 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x07},
859 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
860 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x28, 0x00},
861 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
862 {SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
863 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
864
865 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
866 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
867 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
868 {SENSOR, 0x33, 0x03, 0x49},
869 {BRIDGE, M5602_XB_I2C_DEV_ADDR, 0xba, 0x00},
870 {BRIDGE, M5602_XB_I2C_REG_ADDR, 0x33, 0x00},
871 {BRIDGE, M5602_XB_I2C_CTRL, 0x1a, 0x00},
872
873 {SENSOR, 0x33, 0x03, 0x49}, 211 {SENSOR, 0x33, 0x03, 0x49},
874 {SENSOR, 0x34, 0xc0, 0x19}, 212 {SENSOR, 0x34, 0xc0, 0x19},
875 {SENSOR, 0x3f, 0x20, 0x20}, 213 {SENSOR, 0x3f, 0x20, 0x20},
@@ -898,25 +236,29 @@ static const unsigned char init_mt9m111[][4] =
898 {SENSOR, 0x85, 0x48, 0x0e}, 236 {SENSOR, 0x85, 0x48, 0x0e},
899 {SENSOR, 0x86, 0x5b, 0x02}, 237 {SENSOR, 0x86, 0x5b, 0x02},
900 {SENSOR, 0x87, 0x00, 0x5c}, 238 {SENSOR, 0x87, 0x00, 0x5c},
901 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, 0x08}, 239 {SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
902 {SENSOR, 0x60, 0x00, 0x80}, 240 {SENSOR, 0x60, 0x00, 0x80},
903 {SENSOR, 0x61, 0x00, 0x00}, 241 {SENSOR, 0x61, 0x00, 0x00},
904 {SENSOR, 0x62, 0x00, 0x00}, 242 {SENSOR, 0x62, 0x00, 0x00},
905 {SENSOR, 0x63, 0x00, 0x00}, 243 {SENSOR, 0x63, 0x00, 0x00},
906 {SENSOR, 0x64, 0x00, 0x00}, 244 {SENSOR, 0x64, 0x00, 0x00},
907 245
908 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, 246 {SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
909 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, 247 {SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
910 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, 248 {SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
911 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, 249 {SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
912 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, 250 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
913 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, 251 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
914 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, 252 {SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
915 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, 253 {SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
916 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_B, 0x01, 0x0f}, 254 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
917 {SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f},
918 {SENSOR, 0x30, 0x04, 0x00}, 255 {SENSOR, 0x30, 0x04, 0x00},
256 /* Set number of blank rows chosen to 400 */
257 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
258};
919 259
260static const unsigned char start_mt9m111[][4] =
261{
920 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 262 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
921 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 263 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
922 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 264 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -928,25 +270,6 @@ static const unsigned char init_mt9m111[][4] =
928 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 270 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
929 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 271 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
930 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 272 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
931 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
932 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
933 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
934 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
935 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
936 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
937 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
938 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
939 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, /* 639*/
940 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
941 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
942 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
943 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
944
945 {SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
946 /* Set number of blank rows chosen to 400 */
947 {SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
948 /* Set the global gain to 283 (of 512) */
949 {SENSOR, MT9M111_SC_GLOBAL_GAIN, 0x03, 0x63}
950}; 273};
951 274
952#endif 275#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
new file mode 100644
index 000000000000..7aafeb7cfa07
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -0,0 +1,227 @@
1/*
2 * Driver for the ov7660 sensor
3 *
4 * Copyright (C) 2009 Erik Andrén
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#include "m5602_ov7660.h"
20
21static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
22static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23
24const static struct ctrl ov7660_ctrls[] = {
25#define GAIN_IDX 1
26 {
27 {
28 .id = V4L2_CID_GAIN,
29 .type = V4L2_CTRL_TYPE_INTEGER,
30 .name = "gain",
31 .minimum = 0x00,
32 .maximum = 0xff,
33 .step = 0x1,
34 .default_value = OV7660_DEFAULT_GAIN,
35 .flags = V4L2_CTRL_FLAG_SLIDER
36 },
37 .set = ov7660_set_gain,
38 .get = ov7660_get_gain
39 },
40};
41
42static struct v4l2_pix_format ov7660_modes[] = {
43 {
44 640,
45 480,
46 V4L2_PIX_FMT_SBGGR8,
47 V4L2_FIELD_NONE,
48 .sizeimage =
49 640 * 480,
50 .bytesperline = 640,
51 .colorspace = V4L2_COLORSPACE_SRGB,
52 .priv = 0
53 }
54};
55
56static void ov7660_dump_registers(struct sd *sd);
57
58int ov7660_probe(struct sd *sd)
59{
60 int err = 0, i;
61 u8 prod_id = 0, ver_id = 0;
62
63 s32 *sensor_settings;
64
65 if (force_sensor) {
66 if (force_sensor == OV7660_SENSOR) {
67 info("Forcing an %s sensor", ov7660.name);
68 goto sensor_found;
69 }
70 /* If we want to force another sensor,
71 don't try to probe this one */
72 return -ENODEV;
73 }
74
75 /* Do the preinit */
76 for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
77 u8 data[2];
78
79 if (preinit_ov7660[i][0] == BRIDGE) {
80 err = m5602_write_bridge(sd,
81 preinit_ov7660[i][1],
82 preinit_ov7660[i][2]);
83 } else {
84 data[0] = preinit_ov7660[i][2];
85 err = m5602_write_sensor(sd,
86 preinit_ov7660[i][1], data, 1);
87 }
88 }
89 if (err < 0)
90 return err;
91
92 if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
93 return -ENODEV;
94
95 if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
96 return -ENODEV;
97
98 info("Sensor reported 0x%x%x", prod_id, ver_id);
99
100 if ((prod_id == 0x76) && (ver_id == 0x60)) {
101 info("Detected a ov7660 sensor");
102 goto sensor_found;
103 }
104 return -ENODEV;
105
106sensor_found:
107 sensor_settings = kmalloc(
108 ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL);
109 if (!sensor_settings)
110 return -ENOMEM;
111
112 sd->gspca_dev.cam.cam_mode = ov7660_modes;
113 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
114 sd->desc->ctrls = ov7660_ctrls;
115 sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls);
116
117 for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++)
118 sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value;
119 sd->sensor_priv = sensor_settings;
120
121 return 0;
122}
123
124int ov7660_init(struct sd *sd)
125{
126 int i, err = 0;
127 s32 *sensor_settings = sd->sensor_priv;
128
129 /* Init the sensor */
130 for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
131 u8 data[2];
132
133 if (init_ov7660[i][0] == BRIDGE) {
134 err = m5602_write_bridge(sd,
135 init_ov7660[i][1],
136 init_ov7660[i][2]);
137 } else {
138 data[0] = init_ov7660[i][2];
139 err = m5602_write_sensor(sd,
140 init_ov7660[i][1], data, 1);
141 }
142 }
143
144 if (dump_sensor)
145 ov7660_dump_registers(sd);
146
147 err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
148 if (err < 0)
149 return err;
150
151 return err;
152}
153
154int ov7660_start(struct sd *sd)
155{
156 return 0;
157}
158
159int ov7660_stop(struct sd *sd)
160{
161 return 0;
162}
163
164void ov7660_disconnect(struct sd *sd)
165{
166 ov7660_stop(sd);
167
168 sd->sensor = NULL;
169 kfree(sd->sensor_priv);
170}
171
172static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
173{
174 struct sd *sd = (struct sd *) gspca_dev;
175 s32 *sensor_settings = sd->sensor_priv;
176
177 *val = sensor_settings[GAIN_IDX];
178 PDEBUG(D_V4L2, "Read gain %d", *val);
179 return 0;
180}
181
182static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
183{
184 int err;
185 u8 i2c_data;
186 struct sd *sd = (struct sd *) gspca_dev;
187 s32 *sensor_settings = sd->sensor_priv;
188
189 PDEBUG(D_V4L2, "Setting gain to %d", val);
190
191 sensor_settings[GAIN_IDX] = val;
192
193 err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
194 return err;
195}
196
197static void ov7660_dump_registers(struct sd *sd)
198{
199 int address;
200 info("Dumping the ov7660 register state");
201 for (address = 0; address < 0xa9; address++) {
202 u8 value;
203 m5602_read_sensor(sd, address, &value, 1);
204 info("register 0x%x contains 0x%x",
205 address, value);
206 }
207
208 info("ov7660 register state dump complete");
209
210 info("Probing for which registers that are read/write");
211 for (address = 0; address < 0xff; address++) {
212 u8 old_value, ctrl_value;
213 u8 test_value[2] = {0xff, 0xff};
214
215 m5602_read_sensor(sd, address, &old_value, 1);
216 m5602_write_sensor(sd, address, test_value, 1);
217 m5602_read_sensor(sd, address, &ctrl_value, 1);
218
219 if (ctrl_value == test_value[0])
220 info("register 0x%x is writeable", address);
221 else
222 info("register 0x%x is read only", address);
223
224 /* Restore original value */
225 m5602_write_sensor(sd, address, &old_value, 1);
226 }
227}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
new file mode 100644
index 000000000000..3f2c169a93ea
--- /dev/null
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -0,0 +1,279 @@
1/*
2 * Driver for the ov7660 sensor
3 *
4 * Copyright (C) 2009 Erik Andrén
5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7 *
8 * Portions of code to USB interface and ALi driver software,
9 * Copyright (c) 2006 Willem Duinker
10 * v4l2 interface modeled after the V4L2 driver
11 * for SN9C10x PC Camera Controllers
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 */
18
19#ifndef M5602_OV7660_H_
20#define M5602_OV7660_H_
21
22#include "m5602_sensor.h"
23
24#define OV7660_GAIN 0x00
25#define OV7660_BLUE_GAIN 0x01
26#define OV7660_RED_GAIN 0x02
27#define OV7660_VREF 0x03
28#define OV7660_COM1 0x04
29#define OV7660_BAVE 0x05
30#define OV7660_GEAVE 0x06
31#define OV7660_AECHH 0x07
32#define OV7660_RAVE 0x08
33#define OV7660_COM2 0x09
34#define OV7660_PID 0x0a
35#define OV7660_VER 0x0b
36#define OV7660_COM3 0x0c
37#define OV7660_COM4 0x0d
38#define OV7660_COM5 0x0e
39#define OV7660_COM6 0x0f
40#define OV7660_AECH 0x10
41#define OV7660_CLKRC 0x11
42#define OV7660_COM7 0x12
43#define OV7660_COM8 0x13
44#define OV7660_COM9 0x14
45#define OV7660_COM10 0x15
46#define OV7660_RSVD16 0x16
47#define OV7660_HSTART 0x17
48#define OV7660_HSTOP 0x18
49#define OV7660_VSTART 0x19
50#define OV7660_VSTOP 0x1a
51#define OV7660_PSHFT 0x1b
52#define OV7660_MIDH 0x1c
53#define OV7660_MIDL 0x1d
54#define OV7660_MVFP 0x1e
55#define OV7660_LAEC 0x1f
56#define OV7660_BOS 0x20
57#define OV7660_GBOS 0x21
58#define OV7660_GROS 0x22
59#define OV7660_ROS 0x23
60#define OV7660_AEW 0x24
61#define OV7660_AEB 0x25
62#define OV7660_VPT 0x26
63#define OV7660_BBIAS 0x27
64#define OV7660_GbBIAS 0x28
65#define OV7660_RSVD29 0x29
66#define OV7660_RBIAS 0x2c
67#define OV7660_HREF 0x32
68#define OV7660_ADC 0x37
69#define OV7660_OFON 0x39
70#define OV7660_TSLB 0x3a
71#define OV7660_COM12 0x3c
72#define OV7660_COM13 0x3d
73#define OV7660_LCC1 0x62
74#define OV7660_LCC2 0x63
75#define OV7660_LCC3 0x64
76#define OV7660_LCC4 0x65
77#define OV7660_LCC5 0x66
78#define OV7660_HV 0x69
79#define OV7660_RSVDA1 0xa1
80
81#define OV7660_DEFAULT_GAIN 0x0e
82#define OV7660_DEFAULT_RED_GAIN 0x80
83#define OV7660_DEFAULT_BLUE_GAIN 0x80
84#define OV7660_DEFAULT_SATURATION 0x00
85#define OV7660_DEFAULT_EXPOSURE 0x20
86
87/* Kernel module parameters */
88extern int force_sensor;
89extern int dump_sensor;
90
91int ov7660_probe(struct sd *sd);
92int ov7660_init(struct sd *sd);
93int ov7660_start(struct sd *sd);
94int ov7660_stop(struct sd *sd);
95void ov7660_disconnect(struct sd *sd);
96
97const static struct m5602_sensor ov7660 = {
98 .name = "ov7660",
99 .i2c_slave_id = 0x42,
100 .i2c_regW = 1,
101 .probe = ov7660_probe,
102 .init = ov7660_init,
103 .start = ov7660_start,
104 .stop = ov7660_stop,
105 .disconnect = ov7660_disconnect,
106};
107
108static const unsigned char preinit_ov7660[][4] =
109{
110 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
111 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
112 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
113 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
114 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
115 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
116 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
117 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
118 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
119 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
120 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
121
122 {SENSOR, OV7660_OFON, 0x0c},
123 {SENSOR, OV7660_COM2, 0x11},
124 {SENSOR, OV7660_COM7, 0x05},
125
126 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
127 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
128 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
129 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
130 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
131 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
132 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
133 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
134 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
135 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
136 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
137 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
138 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
139 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
140 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
141};
142
143static const unsigned char init_ov7660[][4] =
144{
145 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
146 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
147 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
148 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
149 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
150 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
151 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
152 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
153 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
154 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
155 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
156
157 {SENSOR, OV7660_OFON, 0x0c},
158 {SENSOR, OV7660_COM2, 0x11},
159 {SENSOR, OV7660_COM7, 0x05},
160
161 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
162 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
163 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
164 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
165 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
166 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
167 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
168 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
169 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
170 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
171 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
172 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
173 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
174 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
175 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
176
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
179
180 {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
181 {SENSOR, OV7660_COM1, 0x00},
182
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
186 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
187 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
188 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
189 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
190
191 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
192 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
193 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
194 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
195 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
196 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
197 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
198 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
199
200 {SENSOR, OV7660_COM7, 0x80},
201 {SENSOR, OV7660_CLKRC, 0x80},
202 {SENSOR, OV7660_BLUE_GAIN, 0x80},
203 {SENSOR, OV7660_RED_GAIN, 0x80},
204 {SENSOR, OV7660_COM9, 0x4c},
205 {SENSOR, OV7660_OFON, 0x43},
206 {SENSOR, OV7660_COM12, 0x28},
207 {SENSOR, OV7660_COM8, 0x00},
208 {SENSOR, OV7660_COM10, 0x40},
209 {SENSOR, OV7660_HSTART, 0x0c},
210 {SENSOR, OV7660_HSTOP, 0x61},
211 {SENSOR, OV7660_HREF, 0xa4},
212 {SENSOR, OV7660_PSHFT, 0x0b},
213 {SENSOR, OV7660_VSTART, 0x01},
214 {SENSOR, OV7660_VSTOP, 0x7a},
215 {SENSOR, OV7660_VREF, 0x00},
216 {SENSOR, OV7660_COM7, 0x05},
217 {SENSOR, OV7660_COM6, 0x4b},
218 {SENSOR, OV7660_BBIAS, 0x98},
219 {SENSOR, OV7660_GbBIAS, 0x98},
220 {SENSOR, OV7660_RSVD29, 0x98},
221 {SENSOR, OV7660_RBIAS, 0x98},
222 {SENSOR, OV7660_COM1, 0x00},
223 {SENSOR, OV7660_AECH, 0x00},
224 {SENSOR, OV7660_AECHH, 0x00},
225 {SENSOR, OV7660_ADC, 0x04},
226 {SENSOR, OV7660_COM13, 0x00},
227 {SENSOR, OV7660_RSVDA1, 0x23},
228 {SENSOR, OV7660_TSLB, 0x0d},
229 {SENSOR, OV7660_HV, 0x80},
230 {SENSOR, OV7660_LCC1, 0x00},
231 {SENSOR, OV7660_LCC2, 0x00},
232 {SENSOR, OV7660_LCC3, 0x10},
233 {SENSOR, OV7660_LCC4, 0x40},
234 {SENSOR, OV7660_LCC5, 0x01},
235
236 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
237 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
238 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
239 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
240 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
241 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
242 {BRIDGE, M5602_XB_SIG_INI, 0x01},
243 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
244 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
245 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
246 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
247 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
248 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
249 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
251 {BRIDGE, M5602_XB_SIG_INI, 0x00},
252 {BRIDGE, M5602_XB_SIG_INI, 0x02},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */
257 {BRIDGE, M5602_XB_SIG_INI, 0x00},
258
259 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
260 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
261
262 {SENSOR, OV7660_AECH, 0x20},
263 {SENSOR, OV7660_COM1, 0x00},
264 {SENSOR, OV7660_OFON, 0x0c},
265 {SENSOR, OV7660_COM2, 0x11},
266 {SENSOR, OV7660_COM7, 0x05},
267 {SENSOR, OV7660_BLUE_GAIN, 0x80},
268 {SENSOR, OV7660_RED_GAIN, 0x80},
269
270 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
271 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
272 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
273 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
274 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
275 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
276 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
277};
278
279#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index fc4548fd441d..c2739d6605a1 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -18,44 +18,87 @@
18 18
19#include "m5602_ov9650.h" 19#include "m5602_ov9650.h"
20 20
21static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
22static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
23static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
26static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
27static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
28static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
29static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
30static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
31static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
32static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
33static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
34 __s32 *val);
35static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
36 __s32 val);
37static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
38static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
39static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
40static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
41
21/* Vertically and horizontally flips the image if matched, needed for machines 42/* Vertically and horizontally flips the image if matched, needed for machines
22 where the sensor is mounted upside down */ 43 where the sensor is mounted upside down */
23static 44static
24 const 45 const
25 struct dmi_system_id ov9650_flip_dmi_table[] = { 46 struct dmi_system_id ov9650_flip_dmi_table[] = {
26 { 47 {
27 .ident = "ASUS A6VC", 48 .ident = "ASUS A6Ja",
28 .matches = { 49 .matches = {
29 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
30 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J")
31 } 52 }
32 }, 53 },
33 { 54 {
34 .ident = "ASUS A6VM", 55 .ident = "ASUS A6JC",
35 .matches = { 56 .matches = {
36 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
37 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 58 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC")
38 } 59 }
39 }, 60 },
40 { 61 {
41 .ident = "ASUS A6JC", 62 .ident = "ASUS A6K",
42 .matches = { 63 .matches = {
43 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 64 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
44 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 65 DMI_MATCH(DMI_PRODUCT_NAME, "A6K")
45 } 66 }
46 }, 67 },
47 { 68 {
48 .ident = "ASUS A6Ja", 69 .ident = "ASUS A6Kt",
49 .matches = { 70 .matches = {
50 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 71 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
51 DMI_MATCH(DMI_PRODUCT_NAME, "A6J") 72 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt")
52 } 73 }
53 }, 74 },
54 { 75 {
55 .ident = "ASUS A6Kt", 76 .ident = "ASUS A6VA",
56 .matches = { 77 .matches = {
57 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 78 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
58 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 79 DMI_MATCH(DMI_PRODUCT_NAME, "A6VA")
80 }
81 },
82 {
83
84 .ident = "ASUS A6VC",
85 .matches = {
86 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
87 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC")
88 }
89 },
90 {
91 .ident = "ASUS A6VM",
92 .matches = {
93 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
94 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
95 }
96 },
97 {
98 .ident = "ASUS A7V",
99 .matches = {
100 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
101 DMI_MATCH(DMI_PRODUCT_NAME, "A7V")
59 } 102 }
60 }, 103 },
61 { 104 {
@@ -68,7 +111,7 @@ static
68 {} 111 {}
69}; 112};
70 113
71const static struct ctrl ov9650_ctrls[] = { 114static const struct ctrl ov9650_ctrls[] = {
72#define EXPOSURE_IDX 0 115#define EXPOSURE_IDX 0
73 { 116 {
74 { 117 {
@@ -102,6 +145,7 @@ const static struct ctrl ov9650_ctrls[] = {
102#define RED_BALANCE_IDX 2 145#define RED_BALANCE_IDX 2
103 { 146 {
104 { 147 {
148 .id = V4L2_CID_RED_BALANCE,
105 .type = V4L2_CTRL_TYPE_INTEGER, 149 .type = V4L2_CTRL_TYPE_INTEGER,
106 .name = "red balance", 150 .name = "red balance",
107 .minimum = 0x00, 151 .minimum = 0x00,
@@ -116,6 +160,7 @@ const static struct ctrl ov9650_ctrls[] = {
116#define BLUE_BALANCE_IDX 3 160#define BLUE_BALANCE_IDX 3
117 { 161 {
118 { 162 {
163 .id = V4L2_CID_BLUE_BALANCE,
119 .type = V4L2_CTRL_TYPE_INTEGER, 164 .type = V4L2_CTRL_TYPE_INTEGER,
120 .name = "blue balance", 165 .name = "blue balance",
121 .minimum = 0x00, 166 .minimum = 0x00,
@@ -182,7 +227,22 @@ const static struct ctrl ov9650_ctrls[] = {
182 }, 227 },
183 .set = ov9650_set_auto_gain, 228 .set = ov9650_set_auto_gain,
184 .get = ov9650_get_auto_gain 229 .get = ov9650_get_auto_gain
230 },
231#define AUTO_EXPOSURE_IDX 8
232 {
233 {
234 .id = V4L2_CID_EXPOSURE_AUTO,
235 .type = V4L2_CTRL_TYPE_BOOLEAN,
236 .name = "auto exposure",
237 .minimum = 0,
238 .maximum = 1,
239 .step = 1,
240 .default_value = 1
241 },
242 .set = ov9650_set_auto_exposure,
243 .get = ov9650_get_auto_exposure
185 } 244 }
245
186}; 246};
187 247
188static struct v4l2_pix_format ov9650_modes[] = { 248static struct v4l2_pix_format ov9650_modes[] = {
@@ -289,12 +349,6 @@ sensor_found:
289 for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) 349 for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
290 sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; 350 sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
291 sd->sensor_priv = sensor_settings; 351 sd->sensor_priv = sensor_settings;
292
293 if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
294 info("vflip quirk active");
295 sensor_settings[VFLIP_IDX] = 1;
296 }
297
298 return 0; 352 return 0;
299} 353}
300 354
@@ -316,7 +370,8 @@ int ov9650_init(struct sd *sd)
316 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 370 err = m5602_write_bridge(sd, init_ov9650[i][1], data);
317 } 371 }
318 372
319 err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); 373 err = ov9650_set_exposure(&sd->gspca_dev,
374 sensor_settings[EXPOSURE_IDX]);
320 if (err < 0) 375 if (err < 0)
321 return err; 376 return err;
322 377
@@ -324,11 +379,13 @@ int ov9650_init(struct sd *sd)
324 if (err < 0) 379 if (err < 0)
325 return err; 380 return err;
326 381
327 err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]); 382 err = ov9650_set_red_balance(&sd->gspca_dev,
383 sensor_settings[RED_BALANCE_IDX]);
328 if (err < 0) 384 if (err < 0)
329 return err; 385 return err;
330 386
331 err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]); 387 err = ov9650_set_blue_balance(&sd->gspca_dev,
388 sensor_settings[BLUE_BALANCE_IDX]);
332 if (err < 0) 389 if (err < 0)
333 return err; 390 return err;
334 391
@@ -340,11 +397,18 @@ int ov9650_init(struct sd *sd)
340 if (err < 0) 397 if (err < 0)
341 return err; 398 return err;
342 399
343 err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]); 400 err = ov9650_set_auto_exposure(&sd->gspca_dev,
401 sensor_settings[AUTO_EXPOSURE_IDX]);
402 if (err < 0)
403 return err;
404
405 err = ov9650_set_auto_white_balance(&sd->gspca_dev,
406 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
344 if (err < 0) 407 if (err < 0)
345 return err; 408 return err;
346 409
347 err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]); 410 err = ov9650_set_auto_gain(&sd->gspca_dev,
411 sensor_settings[AUTO_GAIN_CTRL_IDX]);
348 return err; 412 return err;
349} 413}
350 414
@@ -360,7 +424,10 @@ int ov9650_start(struct sd *sd)
360 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 424 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
361 int hor_offs = OV9650_LEFT_OFFSET; 425 int hor_offs = OV9650_LEFT_OFFSET;
362 426
363 if (sensor_settings[VFLIP_IDX]) 427 if ((!dmi_check_system(ov9650_flip_dmi_table) &&
428 sensor_settings[VFLIP_IDX]) ||
429 (dmi_check_system(ov9650_flip_dmi_table) &&
430 !sensor_settings[VFLIP_IDX]))
364 ver_offs--; 431 ver_offs--;
365 432
366 if (width <= 320) 433 if (width <= 320)
@@ -406,6 +473,14 @@ int ov9650_start(struct sd *sd)
406 if (err < 0) 473 if (err < 0)
407 return err; 474 return err;
408 475
476 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
477 if (err < 0)
478 return err;
479
480 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
481 if (err < 0)
482 return err;
483
409 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 484 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
410 (hor_offs >> 8) & 0xff); 485 (hor_offs >> 8) & 0xff);
411 if (err < 0) 486 if (err < 0)
@@ -425,6 +500,10 @@ int ov9650_start(struct sd *sd)
425 if (err < 0) 500 if (err < 0)
426 return err; 501 return err;
427 502
503 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
504 if (err < 0)
505 return err;
506
428 switch (width) { 507 switch (width) {
429 case 640: 508 case 640:
430 PDEBUG(D_V4L2, "Configuring camera for VGA mode"); 509 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
@@ -467,32 +546,15 @@ int ov9650_stop(struct sd *sd)
467 return m5602_write_sensor(sd, OV9650_COM2, &data, 1); 546 return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
468} 547}
469 548
470int ov9650_power_down(struct sd *sd)
471{
472 int i, err = 0;
473 for (i = 0; i < ARRAY_SIZE(power_down_ov9650) && !err; i++) {
474 u8 data = power_down_ov9650[i][2];
475 if (power_down_ov9650[i][0] == SENSOR)
476 err = m5602_write_sensor(sd,
477 power_down_ov9650[i][1], &data, 1);
478 else
479 err = m5602_write_bridge(sd, power_down_ov9650[i][1],
480 data);
481 }
482
483 return err;
484}
485
486void ov9650_disconnect(struct sd *sd) 549void ov9650_disconnect(struct sd *sd)
487{ 550{
488 ov9650_stop(sd); 551 ov9650_stop(sd);
489 ov9650_power_down(sd);
490 552
491 sd->sensor = NULL; 553 sd->sensor = NULL;
492 kfree(sd->sensor_priv); 554 kfree(sd->sensor_priv);
493} 555}
494 556
495int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 557static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
496{ 558{
497 struct sd *sd = (struct sd *) gspca_dev; 559 struct sd *sd = (struct sd *) gspca_dev;
498 s32 *sensor_settings = sd->sensor_priv; 560 s32 *sensor_settings = sd->sensor_priv;
@@ -502,7 +564,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
502 return 0; 564 return 0;
503} 565}
504 566
505int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 567static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
506{ 568{
507 struct sd *sd = (struct sd *) gspca_dev; 569 struct sd *sd = (struct sd *) gspca_dev;
508 s32 *sensor_settings = sd->sensor_priv; 570 s32 *sensor_settings = sd->sensor_priv;
@@ -532,7 +594,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
532 return err; 594 return err;
533} 595}
534 596
535int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 597static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
536{ 598{
537 struct sd *sd = (struct sd *) gspca_dev; 599 struct sd *sd = (struct sd *) gspca_dev;
538 s32 *sensor_settings = sd->sensor_priv; 600 s32 *sensor_settings = sd->sensor_priv;
@@ -542,7 +604,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
542 return 0; 604 return 0;
543} 605}
544 606
545int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 607static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
546{ 608{
547 int err; 609 int err;
548 u8 i2c_data; 610 u8 i2c_data;
@@ -573,7 +635,7 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
573 return err; 635 return err;
574} 636}
575 637
576int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 638static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
577{ 639{
578 struct sd *sd = (struct sd *) gspca_dev; 640 struct sd *sd = (struct sd *) gspca_dev;
579 s32 *sensor_settings = sd->sensor_priv; 641 s32 *sensor_settings = sd->sensor_priv;
@@ -583,7 +645,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
583 return 0; 645 return 0;
584} 646}
585 647
586int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 648static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
587{ 649{
588 int err; 650 int err;
589 u8 i2c_data; 651 u8 i2c_data;
@@ -599,7 +661,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
599 return err; 661 return err;
600} 662}
601 663
602int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 664static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
603{ 665{
604 struct sd *sd = (struct sd *) gspca_dev; 666 struct sd *sd = (struct sd *) gspca_dev;
605 s32 *sensor_settings = sd->sensor_priv; 667 s32 *sensor_settings = sd->sensor_priv;
@@ -610,7 +672,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
610 return 0; 672 return 0;
611} 673}
612 674
613int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 675static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
614{ 676{
615 int err; 677 int err;
616 u8 i2c_data; 678 u8 i2c_data;
@@ -626,7 +688,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
626 return err; 688 return err;
627} 689}
628 690
629int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 691static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
630{ 692{
631 struct sd *sd = (struct sd *) gspca_dev; 693 struct sd *sd = (struct sd *) gspca_dev;
632 s32 *sensor_settings = sd->sensor_priv; 694 s32 *sensor_settings = sd->sensor_priv;
@@ -636,7 +698,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
636 return 0; 698 return 0;
637} 699}
638 700
639int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 701static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
640{ 702{
641 int err; 703 int err;
642 u8 i2c_data; 704 u8 i2c_data;
@@ -646,13 +708,20 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
646 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 708 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
647 709
648 sensor_settings[HFLIP_IDX] = val; 710 sensor_settings[HFLIP_IDX] = val;
649 i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4); 711
712 if (!dmi_check_system(ov9650_flip_dmi_table))
713 i2c_data = ((val & 0x01) << 5) |
714 (sensor_settings[VFLIP_IDX] << 4);
715 else
716 i2c_data = ((val & 0x01) << 5) |
717 (!sensor_settings[VFLIP_IDX] << 4);
718
650 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 719 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
651 720
652 return err; 721 return err;
653} 722}
654 723
655int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 724static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
656{ 725{
657 struct sd *sd = (struct sd *) gspca_dev; 726 struct sd *sd = (struct sd *) gspca_dev;
658 s32 *sensor_settings = sd->sensor_priv; 727 s32 *sensor_settings = sd->sensor_priv;
@@ -663,7 +732,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
663 return 0; 732 return 0;
664} 733}
665 734
666int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 735static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
667{ 736{
668 int err; 737 int err;
669 u8 i2c_data; 738 u8 i2c_data;
@@ -673,6 +742,9 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
673 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 742 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
674 sensor_settings[VFLIP_IDX] = val; 743 sensor_settings[VFLIP_IDX] = val;
675 744
745 if (dmi_check_system(ov9650_flip_dmi_table))
746 val = !val;
747
676 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); 748 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
677 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 749 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
678 if (err < 0) 750 if (err < 0)
@@ -685,48 +757,38 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
685 return err; 757 return err;
686} 758}
687 759
688int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 760static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
689{ 761{
690 struct sd *sd = (struct sd *) gspca_dev; 762 struct sd *sd = (struct sd *) gspca_dev;
691 s32 *sensor_settings = sd->sensor_priv; 763 s32 *sensor_settings = sd->sensor_priv;
692 764
693 *val = sensor_settings[GAIN_IDX]; 765 *val = sensor_settings[AUTO_EXPOSURE_IDX];
694 PDEBUG(D_V4L2, "Read gain %d", *val); 766 PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
695
696 return 0; 767 return 0;
697} 768}
698 769
699int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 770static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
771 __s32 val)
700{ 772{
701 int err; 773 int err;
702 u8 i2c_data; 774 u8 i2c_data;
703 struct sd *sd = (struct sd *) gspca_dev; 775 struct sd *sd = (struct sd *) gspca_dev;
704 s32 *sensor_settings = sd->sensor_priv; 776 s32 *sensor_settings = sd->sensor_priv;
705 777
706 PDEBUG(D_V4L2, "Set gain to %d", val); 778 PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
707
708 sensor_settings[GAIN_IDX] = val;
709 779
710 /* Read the OV9650_VREF register first to avoid 780 sensor_settings[AUTO_EXPOSURE_IDX] = val;
711 corrupting the VREF high and low bits */ 781 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
712 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
713 if (err < 0)
714 return err;
715
716 /* Mask away all uninteresting bits */
717 i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
718 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
719 if (err < 0) 782 if (err < 0)
720 return err; 783 return err;
721 784
722 /* The 8 LSBs */ 785 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
723 i2c_data = val & 0xff;
724 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
725 786
726 return err; 787 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
727} 788}
728 789
729int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val) 790static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev,
791 __s32 *val)
730{ 792{
731 struct sd *sd = (struct sd *) gspca_dev; 793 struct sd *sd = (struct sd *) gspca_dev;
732 s32 *sensor_settings = sd->sensor_priv; 794 s32 *sensor_settings = sd->sensor_priv;
@@ -735,7 +797,8 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
735 return 0; 797 return 0;
736} 798}
737 799
738int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val) 800static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
801 __s32 val)
739{ 802{
740 int err; 803 int err;
741 u8 i2c_data; 804 u8 i2c_data;
@@ -755,7 +818,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
755 return err; 818 return err;
756} 819}
757 820
758int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 821static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
759{ 822{
760 struct sd *sd = (struct sd *) gspca_dev; 823 struct sd *sd = (struct sd *) gspca_dev;
761 s32 *sensor_settings = sd->sensor_priv; 824 s32 *sensor_settings = sd->sensor_priv;
@@ -765,7 +828,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
765 return 0; 828 return 0;
766} 829}
767 830
768int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 831static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
769{ 832{
770 int err; 833 int err;
771 u8 i2c_data; 834 u8 i2c_data;
@@ -780,9 +843,8 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
780 return err; 843 return err;
781 844
782 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 845 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
783 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
784 846
785 return err; 847 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
786} 848}
787 849
788static void ov9650_dump_registers(struct sd *sd) 850static void ov9650_dump_registers(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index fcc54e4c0f4f..c98c40d69e05 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -120,6 +120,10 @@
120#define OV9650_SOFT_SLEEP (1 << 4) 120#define OV9650_SOFT_SLEEP (1 << 4)
121#define OV9650_OUTPUT_DRIVE_2X (1 << 0) 121#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
122 122
123#define OV9650_DENOISE_ENABLE (1 << 5)
124#define OV9650_WHITE_PIXEL_ENABLE (1 << 1)
125#define OV9650_WHITE_PIXEL_OPTION (1 << 0)
126
123#define OV9650_LEFT_OFFSET 0x62 127#define OV9650_LEFT_OFFSET 0x62
124 128
125#define GAIN_DEFAULT 0x14 129#define GAIN_DEFAULT 0x14
@@ -137,29 +141,9 @@ int ov9650_probe(struct sd *sd);
137int ov9650_init(struct sd *sd); 141int ov9650_init(struct sd *sd);
138int ov9650_start(struct sd *sd); 142int ov9650_start(struct sd *sd);
139int ov9650_stop(struct sd *sd); 143int ov9650_stop(struct sd *sd);
140int ov9650_power_down(struct sd *sd);
141void ov9650_disconnect(struct sd *sd); 144void ov9650_disconnect(struct sd *sd);
142 145
143int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 146static const struct m5602_sensor ov9650 = {
144int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
145int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
146int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val);
147int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
148int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
149int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
150int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
151int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
152int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
153int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
154int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
155int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
156int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
157int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val);
158int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
159int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
160int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
161
162const static struct m5602_sensor ov9650 = {
163 .name = "OV9650", 147 .name = "OV9650",
164 .i2c_slave_id = 0x60, 148 .i2c_slave_id = 0x60,
165 .i2c_regW = 1, 149 .i2c_regW = 1,
@@ -167,7 +151,6 @@ const static struct m5602_sensor ov9650 = {
167 .init = ov9650_init, 151 .init = ov9650_init,
168 .start = ov9650_start, 152 .start = ov9650_start,
169 .stop = ov9650_stop, 153 .stop = ov9650_stop,
170 .power_down = ov9650_power_down,
171 .disconnect = ov9650_disconnect, 154 .disconnect = ov9650_disconnect,
172}; 155};
173 156
@@ -219,7 +202,7 @@ static const unsigned char init_ov9650[][3] =
219 /* Reset chip */ 202 /* Reset chip */
220 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 203 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
221 /* One extra reset is needed in order to make the sensor behave 204 /* One extra reset is needed in order to make the sensor behave
222 properly when resuming from ram */ 205 properly when resuming from ram, could be a timing issue */
223 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 206 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
224 207
225 /* Enable double clock */ 208 /* Enable double clock */
@@ -229,8 +212,7 @@ static const unsigned char init_ov9650[][3] =
229 212
230 /* Set fast AGC/AEC algorithm with unlimited step size */ 213 /* Set fast AGC/AEC algorithm with unlimited step size */
231 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | 214 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
232 OV9650_AEC_UNLIM_STEP_SIZE | 215 OV9650_AEC_UNLIM_STEP_SIZE},
233 OV9650_AWB_EN | OV9650_AGC_EN},
234 216
235 {SENSOR, OV9650_CHLF, 0x10}, 217 {SENSOR, OV9650_CHLF, 0x10},
236 {SENSOR, OV9650_ARBLM, 0xbf}, 218 {SENSOR, OV9650_ARBLM, 0xbf},
@@ -301,8 +283,11 @@ static const unsigned char init_ov9650[][3] =
301 {SENSOR, OV9650_VREF, 0x10}, 283 {SENSOR, OV9650_VREF, 0x10},
302 {SENSOR, OV9650_ADC, 0x04}, 284 {SENSOR, OV9650_ADC, 0x04},
303 {SENSOR, OV9650_HV, 0x40}, 285 {SENSOR, OV9650_HV, 0x40},
286
304 /* Enable denoise, and white-pixel erase */ 287 /* Enable denoise, and white-pixel erase */
305 {SENSOR, OV9650_COM22, 0x23}, 288 {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
289 OV9650_WHITE_PIXEL_ENABLE |
290 OV9650_WHITE_PIXEL_OPTION},
306 291
307 /* Enable VARIOPIXEL */ 292 /* Enable VARIOPIXEL */
308 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, 293 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
@@ -312,26 +297,6 @@ static const unsigned char init_ov9650[][3] =
312 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, 297 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
313}; 298};
314 299
315static const unsigned char power_down_ov9650[][3] =
316{
317 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
318 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
319 {SENSOR, OV9650_COM7, 0x80},
320 {SENSOR, OV9650_OFON, 0xf4},
321 {SENSOR, OV9650_MVFP, 0x80},
322 {SENSOR, OV9650_DBLV, 0x3f},
323 {SENSOR, OV9650_RSVD36, 0x49},
324 {SENSOR, OV9650_COM7, 0x05},
325
326 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
327 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
328 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
329 {BRIDGE, M5602_XB_GPIO_EN_L, 0x06},
330 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
331 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
332 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
333};
334
335static const unsigned char res_init_ov9650[][3] = 300static const unsigned char res_init_ov9650[][3] =
336{ 301{
337 {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, 302 {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index eaddf488bad1..8d74d8065b79 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,29 @@
18 18
19#include "m5602_po1030.h" 19#include "m5602_po1030.h"
20 20
21static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
22static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
23static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
25static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
26static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
27static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
28static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
29static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
30static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
31static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
32static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
36 __s32 val);
37static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
38 __s32 *val);
39static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
40 __s32 val);
41static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
42 __s32 *val);
43
21static struct v4l2_pix_format po1030_modes[] = { 44static struct v4l2_pix_format po1030_modes[] = {
22 { 45 {
23 640, 46 640,
@@ -27,11 +50,12 @@ static struct v4l2_pix_format po1030_modes[] = {
27 .sizeimage = 640 * 480, 50 .sizeimage = 640 * 480,
28 .bytesperline = 640, 51 .bytesperline = 640,
29 .colorspace = V4L2_COLORSPACE_SRGB, 52 .colorspace = V4L2_COLORSPACE_SRGB,
30 .priv = 0 53 .priv = 2
31 } 54 }
32}; 55};
33 56
34const static struct ctrl po1030_ctrls[] = { 57static const struct ctrl po1030_ctrls[] = {
58#define GAIN_IDX 0
35 { 59 {
36 { 60 {
37 .id = V4L2_CID_GAIN, 61 .id = V4L2_CID_GAIN,
@@ -45,7 +69,9 @@ const static struct ctrl po1030_ctrls[] = {
45 }, 69 },
46 .set = po1030_set_gain, 70 .set = po1030_set_gain,
47 .get = po1030_get_gain 71 .get = po1030_get_gain
48 }, { 72 },
73#define EXPOSURE_IDX 1
74 {
49 { 75 {
50 .id = V4L2_CID_EXPOSURE, 76 .id = V4L2_CID_EXPOSURE,
51 .type = V4L2_CTRL_TYPE_INTEGER, 77 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -58,7 +84,9 @@ const static struct ctrl po1030_ctrls[] = {
58 }, 84 },
59 .set = po1030_set_exposure, 85 .set = po1030_set_exposure,
60 .get = po1030_get_exposure 86 .get = po1030_get_exposure
61 }, { 87 },
88#define RED_BALANCE_IDX 2
89 {
62 { 90 {
63 .id = V4L2_CID_RED_BALANCE, 91 .id = V4L2_CID_RED_BALANCE,
64 .type = V4L2_CTRL_TYPE_INTEGER, 92 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -71,7 +99,9 @@ const static struct ctrl po1030_ctrls[] = {
71 }, 99 },
72 .set = po1030_set_red_balance, 100 .set = po1030_set_red_balance,
73 .get = po1030_get_red_balance 101 .get = po1030_get_red_balance
74 }, { 102 },
103#define BLUE_BALANCE_IDX 3
104 {
75 { 105 {
76 .id = V4L2_CID_BLUE_BALANCE, 106 .id = V4L2_CID_BLUE_BALANCE,
77 .type = V4L2_CTRL_TYPE_INTEGER, 107 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -84,7 +114,9 @@ const static struct ctrl po1030_ctrls[] = {
84 }, 114 },
85 .set = po1030_set_blue_balance, 115 .set = po1030_set_blue_balance,
86 .get = po1030_get_blue_balance 116 .get = po1030_get_blue_balance
87 }, { 117 },
118#define HFLIP_IDX 4
119 {
88 { 120 {
89 .id = V4L2_CID_HFLIP, 121 .id = V4L2_CID_HFLIP,
90 .type = V4L2_CTRL_TYPE_BOOLEAN, 122 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -96,7 +128,9 @@ const static struct ctrl po1030_ctrls[] = {
96 }, 128 },
97 .set = po1030_set_hflip, 129 .set = po1030_set_hflip,
98 .get = po1030_get_hflip 130 .get = po1030_get_hflip
99 }, { 131 },
132#define VFLIP_IDX 5
133 {
100 { 134 {
101 .id = V4L2_CID_VFLIP, 135 .id = V4L2_CID_VFLIP,
102 .type = V4L2_CTRL_TYPE_BOOLEAN, 136 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -108,14 +142,58 @@ const static struct ctrl po1030_ctrls[] = {
108 }, 142 },
109 .set = po1030_set_vflip, 143 .set = po1030_set_vflip,
110 .get = po1030_get_vflip 144 .get = po1030_get_vflip
111 } 145 },
146#define AUTO_WHITE_BALANCE_IDX 6
147 {
148 {
149 .id = V4L2_CID_AUTO_WHITE_BALANCE,
150 .type = V4L2_CTRL_TYPE_BOOLEAN,
151 .name = "auto white balance",
152 .minimum = 0,
153 .maximum = 1,
154 .step = 1,
155 .default_value = 0,
156 },
157 .set = po1030_set_auto_white_balance,
158 .get = po1030_get_auto_white_balance
159 },
160#define AUTO_EXPOSURE_IDX 7
161 {
162 {
163 .id = V4L2_CID_EXPOSURE_AUTO,
164 .type = V4L2_CTRL_TYPE_BOOLEAN,
165 .name = "auto exposure",
166 .minimum = 0,
167 .maximum = 1,
168 .step = 1,
169 .default_value = 0,
170 },
171 .set = po1030_set_auto_exposure,
172 .get = po1030_get_auto_exposure
173 },
174#define GREEN_BALANCE_IDX 8
175 {
176 {
177 .id = M5602_V4L2_CID_GREEN_BALANCE,
178 .type = V4L2_CTRL_TYPE_INTEGER,
179 .name = "green balance",
180 .minimum = 0x00,
181 .maximum = 0xff,
182 .step = 0x1,
183 .default_value = PO1030_GREEN_GAIN_DEFAULT,
184 .flags = V4L2_CTRL_FLAG_SLIDER
185 },
186 .set = po1030_set_green_balance,
187 .get = po1030_get_green_balance
188 },
112}; 189};
113 190
114static void po1030_dump_registers(struct sd *sd); 191static void po1030_dump_registers(struct sd *sd);
115 192
116int po1030_probe(struct sd *sd) 193int po1030_probe(struct sd *sd)
117{ 194{
118 u8 prod_id = 0, ver_id = 0, i; 195 u8 dev_id_h = 0, i;
196 s32 *sensor_settings;
119 197
120 if (force_sensor) { 198 if (force_sensor) {
121 if (force_sensor == PO1030_SENSOR) { 199 if (force_sensor == PO1030_SENSOR) {
@@ -139,28 +217,36 @@ int po1030_probe(struct sd *sd)
139 m5602_write_bridge(sd, preinit_po1030[i][1], data); 217 m5602_write_bridge(sd, preinit_po1030[i][1], data);
140 } 218 }
141 219
142 if (m5602_read_sensor(sd, 0x3, &prod_id, 1)) 220 if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
143 return -ENODEV; 221 return -ENODEV;
144 222
145 if (m5602_read_sensor(sd, 0x4, &ver_id, 1)) 223 if (dev_id_h == 0x30) {
146 return -ENODEV;
147
148 if ((prod_id == 0x02) && (ver_id == 0xef)) {
149 info("Detected a po1030 sensor"); 224 info("Detected a po1030 sensor");
150 goto sensor_found; 225 goto sensor_found;
151 } 226 }
152 return -ENODEV; 227 return -ENODEV;
153 228
154sensor_found: 229sensor_found:
230 sensor_settings = kmalloc(
231 ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL);
232 if (!sensor_settings)
233 return -ENOMEM;
234
155 sd->gspca_dev.cam.cam_mode = po1030_modes; 235 sd->gspca_dev.cam.cam_mode = po1030_modes;
156 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); 236 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
157 sd->desc->ctrls = po1030_ctrls; 237 sd->desc->ctrls = po1030_ctrls;
158 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); 238 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
239
240 for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++)
241 sensor_settings[i] = po1030_ctrls[i].qctrl.default_value;
242 sd->sensor_priv = sensor_settings;
243
159 return 0; 244 return 0;
160} 245}
161 246
162int po1030_init(struct sd *sd) 247int po1030_init(struct sd *sd)
163{ 248{
249 s32 *sensor_settings = sd->sensor_priv;
164 int i, err = 0; 250 int i, err = 0;
165 251
166 /* Init the sensor */ 252 /* Init the sensor */
@@ -185,47 +271,206 @@ int po1030_init(struct sd *sd)
185 return -EINVAL; 271 return -EINVAL;
186 } 272 }
187 } 273 }
274 if (err < 0)
275 return err;
188 276
189 if (dump_sensor) 277 if (dump_sensor)
190 po1030_dump_registers(sd); 278 po1030_dump_registers(sd);
191 279
280 err = po1030_set_exposure(&sd->gspca_dev,
281 sensor_settings[EXPOSURE_IDX]);
282 if (err < 0)
283 return err;
284
285 err = po1030_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
286 if (err < 0)
287 return err;
288
289 err = po1030_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
290 if (err < 0)
291 return err;
292
293 err = po1030_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
294 if (err < 0)
295 return err;
296
297 err = po1030_set_red_balance(&sd->gspca_dev,
298 sensor_settings[RED_BALANCE_IDX]);
299 if (err < 0)
300 return err;
301
302 err = po1030_set_blue_balance(&sd->gspca_dev,
303 sensor_settings[BLUE_BALANCE_IDX]);
304 if (err < 0)
305 return err;
306
307 err = po1030_set_green_balance(&sd->gspca_dev,
308 sensor_settings[GREEN_BALANCE_IDX]);
309 if (err < 0)
310 return err;
311
312 err = po1030_set_auto_white_balance(&sd->gspca_dev,
313 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
314 if (err < 0)
315 return err;
316
317 err = po1030_set_auto_exposure(&sd->gspca_dev,
318 sensor_settings[AUTO_EXPOSURE_IDX]);
192 return err; 319 return err;
193} 320}
194 321
195int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 322int po1030_start(struct sd *sd)
196{ 323{
197 struct sd *sd = (struct sd *) gspca_dev; 324 struct cam *cam = &sd->gspca_dev.cam;
198 u8 i2c_data; 325 int i, err = 0;
199 int err; 326 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
327 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
328 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
329 u8 data;
330
331 switch (width) {
332 case 320:
333 data = PO1030_SUBSAMPLING;
334 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
335 if (err < 0)
336 return err;
337
338 data = ((width + 3) >> 8) & 0xff;
339 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
340 if (err < 0)
341 return err;
342
343 data = (width + 3) & 0xff;
344 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
345 if (err < 0)
346 return err;
347
348 data = ((height + 1) >> 8) & 0xff;
349 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
350 if (err < 0)
351 return err;
352
353 data = (height + 1) & 0xff;
354 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
355
356 height += 6;
357 width -= 1;
358 break;
359
360 case 640:
361 data = 0;
362 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
363 if (err < 0)
364 return err;
365
366 data = ((width + 7) >> 8) & 0xff;
367 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
368 if (err < 0)
369 return err;
370
371 data = (width + 7) & 0xff;
372 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
373 if (err < 0)
374 return err;
375
376 data = ((height + 3) >> 8) & 0xff;
377 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
378 if (err < 0)
379 return err;
380
381 data = (height + 3) & 0xff;
382 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
383
384 height += 12;
385 width -= 2;
386 break;
387 }
388 err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
389 if (err < 0)
390 return err;
200 391
201 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H, 392 err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
202 &i2c_data, 1);
203 if (err < 0) 393 if (err < 0)
204 return err; 394 return err;
205 *val = (i2c_data << 8);
206 395
207 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M, 396 err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
208 &i2c_data, 1); 397 if (err < 0)
209 *val |= i2c_data; 398 return err;
210 399
211 PDEBUG(D_V4L2, "Exposure read as %d", *val); 400 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
401 if (err < 0)
402 return err;
403
404 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
405 ((ver_offs >> 8) & 0xff));
406 if (err < 0)
407 return err;
408
409 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
410 if (err < 0)
411 return err;
412
413 for (i = 0; i < 2 && !err; i++)
414 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
415 if (err < 0)
416 return err;
417
418 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
419 if (err < 0)
420 return err;
421
422 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
423 if (err < 0)
424 return err;
425
426 for (i = 0; i < 2 && !err; i++)
427 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
428
429 for (i = 0; i < 2 && !err; i++)
430 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
431
432 for (i = 0; i < 2 && !err; i++)
433 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
434 if (err < 0)
435 return err;
436
437 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
438 if (err < 0)
439 return err;
212 440
441 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
442 if (err < 0)
443 return err;
444
445 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
213 return err; 446 return err;
214} 447}
215 448
216int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 449static int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
217{ 450{
218 struct sd *sd = (struct sd *) gspca_dev; 451 struct sd *sd = (struct sd *) gspca_dev;
452 s32 *sensor_settings = sd->sensor_priv;
453
454 *val = sensor_settings[EXPOSURE_IDX];
455 PDEBUG(D_V4L2, "Exposure read as %d", *val);
456 return 0;
457}
458
459static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
460{
461 struct sd *sd = (struct sd *) gspca_dev;
462 s32 *sensor_settings = sd->sensor_priv;
219 u8 i2c_data; 463 u8 i2c_data;
220 int err; 464 int err;
221 465
466 sensor_settings[EXPOSURE_IDX] = val;
222 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); 467 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
223 468
224 i2c_data = ((val & 0xff00) >> 8); 469 i2c_data = ((val & 0xff00) >> 8);
225 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x", 470 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
226 i2c_data); 471 i2c_data);
227 472
228 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H, 473 err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
229 &i2c_data, 1); 474 &i2c_data, 1);
230 if (err < 0) 475 if (err < 0)
231 return err; 476 return err;
@@ -233,167 +478,256 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
233 i2c_data = (val & 0xff); 478 i2c_data = (val & 0xff);
234 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x", 479 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
235 i2c_data); 480 i2c_data);
236 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M, 481 err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
237 &i2c_data, 1); 482 &i2c_data, 1);
238 483
239 return err; 484 return err;
240} 485}
241 486
242int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 487static int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
243{ 488{
244 struct sd *sd = (struct sd *) gspca_dev; 489 struct sd *sd = (struct sd *) gspca_dev;
245 u8 i2c_data; 490 s32 *sensor_settings = sd->sensor_priv;
246 int err;
247 491
248 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, 492 *val = sensor_settings[GAIN_IDX];
249 &i2c_data, 1);
250 *val = i2c_data;
251 PDEBUG(D_V4L2, "Read global gain %d", *val); 493 PDEBUG(D_V4L2, "Read global gain %d", *val);
252 494 return 0;
253 return err;
254} 495}
255 496
256int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 497static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
257{ 498{
258 struct sd *sd = (struct sd *) gspca_dev; 499 struct sd *sd = (struct sd *) gspca_dev;
500 s32 *sensor_settings = sd->sensor_priv;
259 u8 i2c_data; 501 u8 i2c_data;
260 int err; 502 int err;
261 503
262 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, 504 sensor_settings[GAIN_IDX] = val;
505
506 i2c_data = val & 0xff;
507 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
508 err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
263 &i2c_data, 1); 509 &i2c_data, 1);
510 return err;
511}
264 512
265 *val = (i2c_data >> 7) & 0x01 ; 513static int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
514{
515 struct sd *sd = (struct sd *) gspca_dev;
516 s32 *sensor_settings = sd->sensor_priv;
266 517
518 *val = sensor_settings[HFLIP_IDX];
267 PDEBUG(D_V4L2, "Read hflip %d", *val); 519 PDEBUG(D_V4L2, "Read hflip %d", *val);
268 520
269 return err; 521 return 0;
270} 522}
271 523
272int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 524static int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
273{ 525{
274 struct sd *sd = (struct sd *) gspca_dev; 526 struct sd *sd = (struct sd *) gspca_dev;
527 s32 *sensor_settings = sd->sensor_priv;
275 u8 i2c_data; 528 u8 i2c_data;
276 int err; 529 int err;
277 530
531 sensor_settings[HFLIP_IDX] = val;
532
278 PDEBUG(D_V4L2, "Set hflip %d", val); 533 PDEBUG(D_V4L2, "Set hflip %d", val);
279 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); 534 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
280 if (err < 0) 535 if (err < 0)
281 return err; 536 return err;
282 537
283 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7); 538 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
284 539
285 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, 540 err = m5602_write_sensor(sd, PO1030_CONTROL2,
286 &i2c_data, 1); 541 &i2c_data, 1);
287 542
288 return err; 543 return err;
289} 544}
290 545
291int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 546static int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
292{ 547{
293 struct sd *sd = (struct sd *) gspca_dev; 548 struct sd *sd = (struct sd *) gspca_dev;
294 u8 i2c_data; 549 s32 *sensor_settings = sd->sensor_priv;
295 int err;
296
297 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
298 &i2c_data, 1);
299
300 *val = (i2c_data >> 6) & 0x01;
301 550
551 *val = sensor_settings[VFLIP_IDX];
302 PDEBUG(D_V4L2, "Read vflip %d", *val); 552 PDEBUG(D_V4L2, "Read vflip %d", *val);
303 553
304 return err; 554 return 0;
305} 555}
306 556
307int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 557static int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
308{ 558{
309 struct sd *sd = (struct sd *) gspca_dev; 559 struct sd *sd = (struct sd *) gspca_dev;
560 s32 *sensor_settings = sd->sensor_priv;
310 u8 i2c_data; 561 u8 i2c_data;
311 int err; 562 int err;
312 563
564 sensor_settings[VFLIP_IDX] = val;
565
313 PDEBUG(D_V4L2, "Set vflip %d", val); 566 PDEBUG(D_V4L2, "Set vflip %d", val);
314 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); 567 err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
315 if (err < 0) 568 if (err < 0)
316 return err; 569 return err;
317 570
318 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6); 571 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
319 572
320 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2, 573 err = m5602_write_sensor(sd, PO1030_CONTROL2,
321 &i2c_data, 1); 574 &i2c_data, 1);
322 575
323 return err; 576 return err;
324} 577}
325 578
326int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) 579static int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
580{
581 struct sd *sd = (struct sd *) gspca_dev;
582 s32 *sensor_settings = sd->sensor_priv;
583
584 *val = sensor_settings[RED_BALANCE_IDX];
585 PDEBUG(D_V4L2, "Read red gain %d", *val);
586 return 0;
587}
588
589static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
327{ 590{
328 struct sd *sd = (struct sd *) gspca_dev; 591 struct sd *sd = (struct sd *) gspca_dev;
592 s32 *sensor_settings = sd->sensor_priv;
329 u8 i2c_data; 593 u8 i2c_data;
330 int err; 594 int err;
331 595
596 sensor_settings[RED_BALANCE_IDX] = val;
597
332 i2c_data = val & 0xff; 598 i2c_data = val & 0xff;
333 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); 599 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
334 err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, 600 err = m5602_write_sensor(sd, PO1030_RED_GAIN,
335 &i2c_data, 1); 601 &i2c_data, 1);
336 return err; 602 return err;
337} 603}
338 604
339int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 605static int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
340{ 606{
341 struct sd *sd = (struct sd *) gspca_dev; 607 struct sd *sd = (struct sd *) gspca_dev;
342 u8 i2c_data; 608 s32 *sensor_settings = sd->sensor_priv;
343 int err;
344 609
345 err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN, 610 *val = sensor_settings[BLUE_BALANCE_IDX];
346 &i2c_data, 1); 611 PDEBUG(D_V4L2, "Read blue gain %d", *val);
347 *val = i2c_data; 612
348 PDEBUG(D_V4L2, "Read red gain %d", *val); 613 return 0;
349 return err;
350} 614}
351 615
352int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 616static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
353{ 617{
354 struct sd *sd = (struct sd *) gspca_dev; 618 struct sd *sd = (struct sd *) gspca_dev;
619 s32 *sensor_settings = sd->sensor_priv;
355 u8 i2c_data; 620 u8 i2c_data;
356 int err; 621 int err;
357 622
623 sensor_settings[BLUE_BALANCE_IDX] = val;
624
358 i2c_data = val & 0xff; 625 i2c_data = val & 0xff;
359 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); 626 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
360 err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, 627 err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
361 &i2c_data, 1); 628 &i2c_data, 1);
629
362 return err; 630 return err;
363} 631}
364 632
365int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 633static int po1030_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
366{ 634{
367 struct sd *sd = (struct sd *) gspca_dev; 635 struct sd *sd = (struct sd *) gspca_dev;
636 s32 *sensor_settings = sd->sensor_priv;
637
638 *val = sensor_settings[GREEN_BALANCE_IDX];
639 PDEBUG(D_V4L2, "Read green gain %d", *val);
640
641 return 0;
642}
643
644static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
645{
646 struct sd *sd = (struct sd *) gspca_dev;
647 s32 *sensor_settings = sd->sensor_priv;
368 u8 i2c_data; 648 u8 i2c_data;
369 int err; 649 int err;
370 650
371 err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN, 651 sensor_settings[GREEN_BALANCE_IDX] = val;
652 i2c_data = val & 0xff;
653 PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
654
655 err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
656 &i2c_data, 1);
657 if (err < 0)
658 return err;
659
660 return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
372 &i2c_data, 1); 661 &i2c_data, 1);
373 *val = i2c_data; 662}
374 PDEBUG(D_V4L2, "Read blue gain %d", *val);
375 663
376 return err; 664static int po1030_get_auto_white_balance(struct gspca_dev *gspca_dev,
665 __s32 *val)
666{
667 struct sd *sd = (struct sd *) gspca_dev;
668 s32 *sensor_settings = sd->sensor_priv;
669
670 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
671 PDEBUG(D_V4L2, "Auto white balancing is %d", *val);
672
673 return 0;
377} 674}
378 675
379int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 676static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
677 __s32 val)
380{ 678{
381 struct sd *sd = (struct sd *) gspca_dev; 679 struct sd *sd = (struct sd *) gspca_dev;
680 s32 *sensor_settings = sd->sensor_priv;
382 u8 i2c_data; 681 u8 i2c_data;
383 int err; 682 int err;
384 i2c_data = val & 0xff;
385 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
386 err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
387 &i2c_data, 1);
388 683
684 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
685
686 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
687 if (err < 0)
688 return err;
689
690 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
691 i2c_data = (i2c_data & 0xfe) | (val & 0x01);
692 err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
389 return err; 693 return err;
390} 694}
391 695
392int po1030_power_down(struct sd *sd) 696static int po1030_get_auto_exposure(struct gspca_dev *gspca_dev,
697 __s32 *val)
393{ 698{
699 struct sd *sd = (struct sd *) gspca_dev;
700 s32 *sensor_settings = sd->sensor_priv;
701
702 *val = sensor_settings[AUTO_EXPOSURE_IDX];
703 PDEBUG(D_V4L2, "Auto exposure is %d", *val);
394 return 0; 704 return 0;
395} 705}
396 706
707static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
708 __s32 val)
709{
710 struct sd *sd = (struct sd *) gspca_dev;
711 s32 *sensor_settings = sd->sensor_priv;
712 u8 i2c_data;
713 int err;
714
715 sensor_settings[AUTO_EXPOSURE_IDX] = val;
716 err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
717 if (err < 0)
718 return err;
719
720 PDEBUG(D_V4L2, "Set auto exposure to %d", val);
721 i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
722 return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
723}
724
725void po1030_disconnect(struct sd *sd)
726{
727 sd->sensor = NULL;
728 kfree(sd->sensor_priv);
729}
730
397static void po1030_dump_registers(struct sd *sd) 731static void po1030_dump_registers(struct sd *sd)
398{ 732{
399 int address; 733 int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index c10b12335818..1ea380b2bbe7 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -25,98 +25,123 @@
25 25
26/*****************************************************************************/ 26/*****************************************************************************/
27 27
28#define PO1030_REG_DEVID_H 0x00 28#define PO1030_DEVID_H 0x00
29#define PO1030_REG_DEVID_L 0x01 29#define PO1030_DEVID_L 0x01
30#define PO1030_REG_FRAMEWIDTH_H 0x04 30#define PO1030_FRAMEWIDTH_H 0x04
31#define PO1030_REG_FRAMEWIDTH_L 0x05 31#define PO1030_FRAMEWIDTH_L 0x05
32#define PO1030_REG_FRAMEHEIGHT_H 0x06 32#define PO1030_FRAMEHEIGHT_H 0x06
33#define PO1030_REG_FRAMEHEIGHT_L 0x07 33#define PO1030_FRAMEHEIGHT_L 0x07
34#define PO1030_REG_WINDOWX_H 0x08 34#define PO1030_WINDOWX_H 0x08
35#define PO1030_REG_WINDOWX_L 0x09 35#define PO1030_WINDOWX_L 0x09
36#define PO1030_REG_WINDOWY_H 0x0a 36#define PO1030_WINDOWY_H 0x0a
37#define PO1030_REG_WINDOWY_L 0x0b 37#define PO1030_WINDOWY_L 0x0b
38#define PO1030_REG_WINDOWWIDTH_H 0x0c 38#define PO1030_WINDOWWIDTH_H 0x0c
39#define PO1030_REG_WINDOWWIDTH_L 0x0d 39#define PO1030_WINDOWWIDTH_L 0x0d
40#define PO1030_REG_WINDOWHEIGHT_H 0x0e 40#define PO1030_WINDOWHEIGHT_H 0x0e
41#define PO1030_REG_WINDOWHEIGHT_L 0x0f 41#define PO1030_WINDOWHEIGHT_L 0x0f
42 42
43#define PO1030_REG_GLOBALIBIAS 0x12 43#define PO1030_GLOBALIBIAS 0x12
44#define PO1030_REG_PIXELIBIAS 0x13 44#define PO1030_PIXELIBIAS 0x13
45 45
46#define PO1030_REG_GLOBALGAIN 0x15 46#define PO1030_GLOBALGAIN 0x15
47#define PO1030_REG_RED_GAIN 0x16 47#define PO1030_RED_GAIN 0x16
48#define PO1030_REG_GREEN_1_GAIN 0x17 48#define PO1030_GREEN_1_GAIN 0x17
49#define PO1030_REG_BLUE_GAIN 0x18 49#define PO1030_BLUE_GAIN 0x18
50#define PO1030_REG_GREEN_2_GAIN 0x19 50#define PO1030_GREEN_2_GAIN 0x19
51 51
52#define PO1030_REG_INTEGLINES_H 0x1a 52#define PO1030_INTEGLINES_H 0x1a
53#define PO1030_REG_INTEGLINES_M 0x1b 53#define PO1030_INTEGLINES_M 0x1b
54#define PO1030_REG_INTEGLINES_L 0x1c 54#define PO1030_INTEGLINES_L 0x1c
55 55
56#define PO1030_REG_CONTROL1 0x1d 56#define PO1030_CONTROL1 0x1d
57#define PO1030_REG_CONTROL2 0x1e 57#define PO1030_CONTROL2 0x1e
58#define PO1030_REG_CONTROL3 0x1f 58#define PO1030_CONTROL3 0x1f
59#define PO1030_REG_CONTROL4 0x20 59#define PO1030_CONTROL4 0x20
60 60
61#define PO1030_REG_PERIOD50_H 0x23 61#define PO1030_PERIOD50_H 0x23
62#define PO1030_REG_PERIOD50_L 0x24 62#define PO1030_PERIOD50_L 0x24
63#define PO1030_REG_PERIOD60_H 0x25 63#define PO1030_PERIOD60_H 0x25
64#define PO1030_REG_PERIOD60_L 0x26 64#define PO1030_PERIOD60_L 0x26
65#define PO1030_REG_REGCLK167 0x27 65#define PO1030_REGCLK167 0x27
66#define PO1030_REG_DELTA50 0x28 66#define PO1030_FLICKER_DELTA50 0x28
67#define PO1030_REG_DELTA60 0x29 67#define PO1030_FLICKERDELTA60 0x29
68 68
69#define PO1030_REG_ADCOFFSET 0x2c 69#define PO1030_ADCOFFSET 0x2c
70 70
71/* Gamma Correction Coeffs */ 71/* Gamma Correction Coeffs */
72#define PO1030_REG_GC0 0x2d 72#define PO1030_GC0 0x2d
73#define PO1030_REG_GC1 0x2e 73#define PO1030_GC1 0x2e
74#define PO1030_REG_GC2 0x2f 74#define PO1030_GC2 0x2f
75#define PO1030_REG_GC3 0x30 75#define PO1030_GC3 0x30
76#define PO1030_REG_GC4 0x31 76#define PO1030_GC4 0x31
77#define PO1030_REG_GC5 0x32 77#define PO1030_GC5 0x32
78#define PO1030_REG_GC6 0x33 78#define PO1030_GC6 0x33
79#define PO1030_REG_GC7 0x34 79#define PO1030_GC7 0x34
80 80
81/* Color Transform Matrix */ 81/* Color Transform Matrix */
82#define PO1030_REG_CT0 0x35 82#define PO1030_CT0 0x35
83#define PO1030_REG_CT1 0x36 83#define PO1030_CT1 0x36
84#define PO1030_REG_CT2 0x37 84#define PO1030_CT2 0x37
85#define PO1030_REG_CT3 0x38 85#define PO1030_CT3 0x38
86#define PO1030_REG_CT4 0x39 86#define PO1030_CT4 0x39
87#define PO1030_REG_CT5 0x3a 87#define PO1030_CT5 0x3a
88#define PO1030_REG_CT6 0x3b 88#define PO1030_CT6 0x3b
89#define PO1030_REG_CT7 0x3c 89#define PO1030_CT7 0x3c
90#define PO1030_REG_CT8 0x3d 90#define PO1030_CT8 0x3d
91 91
92#define PO1030_REG_AUTOCTRL1 0x3e 92#define PO1030_AUTOCTRL1 0x3e
93#define PO1030_REG_AUTOCTRL2 0x3f 93#define PO1030_AUTOCTRL2 0x3f
94 94
95#define PO1030_REG_YTARGET 0x40 95#define PO1030_YTARGET 0x40
96#define PO1030_REG_GLOBALGAINMIN 0x41 96#define PO1030_GLOBALGAINMIN 0x41
97#define PO1030_REG_GLOBALGAINMAX 0x42 97#define PO1030_GLOBALGAINMAX 0x42
98
99#define PO1030_AWB_RED_TUNING 0x47
100#define PO1030_AWB_BLUE_TUNING 0x48
98 101
99/* Output format control */ 102/* Output format control */
100#define PO1030_REG_OUTFORMCTRL1 0x5a 103#define PO1030_OUTFORMCTRL1 0x5a
101#define PO1030_REG_OUTFORMCTRL2 0x5b 104#define PO1030_OUTFORMCTRL2 0x5b
102#define PO1030_REG_OUTFORMCTRL3 0x5c 105#define PO1030_OUTFORMCTRL3 0x5c
103#define PO1030_REG_OUTFORMCTRL4 0x5d 106#define PO1030_OUTFORMCTRL4 0x5d
104#define PO1030_REG_OUTFORMCTRL5 0x5e 107#define PO1030_OUTFORMCTRL5 0x5e
105 108
106/* Imaging coefficients */ 109#define PO1030_EDGE_ENH_OFF 0x5f
107#define PO1030_REG_YBRIGHT 0x73 110#define PO1030_EGA 0x60
108#define PO1030_REG_YCONTRAST 0x74
109#define PO1030_REG_YSATURATION 0x75
110 111
111#define PO1030_HFLIP (1 << 7) 112#define PO1030_Cb_U_GAIN 0x63
112#define PO1030_VFLIP (1 << 6) 113#define PO1030_Cr_V_GAIN 0x64
114
115#define PO1030_YCONTRAST 0x74
116#define PO1030_YSATURATION 0x75
117
118#define PO1030_HFLIP (1 << 7)
119#define PO1030_VFLIP (1 << 6)
120
121#define PO1030_HREF_ENABLE (1 << 6)
122
123#define PO1030_RAW_RGB_BAYER 0x4
124
125#define PO1030_FRAME_EQUAL (1 << 3)
126#define PO1030_AUTO_SUBSAMPLING (1 << 4)
127
128#define PO1030_WEIGHT_WIN_2X (1 << 3)
129
130#define PO1030_SHUTTER_MODE (1 << 6)
131#define PO1030_AUTO_SUBSAMPLING (1 << 4)
132#define PO1030_FRAME_EQUAL (1 << 3)
133
134#define PO1030_SENSOR_RESET (1 << 5)
135
136#define PO1030_SUBSAMPLING (1 << 6)
113 137
114/*****************************************************************************/ 138/*****************************************************************************/
115 139
116#define PO1030_GLOBAL_GAIN_DEFAULT 0x12 140#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
117#define PO1030_EXPOSURE_DEFAULT 0x0085 141#define PO1030_EXPOSURE_DEFAULT 0x0085
118#define PO1030_BLUE_GAIN_DEFAULT 0x40 142#define PO1030_BLUE_GAIN_DEFAULT 0x36
119#define PO1030_RED_GAIN_DEFAULT 0x40 143#define PO1030_RED_GAIN_DEFAULT 0x36
144#define PO1030_GREEN_GAIN_DEFAULT 0x40
120 145
121/*****************************************************************************/ 146/*****************************************************************************/
122 147
@@ -126,20 +151,8 @@ extern int dump_sensor;
126 151
127int po1030_probe(struct sd *sd); 152int po1030_probe(struct sd *sd);
128int po1030_init(struct sd *sd); 153int po1030_init(struct sd *sd);
129int po1030_power_down(struct sd *sd); 154int po1030_start(struct sd *sd);
130 155void po1030_disconnect(struct sd *sd);
131int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
132int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
133int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
134int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val);
135int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
136int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
137int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
138int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
139int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
140int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
141int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
142int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
143 156
144static const struct m5602_sensor po1030 = { 157static const struct m5602_sensor po1030 = {
145 .name = "PO1030", 158 .name = "PO1030",
@@ -149,7 +162,8 @@ static const struct m5602_sensor po1030 = {
149 162
150 .probe = po1030_probe, 163 .probe = po1030_probe,
151 .init = po1030_init, 164 .init = po1030_init,
152 .power_down = po1030_power_down, 165 .start = po1030_start,
166 .disconnect = po1030_disconnect,
153}; 167};
154 168
155static const unsigned char preinit_po1030[][3] = 169static const unsigned char preinit_po1030[][3] =
@@ -159,248 +173,103 @@ static const unsigned char preinit_po1030[][3] =
159 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 173 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
160 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 174 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
161 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 175 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
162 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
163 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 176 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
164 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
165 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 177 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
166
167 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
168
169 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
170 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
171 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
172 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
173 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
174 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
175 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
176 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
177 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
178 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 178 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
179 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
180 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
181 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
182 {BRIDGE, M5602_XB_SIG_INI, 0x01},
183 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
184 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
185 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
186 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
187 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
188 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
189 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
190 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
191 {BRIDGE, M5602_XB_SIG_INI, 0x00},
192 {BRIDGE, M5602_XB_SIG_INI, 0x02},
193 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
194 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
195 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
196 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
197 {BRIDGE, M5602_XB_SIG_INI, 0x00},
198
199 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
200
201 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 179 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
202 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 180 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
203 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 181 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
204 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 182 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
205 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 183 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
184
185 {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
186
206 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 187 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
207 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 188 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
208 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 189 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
209 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 190 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
210 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
211 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 191 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
212 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 192 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
213 {BRIDGE, M5602_XB_GPIO_DAT, 0x00} 193 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}
214}; 194};
215 195
216static const unsigned char init_po1030[][4] = 196static const unsigned char init_po1030[][3] =
217{ 197{
218 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, 198 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
219 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, 199 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
220 /*sequence 1*/
221 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 200 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
222 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 201 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
223 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 202 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
224 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
225
226 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 203 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
227 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
228 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 204 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
229 /*end of sequence 1*/
230
231 /*sequence 2 (same as stop sequence)*/
232 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
233 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
234 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
235 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
236 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
237 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
238
239 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
240 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
241 /*end of sequence 2*/
242 205
243 /*sequence 5*/ 206 {SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
244 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
245 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
246 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
247 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
248 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
249 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
250 {BRIDGE, M5602_XB_SIG_INI, 0x01},
251 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
252 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
257 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
258 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
259 {BRIDGE, M5602_XB_SIG_INI, 0x00},
260 {BRIDGE, M5602_XB_SIG_INI, 0x02},
261 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
262 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
263 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
264 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87},
265 {BRIDGE, M5602_XB_SIG_INI, 0x00},
266 /*end of sequence 5*/
267
268 /*sequence 2 stop */
269 {SENSOR, PO1030_REG_AUTOCTRL2, 0x24},
270 207
271 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 208 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
272 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 209 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
273 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 210 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
211 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
274 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 212 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
275 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02}, 213 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
276 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04}, 214 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
277 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 215 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
278 /*end of sequence 2 stop */
279
280/* ---------------------------------
281 * end of init - begin of start
282 * --------------------------------- */
283
284 /*sequence 3*/
285 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
286 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
287 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
288 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
289 /*end of sequence 3*/
290 /*sequence 4*/
291 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 216 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
292 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 217 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
293 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
294 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
295 218
296 {SENSOR, PO1030_REG_AUTOCTRL2, 0x04}, 219 {SENSOR, PO1030_AUTOCTRL2, 0x04},
220
221 {SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
222 {SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
223
224 {SENSOR, PO1030_CONTROL2, 0x03},
225 {SENSOR, 0x21, 0x90},
226 {SENSOR, PO1030_YTARGET, 0x60},
227 {SENSOR, 0x59, 0x13},
228 {SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
229 {SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
230 {SENSOR, PO1030_EGA, 0x80},
231 {SENSOR, 0x78, 0x14},
232 {SENSOR, 0x6f, 0x01},
233 {SENSOR, PO1030_GLOBALGAINMAX, 0x14},
234 {SENSOR, PO1030_Cb_U_GAIN, 0x38},
235 {SENSOR, PO1030_Cr_V_GAIN, 0x38},
236 {SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
237 PO1030_AUTO_SUBSAMPLING |
238 PO1030_FRAME_EQUAL},
239 {SENSOR, PO1030_GC0, 0x10},
240 {SENSOR, PO1030_GC1, 0x20},
241 {SENSOR, PO1030_GC2, 0x40},
242 {SENSOR, PO1030_GC3, 0x60},
243 {SENSOR, PO1030_GC4, 0x80},
244 {SENSOR, PO1030_GC5, 0xa0},
245 {SENSOR, PO1030_GC6, 0xc0},
246 {SENSOR, PO1030_GC7, 0xff},
297 247
298 /* Set the width to 751 */ 248 /* Set the width to 751 */
299 {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02}, 249 {SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
300 {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}, 250 {SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
301 251
302 /* Set the height to 540 */ 252 /* Set the height to 540 */
303 {SENSOR, PO1030_REG_FRAMEHEIGHT_H, 0x02}, 253 {SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
304 {SENSOR, PO1030_REG_FRAMEHEIGHT_L, 0x1c}, 254 {SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
305 255
306 /* Set the x window to 1 */ 256 /* Set the x window to 1 */
307 {SENSOR, PO1030_REG_WINDOWX_H, 0x00}, 257 {SENSOR, PO1030_WINDOWX_H, 0x00},
308 {SENSOR, PO1030_REG_WINDOWX_L, 0x01}, 258 {SENSOR, PO1030_WINDOWX_L, 0x01},
309 259
310 /* Set the y window to 1 */ 260 /* Set the y window to 1 */
311 {SENSOR, PO1030_REG_WINDOWY_H, 0x00}, 261 {SENSOR, PO1030_WINDOWY_H, 0x00},
312 {SENSOR, PO1030_REG_WINDOWY_L, 0x01}, 262 {SENSOR, PO1030_WINDOWY_L, 0x01},
313
314 {SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
315 {SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
316 {SENSOR, PO1030_REG_WINDOWHEIGHT_H, 0x01},
317 {SENSOR, PO1030_REG_WINDOWHEIGHT_L, 0xe3},
318
319 {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
320 {SENSOR, PO1030_REG_OUTFORMCTRL2, 0x04},
321 {SENSOR, PO1030_REG_AUTOCTRL1, 0x08},
322 {SENSOR, PO1030_REG_CONTROL2, 0x03},
323 {SENSOR, 0x21, 0x90},
324 {SENSOR, PO1030_REG_YTARGET, 0x60},
325 {SENSOR, 0x59, 0x13},
326 {SENSOR, PO1030_REG_OUTFORMCTRL1, 0x40},
327 {SENSOR, 0x5f, 0x00},
328 {SENSOR, 0x60, 0x80},
329 {SENSOR, 0x78, 0x14},
330 {SENSOR, 0x6f, 0x01},
331 {SENSOR, PO1030_REG_CONTROL1, 0x18},
332 {SENSOR, PO1030_REG_GLOBALGAINMAX, 0x14},
333 {SENSOR, 0x63, 0x38},
334 {SENSOR, 0x64, 0x38},
335 {SENSOR, PO1030_REG_CONTROL1, 0x58},
336 {SENSOR, PO1030_REG_RED_GAIN, 0x30},
337 {SENSOR, PO1030_REG_GREEN_1_GAIN, 0x30},
338 {SENSOR, PO1030_REG_BLUE_GAIN, 0x30},
339 {SENSOR, PO1030_REG_GREEN_2_GAIN, 0x30},
340 {SENSOR, PO1030_REG_GC0, 0x10},
341 {SENSOR, PO1030_REG_GC1, 0x20},
342 {SENSOR, PO1030_REG_GC2, 0x40},
343 {SENSOR, PO1030_REG_GC3, 0x60},
344 {SENSOR, PO1030_REG_GC4, 0x80},
345 {SENSOR, PO1030_REG_GC5, 0xa0},
346 {SENSOR, PO1030_REG_GC6, 0xc0},
347 {SENSOR, PO1030_REG_GC7, 0xff},
348 /*end of sequence 4*/
349 /*sequence 5*/
350 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
351 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
352 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
353 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
354 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
355 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
356 {BRIDGE, M5602_XB_SIG_INI, 0x01},
357 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
358 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
359 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
360 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
361 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
362 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
363 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
364 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
365 {BRIDGE, M5602_XB_SIG_INI, 0x00},
366 {BRIDGE, M5602_XB_SIG_INI, 0x00},
367 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
368 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
369 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
370 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7e},
371 {BRIDGE, M5602_XB_SIG_INI, 0x00},
372 /*end of sequence 5*/
373
374 /*sequence 6*/
375 /* Changing 40 in f0 the image becomes green in bayer mode and red in
376 * rgb mode */
377 {SENSOR, PO1030_REG_RED_GAIN, PO1030_RED_GAIN_DEFAULT},
378 /* in changing 40 in f0 the image becomes green in bayer mode and red in
379 * rgb mode */
380 {SENSOR, PO1030_REG_BLUE_GAIN, PO1030_BLUE_GAIN_DEFAULT},
381 263
382 /* with a very low lighted environment increase the exposure but 264 /* with a very low lighted environment increase the exposure but
383 * decrease the FPS (Frame Per Second) */ 265 * decrease the FPS (Frame Per Second) */
384 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 266 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
385 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 267 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
386 268
387 /* Controls high exposure more than SENSOR_LOW_EXPOSURE, use only in 269 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
388 * low lighted environment (f0 is more than ff ?)*/ 270 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
389 {SENSOR, PO1030_REG_INTEGLINES_H, ((PO1030_EXPOSURE_DEFAULT >> 2) 271 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
390 & 0xff)}, 272 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
391
392 /* Controls middle exposure, use only in high lighted environment */
393 {SENSOR, PO1030_REG_INTEGLINES_M, PO1030_EXPOSURE_DEFAULT & 0xff},
394
395 /* Controls clarity (not sure) */
396 {SENSOR, PO1030_REG_INTEGLINES_L, 0x00},
397 /* Controls gain (the image is more lighted) */
398 {SENSOR, PO1030_REG_GLOBALGAIN, PO1030_GLOBAL_GAIN_DEFAULT},
399
400 /* Sets the width */
401 {SENSOR, PO1030_REG_FRAMEWIDTH_H, 0x02},
402 {SENSOR, PO1030_REG_FRAMEWIDTH_L, 0xef}
403 /*end of sequence 6*/
404}; 273};
405 274
406#endif 275#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 4306d596056d..191bcd718979 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -18,6 +18,19 @@
18 18
19#include "m5602_s5k4aa.h" 19#include "m5602_s5k4aa.h"
20 20
21static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
22static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
23static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
24static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
25static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
26static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
27static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
28static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
29static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val);
30static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val);
31static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
32static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
33
21static 34static
22 const 35 const
23 struct dmi_system_id s5k4aa_vflip_dmi_table[] = { 36 struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
@@ -46,6 +59,18 @@ static
46 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 59 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
47 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700") 60 DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
48 } 61 }
62 }, {
63 .ident = "MSI L735",
64 .matches = {
65 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
66 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
67 }
68 }, {
69 .ident = "Lenovo Y300",
70 .matches = {
71 DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"),
72 DMI_MATCH(DMI_PRODUCT_NAME, "Y300")
73 }
49 }, 74 },
50 { } 75 { }
51}; 76};
@@ -61,10 +86,22 @@ static struct v4l2_pix_format s5k4aa_modes[] = {
61 .bytesperline = 640, 86 .bytesperline = 640,
62 .colorspace = V4L2_COLORSPACE_SRGB, 87 .colorspace = V4L2_COLORSPACE_SRGB,
63 .priv = 0 88 .priv = 0
89 },
90 {
91 1280,
92 1024,
93 V4L2_PIX_FMT_SBGGR8,
94 V4L2_FIELD_NONE,
95 .sizeimage =
96 1280 * 1024,
97 .bytesperline = 1280,
98 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0
64 } 100 }
65}; 101};
66 102
67const static struct ctrl s5k4aa_ctrls[] = { 103static const struct ctrl s5k4aa_ctrls[] = {
104#define VFLIP_IDX 0
68 { 105 {
69 { 106 {
70 .id = V4L2_CID_VFLIP, 107 .id = V4L2_CID_VFLIP,
@@ -77,8 +114,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
77 }, 114 },
78 .set = s5k4aa_set_vflip, 115 .set = s5k4aa_set_vflip,
79 .get = s5k4aa_get_vflip 116 .get = s5k4aa_get_vflip
80 117 },
81 }, { 118#define HFLIP_IDX 1
119 {
82 { 120 {
83 .id = V4L2_CID_HFLIP, 121 .id = V4L2_CID_HFLIP,
84 .type = V4L2_CTRL_TYPE_BOOLEAN, 122 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -90,8 +128,9 @@ const static struct ctrl s5k4aa_ctrls[] = {
90 }, 128 },
91 .set = s5k4aa_set_hflip, 129 .set = s5k4aa_set_hflip,
92 .get = s5k4aa_get_hflip 130 .get = s5k4aa_get_hflip
93 131 },
94 }, { 132#define GAIN_IDX 2
133 {
95 { 134 {
96 .id = V4L2_CID_GAIN, 135 .id = V4L2_CID_GAIN,
97 .type = V4L2_CTRL_TYPE_INTEGER, 136 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -99,12 +138,14 @@ const static struct ctrl s5k4aa_ctrls[] = {
99 .minimum = 0, 138 .minimum = 0,
100 .maximum = 127, 139 .maximum = 127,
101 .step = 1, 140 .step = 1,
102 .default_value = 0xa0, 141 .default_value = S5K4AA_DEFAULT_GAIN,
103 .flags = V4L2_CTRL_FLAG_SLIDER 142 .flags = V4L2_CTRL_FLAG_SLIDER
104 }, 143 },
105 .set = s5k4aa_set_gain, 144 .set = s5k4aa_set_gain,
106 .get = s5k4aa_get_gain 145 .get = s5k4aa_get_gain
107 }, { 146 },
147#define EXPOSURE_IDX 3
148 {
108 { 149 {
109 .id = V4L2_CID_EXPOSURE, 150 .id = V4L2_CID_EXPOSURE,
110 .type = V4L2_CTRL_TYPE_INTEGER, 151 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -117,7 +158,36 @@ const static struct ctrl s5k4aa_ctrls[] = {
117 }, 158 },
118 .set = s5k4aa_set_exposure, 159 .set = s5k4aa_set_exposure,
119 .get = s5k4aa_get_exposure 160 .get = s5k4aa_get_exposure
120 } 161 },
162#define NOISE_SUPP_IDX 4
163 {
164 {
165 .id = V4L2_CID_PRIVATE_BASE,
166 .type = V4L2_CTRL_TYPE_BOOLEAN,
167 .name = "Noise suppression (smoothing)",
168 .minimum = 0,
169 .maximum = 1,
170 .step = 1,
171 .default_value = 1,
172 },
173 .set = s5k4aa_set_noise,
174 .get = s5k4aa_get_noise
175 },
176#define BRIGHTNESS_IDX 5
177 {
178 {
179 .id = V4L2_CID_BRIGHTNESS,
180 .type = V4L2_CTRL_TYPE_INTEGER,
181 .name = "Brightness",
182 .minimum = 0,
183 .maximum = 0x1f,
184 .step = 1,
185 .default_value = S5K4AA_DEFAULT_BRIGHTNESS,
186 },
187 .set = s5k4aa_set_brightness,
188 .get = s5k4aa_get_brightness
189 },
190
121}; 191};
122 192
123static void s5k4aa_dump_registers(struct sd *sd); 193static void s5k4aa_dump_registers(struct sd *sd);
@@ -127,6 +197,7 @@ int s5k4aa_probe(struct sd *sd)
127 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 197 u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
128 const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; 198 const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
129 int i, err = 0; 199 int i, err = 0;
200 s32 *sensor_settings;
130 201
131 if (force_sensor) { 202 if (force_sensor) {
132 if (force_sensor == S5K4AA_SENSOR) { 203 if (force_sensor == S5K4AA_SENSOR) {
@@ -185,10 +256,20 @@ int s5k4aa_probe(struct sd *sd)
185 info("Detected a s5k4aa sensor"); 256 info("Detected a s5k4aa sensor");
186 257
187sensor_found: 258sensor_found:
259 sensor_settings = kmalloc(
260 ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL);
261 if (!sensor_settings)
262 return -ENOMEM;
263
188 sd->gspca_dev.cam.cam_mode = s5k4aa_modes; 264 sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
189 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); 265 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
190 sd->desc->ctrls = s5k4aa_ctrls; 266 sd->desc->ctrls = s5k4aa_ctrls;
191 sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); 267 sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
268
269 for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++)
270 sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value;
271 sd->sensor_priv = sensor_settings;
272
192 return 0; 273 return 0;
193} 274}
194 275
@@ -197,9 +278,45 @@ int s5k4aa_start(struct sd *sd)
197 int i, err = 0; 278 int i, err = 0;
198 u8 data[2]; 279 u8 data[2];
199 struct cam *cam = &sd->gspca_dev.cam; 280 struct cam *cam = &sd->gspca_dev.cam;
281 s32 *sensor_settings = sd->sensor_priv;
282
283 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
284 case 1280:
285 PDEBUG(D_V4L2, "Configuring camera for SXGA mode");
286
287 for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
288 switch (SXGA_s5k4aa[i][0]) {
289 case BRIDGE:
290 err = m5602_write_bridge(sd,
291 SXGA_s5k4aa[i][1],
292 SXGA_s5k4aa[i][2]);
293 break;
294
295 case SENSOR:
296 data[0] = SXGA_s5k4aa[i][2];
297 err = m5602_write_sensor(sd,
298 SXGA_s5k4aa[i][1],
299 data, 1);
300 break;
301
302 case SENSOR_LONG:
303 data[0] = SXGA_s5k4aa[i][2];
304 data[1] = SXGA_s5k4aa[i][3];
305 err = m5602_write_sensor(sd,
306 SXGA_s5k4aa[i][1],
307 data, 2);
308 break;
309
310 default:
311 err("Invalid stream command, exiting init");
312 return -EINVAL;
313 }
314 }
315 err = s5k4aa_set_noise(&sd->gspca_dev, 0);
316 if (err < 0)
317 return err;
318 break;
200 319
201 switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
202 {
203 case 640: 320 case 640:
204 PDEBUG(D_V4L2, "Configuring camera for VGA mode"); 321 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
205 322
@@ -231,8 +348,37 @@ int s5k4aa_start(struct sd *sd)
231 return -EINVAL; 348 return -EINVAL;
232 } 349 }
233 } 350 }
351 err = s5k4aa_set_noise(&sd->gspca_dev, 1);
352 if (err < 0)
353 return err;
354 break;
234 } 355 }
235 return err; 356 if (err < 0)
357 return err;
358
359 err = s5k4aa_set_exposure(&sd->gspca_dev,
360 sensor_settings[EXPOSURE_IDX]);
361 if (err < 0)
362 return err;
363
364 err = s5k4aa_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
365 if (err < 0)
366 return err;
367
368 err = s5k4aa_set_brightness(&sd->gspca_dev,
369 sensor_settings[BRIGHTNESS_IDX]);
370 if (err < 0)
371 return err;
372
373 err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]);
374 if (err < 0)
375 return err;
376
377 err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
378 if (err < 0)
379 return err;
380
381 return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
236} 382}
237 383
238int s5k4aa_init(struct sd *sd) 384int s5k4aa_init(struct sd *sd)
@@ -270,62 +416,28 @@ int s5k4aa_init(struct sd *sd)
270 if (dump_sensor) 416 if (dump_sensor)
271 s5k4aa_dump_registers(sd); 417 s5k4aa_dump_registers(sd);
272 418
273 if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) { 419 return err;
274 u8 data = 0x02;
275 info("vertical flip quirk active");
276 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
277 m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
278 data |= S5K4AA_RM_V_FLIP;
279 data &= ~S5K4AA_RM_H_FLIP;
280 m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
281
282 /* Decrement COLSTART to preserve color order (BGGR) */
283 m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
284 data--;
285 m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
286
287 /* Increment ROWSTART to preserve color order (BGGR) */
288 m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
289 data++;
290 m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
291 }
292
293 return (err < 0) ? err : 0;
294}
295
296int s5k4aa_power_down(struct sd *sd)
297{
298 return 0;
299} 420}
300 421
301int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 422static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
302{ 423{
303 struct sd *sd = (struct sd *) gspca_dev; 424 struct sd *sd = (struct sd *) gspca_dev;
304 u8 data = S5K4AA_PAGE_MAP_2; 425 s32 *sensor_settings = sd->sensor_priv;
305 int err;
306
307 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
308 if (err < 0)
309 return err;
310 426
311 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); 427 *val = sensor_settings[EXPOSURE_IDX];
312 if (err < 0)
313 return err;
314
315 *val = data << 8;
316 err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
317 *val |= data;
318 PDEBUG(D_V4L2, "Read exposure %d", *val); 428 PDEBUG(D_V4L2, "Read exposure %d", *val);
319 429
320 return err; 430 return 0;
321} 431}
322 432
323int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 433static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
324{ 434{
325 struct sd *sd = (struct sd *) gspca_dev; 435 struct sd *sd = (struct sd *) gspca_dev;
436 s32 *sensor_settings = sd->sensor_priv;
326 u8 data = S5K4AA_PAGE_MAP_2; 437 u8 data = S5K4AA_PAGE_MAP_2;
327 int err; 438 int err;
328 439
440 sensor_settings[EXPOSURE_IDX] = val;
329 PDEBUG(D_V4L2, "Set exposure to %d", val); 441 PDEBUG(D_V4L2, "Set exposure to %d", val);
330 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 442 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
331 if (err < 0) 443 if (err < 0)
@@ -340,29 +452,26 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
340 return err; 452 return err;
341} 453}
342 454
343int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 455static int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
344{ 456{
345 struct sd *sd = (struct sd *) gspca_dev; 457 struct sd *sd = (struct sd *) gspca_dev;
346 u8 data = S5K4AA_PAGE_MAP_2; 458 s32 *sensor_settings = sd->sensor_priv;
347 int err;
348
349 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
350 if (err < 0)
351 return err;
352 459
353 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 460 *val = sensor_settings[VFLIP_IDX];
354 *val = (data & S5K4AA_RM_V_FLIP) >> 7;
355 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 461 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
356 462
357 return err; 463 return 0;
358} 464}
359 465
360int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 466static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
361{ 467{
362 struct sd *sd = (struct sd *) gspca_dev; 468 struct sd *sd = (struct sd *) gspca_dev;
469 s32 *sensor_settings = sd->sensor_priv;
363 u8 data = S5K4AA_PAGE_MAP_2; 470 u8 data = S5K4AA_PAGE_MAP_2;
364 int err; 471 int err;
365 472
473 sensor_settings[VFLIP_IDX] = val;
474
366 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 475 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
367 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 476 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
368 if (err < 0) 477 if (err < 0)
@@ -370,56 +479,48 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
370 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 479 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
371 if (err < 0) 480 if (err < 0)
372 return err; 481 return err;
373 data = ((data & ~S5K4AA_RM_V_FLIP) 482
374 | ((val & 0x01) << 7)); 483 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
375 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
376 if (err < 0) 484 if (err < 0)
377 return err; 485 return err;
378 486
379 if (val) { 487 if (dmi_check_system(s5k4aa_vflip_dmi_table))
380 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 488 val = !val;
381 if (err < 0)
382 return err;
383
384 data++;
385 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
386 } else {
387 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
388 if (err < 0)
389 return err;
390 489
391 data--; 490 data = ((data & ~S5K4AA_RM_V_FLIP) | ((val & 0x01) << 7));
392 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); 491 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
393 } 492 if (err < 0)
493 return err;
394 494
495 err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
496 if (err < 0)
497 return err;
498 data = (data & 0xfe) | !val;
499 err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
395 return err; 500 return err;
396} 501}
397 502
398int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 503static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
399{ 504{
400 struct sd *sd = (struct sd *) gspca_dev; 505 struct sd *sd = (struct sd *) gspca_dev;
401 u8 data = S5K4AA_PAGE_MAP_2; 506 s32 *sensor_settings = sd->sensor_priv;
402 int err;
403
404 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
405 if (err < 0)
406 return err;
407 507
408 err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 508 *val = sensor_settings[HFLIP_IDX];
409 *val = (data & S5K4AA_RM_H_FLIP) >> 6;
410 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 509 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
411 510
412 return err; 511 return 0;
413} 512}
414 513
415int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 514static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
416{ 515{
417 struct sd *sd = (struct sd *) gspca_dev; 516 struct sd *sd = (struct sd *) gspca_dev;
517 s32 *sensor_settings = sd->sensor_priv;
418 u8 data = S5K4AA_PAGE_MAP_2; 518 u8 data = S5K4AA_PAGE_MAP_2;
419 int err; 519 int err;
420 520
421 PDEBUG(D_V4L2, "Set horizontal flip to %d", 521 sensor_settings[HFLIP_IDX] = val;
422 val); 522
523 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
423 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 524 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
424 if (err < 0) 525 if (err < 0)
425 return err; 526 return err;
@@ -427,62 +528,116 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
427 if (err < 0) 528 if (err < 0)
428 return err; 529 return err;
429 530
531 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
532 if (err < 0)
533 return err;
534
535 if (dmi_check_system(s5k4aa_vflip_dmi_table))
536 val = !val;
537
430 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6)); 538 data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
431 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 539 err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
432 if (err < 0) 540 if (err < 0)
433 return err; 541 return err;
434 542
435 if (val) { 543 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
436 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); 544 if (err < 0)
437 if (err < 0) 545 return err;
438 return err; 546 data = (data & 0xfe) | !val;
439 data++; 547 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
440 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
441 if (err < 0)
442 return err;
443 } else {
444 err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
445 if (err < 0)
446 return err;
447 data--;
448 err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
449 }
450
451 return err; 548 return err;
452} 549}
453 550
454int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 551static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
552{
553 struct sd *sd = (struct sd *) gspca_dev;
554 s32 *sensor_settings = sd->sensor_priv;
555
556 *val = sensor_settings[GAIN_IDX];
557 PDEBUG(D_V4L2, "Read gain %d", *val);
558 return 0;
559}
560
561static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
455{ 562{
456 struct sd *sd = (struct sd *) gspca_dev; 563 struct sd *sd = (struct sd *) gspca_dev;
564 s32 *sensor_settings = sd->sensor_priv;
457 u8 data = S5K4AA_PAGE_MAP_2; 565 u8 data = S5K4AA_PAGE_MAP_2;
458 int err; 566 int err;
459 567
568 sensor_settings[GAIN_IDX] = val;
569
570 PDEBUG(D_V4L2, "Set gain to %d", val);
460 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 571 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
461 if (err < 0) 572 if (err < 0)
462 return err; 573 return err;
463 574
464 err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); 575 data = val & 0xff;
465 *val = data; 576 err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1);
466 PDEBUG(D_V4L2, "Read gain %d", *val);
467 577
468 return err; 578 return err;
469} 579}
470 580
471int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) 581static int s5k4aa_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
582{
583 struct sd *sd = (struct sd *) gspca_dev;
584 s32 *sensor_settings = sd->sensor_priv;
585
586 *val = sensor_settings[BRIGHTNESS_IDX];
587 PDEBUG(D_V4L2, "Read brightness %d", *val);
588 return 0;
589}
590
591static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
472{ 592{
473 struct sd *sd = (struct sd *) gspca_dev; 593 struct sd *sd = (struct sd *) gspca_dev;
594 s32 *sensor_settings = sd->sensor_priv;
474 u8 data = S5K4AA_PAGE_MAP_2; 595 u8 data = S5K4AA_PAGE_MAP_2;
475 int err; 596 int err;
476 597
477 PDEBUG(D_V4L2, "Set gain to %d", val); 598 sensor_settings[BRIGHTNESS_IDX] = val;
599
600 PDEBUG(D_V4L2, "Set brightness to %d", val);
478 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 601 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
479 if (err < 0) 602 if (err < 0)
480 return err; 603 return err;
481 604
482 data = val & 0xff; 605 data = val & 0xff;
483 err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1); 606 return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1);
607}
484 608
485 return err; 609static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val)
610{
611 struct sd *sd = (struct sd *) gspca_dev;
612 s32 *sensor_settings = sd->sensor_priv;
613
614 *val = sensor_settings[NOISE_SUPP_IDX];
615 PDEBUG(D_V4L2, "Read noise %d", *val);
616 return 0;
617}
618
619static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
620{
621 struct sd *sd = (struct sd *) gspca_dev;
622 s32 *sensor_settings = sd->sensor_priv;
623 u8 data = S5K4AA_PAGE_MAP_2;
624 int err;
625
626 sensor_settings[NOISE_SUPP_IDX] = val;
627
628 PDEBUG(D_V4L2, "Set noise to %d", val);
629 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
630 if (err < 0)
631 return err;
632
633 data = val & 0x01;
634 return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1);
635}
636
637void s5k4aa_disconnect(struct sd *sd)
638{
639 sd->sensor = NULL;
640 kfree(sd->sensor_priv);
486} 641}
487 642
488static void s5k4aa_dump_registers(struct sd *sd) 643static void s5k4aa_dump_registers(struct sd *sd)
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index ca854d4f9475..4440da4e7f0f 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -47,8 +47,9 @@
47#define S5K4AA_H_BLANK_LO__ 0x1e 47#define S5K4AA_H_BLANK_LO__ 0x1e
48#define S5K4AA_EXPOSURE_HI 0x17 48#define S5K4AA_EXPOSURE_HI 0x17
49#define S5K4AA_EXPOSURE_LO 0x18 49#define S5K4AA_EXPOSURE_LO 0x18
50#define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ 50#define S5K4AA_BRIGHTNESS 0x1f /* (digital?) gain : 5 bits */
51#define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ 51#define S5K4AA_GAIN 0x20 /* (analogue?) gain : 7 bits */
52#define S5K4AA_NOISE_SUPP 0x37
52 53
53#define S5K4AA_RM_ROW_SKIP_4X 0x08 54#define S5K4AA_RM_ROW_SKIP_4X 0x08
54#define S5K4AA_RM_ROW_SKIP_2X 0x04 55#define S5K4AA_RM_ROW_SKIP_2X 0x04
@@ -57,6 +58,9 @@
57#define S5K4AA_RM_H_FLIP 0x40 58#define S5K4AA_RM_H_FLIP 0x40
58#define S5K4AA_RM_V_FLIP 0x80 59#define S5K4AA_RM_V_FLIP 0x80
59 60
61#define S5K4AA_DEFAULT_GAIN 0x5f
62#define S5K4AA_DEFAULT_BRIGHTNESS 0x10
63
60/*****************************************************************************/ 64/*****************************************************************************/
61 65
62/* Kernel module parameters */ 66/* Kernel module parameters */
@@ -66,25 +70,17 @@ extern int dump_sensor;
66int s5k4aa_probe(struct sd *sd); 70int s5k4aa_probe(struct sd *sd);
67int s5k4aa_init(struct sd *sd); 71int s5k4aa_init(struct sd *sd);
68int s5k4aa_start(struct sd *sd); 72int s5k4aa_start(struct sd *sd);
69int s5k4aa_power_down(struct sd *sd); 73void s5k4aa_disconnect(struct sd *sd);
70
71int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
72int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
73int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
74int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
75int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
76int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
77int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
78int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
79 74
80static const struct m5602_sensor s5k4aa = { 75static const struct m5602_sensor s5k4aa = {
81 .name = "S5K4AA", 76 .name = "S5K4AA",
77 .i2c_slave_id = 0x5a,
78 .i2c_regW = 2,
79
82 .probe = s5k4aa_probe, 80 .probe = s5k4aa_probe,
83 .init = s5k4aa_init, 81 .init = s5k4aa_init,
84 .start = s5k4aa_start, 82 .start = s5k4aa_start,
85 .power_down = s5k4aa_power_down, 83 .disconnect = s5k4aa_disconnect,
86 .i2c_slave_id = 0x5a,
87 .i2c_regW = 2,
88}; 84};
89 85
90static const unsigned char preinit_s5k4aa[][4] = 86static const unsigned char preinit_s5k4aa[][4] =
@@ -179,30 +175,12 @@ static const unsigned char init_s5k4aa[][4] =
179 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 175 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
180 {SENSOR, 0x0c, 0x05, 0x00}, 176 {SENSOR, 0x0c, 0x05, 0x00},
181 {SENSOR, 0x02, 0x0e, 0x00}, 177 {SENSOR, 0x02, 0x0e, 0x00},
182 {SENSOR, S5K4AA_GAIN_1, 0x0f, 0x00},
183 {SENSOR, S5K4AA_GAIN_2, 0x00, 0x00},
184 {SENSOR, S5K4AA_GLOBAL_GAIN__, 0x01, 0x00},
185 {SENSOR, 0x11, 0x00, 0x00},
186 {SENSOR, 0x12, 0x00, 0x00},
187 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
188 {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00}, 178 {SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
189 {SENSOR, 0x37, 0x00, 0x00}, 179 {SENSOR, 0x37, 0x00, 0x00},
190 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, 180};
191 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
192 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
193 {SENSOR, S5K4AA_COLSTART_LO, 0x0b, 0x00},
194 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
195 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc4, 0x00},
196 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
197 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x08, 0x00},
198 {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
199 {SENSOR, S5K4AA_H_BLANK_LO__, 0x48, 0x00},
200 {SENSOR, S5K4AA_EXPOSURE_HI, 0x00, 0x00},
201 {SENSOR, S5K4AA_EXPOSURE_LO, 0x43, 0x00},
202 {SENSOR, 0x11, 0x04, 0x00},
203 {SENSOR, 0x12, 0xc3, 0x00},
204 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
205 181
182static const unsigned char VGA_s5k4aa[][4] =
183{
206 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 184 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
207 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 185 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
208 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 186 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -238,7 +216,7 @@ static const unsigned char init_s5k4aa[][4] =
238 {SENSOR, 0x37, 0x01, 0x00}, 216 {SENSOR, 0x37, 0x01, 0x00},
239 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */ 217 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
240 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, 218 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
241 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, 219 {SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
242 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, 220 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
243 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, 221 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
244 /* window_height_hi, window_height_lo : 960 = 0x03c0 */ 222 /* window_height_hi, window_height_lo : 960 = 0x03c0 */
@@ -255,12 +233,9 @@ static const unsigned char init_s5k4aa[][4] =
255 {SENSOR, 0x12, 0xc3, 0x00}, 233 {SENSOR, 0x12, 0xc3, 0x00},
256 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 234 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
257 {SENSOR, 0x02, 0x0e, 0x00}, 235 {SENSOR, 0x02, 0x0e, 0x00},
258 {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
259 {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
260 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
261}; 236};
262 237
263static const unsigned char VGA_s5k4aa[][4] = 238static const unsigned char SXGA_s5k4aa[][4] =
264{ 239{
265 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 240 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
266 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 241 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
@@ -273,50 +248,42 @@ static const unsigned char VGA_s5k4aa[][4] =
273 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 248 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
274 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 249 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
275 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
276 /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */ 251 /* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
277 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, 252 {BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
278 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00}, 253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
279 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
280 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
281 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 256 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
282 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00}, 257 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
283 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 258 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
284 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 259 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
285 /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */ 260 /* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
286 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 261 {BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
287 {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00}, 262 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
288 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 263 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
289 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 264 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
290 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */ 265 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
291 266
292 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 267 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
293 {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X 268 {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
294 | S5K4AA_RM_COL_SKIP_2X, 0x00},
295 /* 0x37 : Fix image stability when light is too bright and improves
296 * image quality in 640x480, but worsens it in 1280x1024 */
297 {SENSOR, 0x37, 0x01, 0x00}, 269 {SENSOR, 0x37, 0x01, 0x00},
298 /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
299 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00}, 270 {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
300 {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00}, 271 {SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
301 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00}, 272 {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
302 {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00}, 273 {SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
303 /* window_height_hi, window_height_lo : 960 = 0x03c0 */ 274 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
304 {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00}, 275 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
305 {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
306 /* window_width_hi, window_width_lo : 1280 = 0x0500 */
307 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00}, 276 {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
308 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00}, 277 {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
309 {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00}, 278 {SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
310 {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */ 279 {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
311 {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00}, 280 {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
312 {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00}, 281 {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
313 {SENSOR, 0x11, 0x04, 0x00}, 282 {SENSOR, 0x11, 0x04, 0x00},
314 {SENSOR, 0x12, 0xc3, 0x00}, 283 {SENSOR, 0x12, 0xc3, 0x00},
315 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00}, 284 {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
316 {SENSOR, 0x02, 0x0e, 0x00}, 285 {SENSOR, 0x02, 0x0e, 0x00},
317 {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
318 {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
319 {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
320}; 286};
321 287
288
322#endif 289#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 42c86aa4dc8d..7127321ace8c 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -16,8 +16,20 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/kthread.h>
19#include "m5602_s5k83a.h" 20#include "m5602_s5k83a.h"
20 21
22static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
25static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
26static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
27static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
28static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
29static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
30static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
31static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
32
21static struct v4l2_pix_format s5k83a_modes[] = { 33static struct v4l2_pix_format s5k83a_modes[] = {
22 { 34 {
23 640, 35 640,
@@ -32,68 +44,77 @@ static struct v4l2_pix_format s5k83a_modes[] = {
32 } 44 }
33}; 45};
34 46
35const static struct ctrl s5k83a_ctrls[] = { 47static const struct ctrl s5k83a_ctrls[] = {
48#define GAIN_IDX 0
36 { 49 {
37 { 50 {
38 .id = V4L2_CID_BRIGHTNESS, 51 .id = V4L2_CID_GAIN,
39 .type = V4L2_CTRL_TYPE_INTEGER, 52 .type = V4L2_CTRL_TYPE_INTEGER,
40 .name = "brightness", 53 .name = "gain",
41 .minimum = 0x00, 54 .minimum = 0x00,
42 .maximum = 0xff, 55 .maximum = 0xff,
43 .step = 0x01, 56 .step = 0x01,
44 .default_value = S5K83A_DEFAULT_BRIGHTNESS, 57 .default_value = S5K83A_DEFAULT_GAIN,
45 .flags = V4L2_CTRL_FLAG_SLIDER 58 .flags = V4L2_CTRL_FLAG_SLIDER
46 }, 59 },
47 .set = s5k83a_set_brightness, 60 .set = s5k83a_set_gain,
48 .get = s5k83a_get_brightness 61 .get = s5k83a_get_gain
49 62
50 }, { 63 },
64#define BRIGHTNESS_IDX 1
65 {
51 { 66 {
52 .id = V4L2_CID_WHITENESS, 67 .id = V4L2_CID_BRIGHTNESS,
53 .type = V4L2_CTRL_TYPE_INTEGER, 68 .type = V4L2_CTRL_TYPE_INTEGER,
54 .name = "whiteness", 69 .name = "brightness",
55 .minimum = 0x00, 70 .minimum = 0x00,
56 .maximum = 0xff, 71 .maximum = 0xff,
57 .step = 0x01, 72 .step = 0x01,
58 .default_value = S5K83A_DEFAULT_WHITENESS, 73 .default_value = S5K83A_DEFAULT_BRIGHTNESS,
59 .flags = V4L2_CTRL_FLAG_SLIDER 74 .flags = V4L2_CTRL_FLAG_SLIDER
60 }, 75 },
61 .set = s5k83a_set_whiteness, 76 .set = s5k83a_set_brightness,
62 .get = s5k83a_get_whiteness, 77 .get = s5k83a_get_brightness,
63 }, { 78 },
79#define EXPOSURE_IDX 2
80 {
64 { 81 {
65 .id = V4L2_CID_GAIN, 82 .id = V4L2_CID_EXPOSURE,
66 .type = V4L2_CTRL_TYPE_INTEGER, 83 .type = V4L2_CTRL_TYPE_INTEGER,
67 .name = "gain", 84 .name = "exposure",
68 .minimum = 0x00, 85 .minimum = 0x00,
69 .maximum = S5K83A_MAXIMUM_GAIN, 86 .maximum = S5K83A_MAXIMUM_EXPOSURE,
70 .step = 0x01, 87 .step = 0x01,
71 .default_value = S5K83A_DEFAULT_GAIN, 88 .default_value = S5K83A_DEFAULT_EXPOSURE,
72 .flags = V4L2_CTRL_FLAG_SLIDER 89 .flags = V4L2_CTRL_FLAG_SLIDER
73 }, 90 },
74 .set = s5k83a_set_gain, 91 .set = s5k83a_set_exposure,
75 .get = s5k83a_get_gain 92 .get = s5k83a_get_exposure
76 }, { 93 },
94#define HFLIP_IDX 3
95 {
77 { 96 {
78 .id = V4L2_CID_HFLIP, 97 .id = V4L2_CID_HFLIP,
79 .type = V4L2_CTRL_TYPE_BOOLEAN, 98 .type = V4L2_CTRL_TYPE_BOOLEAN,
80 .name = "horizontal flip", 99 .name = "horizontal flip",
81 .minimum = 0, 100 .minimum = 0,
82 .maximum = 1, 101 .maximum = 1,
83 .step = 1, 102 .step = 1,
84 .default_value = 0 103 .default_value = 0
85 }, 104 },
86 .set = s5k83a_set_hflip, 105 .set = s5k83a_set_hflip,
87 .get = s5k83a_get_hflip 106 .get = s5k83a_get_hflip
88 }, { 107 },
108#define VFLIP_IDX 4
109 {
89 { 110 {
90 .id = V4L2_CID_VFLIP, 111 .id = V4L2_CID_VFLIP,
91 .type = V4L2_CTRL_TYPE_BOOLEAN, 112 .type = V4L2_CTRL_TYPE_BOOLEAN,
92 .name = "vertical flip", 113 .name = "vertical flip",
93 .minimum = 0, 114 .minimum = 0,
94 .maximum = 1, 115 .maximum = 1,
95 .step = 1, 116 .step = 1,
96 .default_value = 0 117 .default_value = 0
97 }, 118 },
98 .set = s5k83a_set_vflip, 119 .set = s5k83a_set_vflip,
99 .get = s5k83a_get_vflip 120 .get = s5k83a_get_vflip
@@ -101,9 +122,14 @@ const static struct ctrl s5k83a_ctrls[] = {
101}; 122};
102 123
103static void s5k83a_dump_registers(struct sd *sd); 124static void s5k83a_dump_registers(struct sd *sd);
125static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
126static int s5k83a_set_led_indication(struct sd *sd, u8 val);
127static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
128 __s32 vflip, __s32 hflip);
104 129
105int s5k83a_probe(struct sd *sd) 130int s5k83a_probe(struct sd *sd)
106{ 131{
132 struct s5k83a_priv *sens_priv;
107 u8 prod_id = 0, ver_id = 0; 133 u8 prod_id = 0, ver_id = 0;
108 int i, err = 0; 134 int i, err = 0;
109 135
@@ -145,16 +171,36 @@ int s5k83a_probe(struct sd *sd)
145 info("Detected a s5k83a sensor"); 171 info("Detected a s5k83a sensor");
146 172
147sensor_found: 173sensor_found:
174 sens_priv = kmalloc(
175 sizeof(struct s5k83a_priv), GFP_KERNEL);
176 if (!sens_priv)
177 return -ENOMEM;
178
179 sens_priv->settings =
180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181 if (!sens_priv->settings)
182 return -ENOMEM;
183
148 sd->gspca_dev.cam.cam_mode = s5k83a_modes; 184 sd->gspca_dev.cam.cam_mode = s5k83a_modes;
149 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); 185 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
150 sd->desc->ctrls = s5k83a_ctrls; 186 sd->desc->ctrls = s5k83a_ctrls;
151 sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls); 187 sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
188
189 /* null the pointer! thread is't running now */
190 sens_priv->rotation_thread = NULL;
191
192 for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
193 sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
194
195 sd->sensor_priv = sens_priv;
152 return 0; 196 return 0;
153} 197}
154 198
155int s5k83a_init(struct sd *sd) 199int s5k83a_init(struct sd *sd)
156{ 200{
157 int i, err = 0; 201 int i, err = 0;
202 s32 *sensor_settings =
203 ((struct s5k83a_priv *) sd->sensor_priv)->settings;
158 204
159 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) { 205 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
160 u8 data[2] = {0x00, 0x00}; 206 u8 data[2] = {0x00, 0x00};
@@ -187,87 +233,138 @@ int s5k83a_init(struct sd *sd)
187 if (dump_sensor) 233 if (dump_sensor)
188 s5k83a_dump_registers(sd); 234 s5k83a_dump_registers(sd);
189 235
190 return (err < 0) ? err : 0; 236 err = s5k83a_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
191} 237 if (err < 0)
238 return err;
192 239
193int s5k83a_start(struct sd *sd) 240 err = s5k83a_set_brightness(&sd->gspca_dev,
194{ 241 sensor_settings[BRIGHTNESS_IDX]);
195 return s5k83a_set_led_indication(sd, 1); 242 if (err < 0)
196} 243 return err;
197 244
198int s5k83a_stop(struct sd *sd) 245 err = s5k83a_set_exposure(&sd->gspca_dev,
199{ 246 sensor_settings[EXPOSURE_IDX]);
200 return s5k83a_set_led_indication(sd, 0); 247 if (err < 0)
248 return err;
249
250 err = s5k83a_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
251 if (err < 0)
252 return err;
253
254 err = s5k83a_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
255
256 return err;
201} 257}
202 258
203int s5k83a_power_down(struct sd *sd) 259static int rotation_thread_function(void *data)
204{ 260{
261 struct sd *sd = (struct sd *) data;
262 struct s5k83a_priv *sens_priv = sd->sensor_priv;
263 u8 reg, previous_rotation = 0;
264 __s32 vflip, hflip;
265
266 set_current_state(TASK_INTERRUPTIBLE);
267 while (!schedule_timeout(100)) {
268 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
269 break;
270
271 s5k83a_get_rotation(sd, &reg);
272 if (previous_rotation != reg) {
273 previous_rotation = reg;
274 info("Camera was flipped");
275
276 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
277 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
278
279 if (reg) {
280 vflip = !vflip;
281 hflip = !hflip;
282 }
283 s5k83a_set_flip_real((struct gspca_dev *) sd,
284 vflip, hflip);
285 }
286
287 mutex_unlock(&sd->gspca_dev.usb_lock);
288 set_current_state(TASK_INTERRUPTIBLE);
289 }
290
291 /* return to "front" flip */
292 if (previous_rotation) {
293 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
294 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
295 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
296 }
297
298 sens_priv->rotation_thread = NULL;
205 return 0; 299 return 0;
206} 300}
207 301
208static void s5k83a_dump_registers(struct sd *sd) 302int s5k83a_start(struct sd *sd)
209{ 303{
210 int address; 304 int i, err = 0;
211 u8 page, old_page; 305 struct s5k83a_priv *sens_priv = sd->sensor_priv;
212 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
213 306
214 for (page = 0; page < 16; page++) { 307 /* Create another thread, polling the GPIO ports of the camera to check
215 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 308 if it got rotated. This is how the windows driver does it so we have
216 info("Dumping the s5k83a register state for page 0x%x", page); 309 to assume that there is no better way of accomplishing this */
217 for (address = 0; address <= 0xff; address++) { 310 sens_priv->rotation_thread = kthread_create(rotation_thread_function,
218 u8 val = 0; 311 sd, "rotation thread");
219 m5602_read_sensor(sd, address, &val, 1); 312 wake_up_process(sens_priv->rotation_thread);
220 info("register 0x%x contains 0x%x", 313
221 address, val); 314 /* Preinit the sensor */
222 } 315 for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
316 u8 data[2] = {start_s5k83a[i][2], start_s5k83a[i][3]};
317 if (start_s5k83a[i][0] == SENSOR)
318 err = m5602_write_sensor(sd, start_s5k83a[i][1],
319 data, 2);
320 else
321 err = m5602_write_bridge(sd, start_s5k83a[i][1],
322 data[0]);
223 } 323 }
224 info("s5k83a register state dump complete"); 324 if (err < 0)
325 return err;
225 326
226 for (page = 0; page < 16; page++) { 327 return s5k83a_set_led_indication(sd, 1);
227 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1); 328}
228 info("Probing for which registers that are read/write "
229 "for page 0x%x", page);
230 for (address = 0; address <= 0xff; address++) {
231 u8 old_val, ctrl_val, test_val = 0xff;
232 329
233 m5602_read_sensor(sd, address, &old_val, 1); 330int s5k83a_stop(struct sd *sd)
234 m5602_write_sensor(sd, address, &test_val, 1); 331{
235 m5602_read_sensor(sd, address, &ctrl_val, 1); 332 struct s5k83a_priv *sens_priv = sd->sensor_priv;
236 333
237 if (ctrl_val == test_val) 334 if (sens_priv->rotation_thread)
238 info("register 0x%x is writeable", address); 335 kthread_stop(sens_priv->rotation_thread);
239 else
240 info("register 0x%x is read only", address);
241 336
242 /* Restore original val */ 337 return s5k83a_set_led_indication(sd, 0);
243 m5602_write_sensor(sd, address, &old_val, 1);
244 }
245 }
246 info("Read/write register probing complete");
247 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
248} 338}
249 339
250int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) 340void s5k83a_disconnect(struct sd *sd)
251{ 341{
252 int err; 342 struct s5k83a_priv *sens_priv = sd->sensor_priv;
253 u8 data[2];
254 struct sd *sd = (struct sd *) gspca_dev;
255 343
256 err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 344 s5k83a_stop(sd);
257 if (err < 0) 345
258 return err; 346 sd->sensor = NULL;
347 kfree(sens_priv->settings);
348 kfree(sens_priv);
349}
259 350
260 data[1] = data[1] << 1; 351static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
261 *val = data[1]; 352{
353 struct sd *sd = (struct sd *) gspca_dev;
354 struct s5k83a_priv *sens_priv = sd->sensor_priv;
262 355
263 return err; 356 *val = sens_priv->settings[GAIN_IDX];
357 return 0;
264} 358}
265 359
266int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val) 360static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
267{ 361{
268 int err; 362 int err;
269 u8 data[2]; 363 u8 data[2];
270 struct sd *sd = (struct sd *) gspca_dev; 364 struct sd *sd = (struct sd *) gspca_dev;
365 struct s5k83a_priv *sens_priv = sd->sensor_priv;
366
367 sens_priv->settings[GAIN_IDX] = val;
271 368
272 data[0] = 0x00; 369 data[0] = 0x00;
273 data[1] = 0x20; 370 data[1] = 0x20;
@@ -283,89 +380,69 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
283 380
284 /* FIXME: This is not sane, we need to figure out the composition 381 /* FIXME: This is not sane, we need to figure out the composition
285 of these registers */ 382 of these registers */
286 data[0] = val >> 3; /* brightness, high 5 bits */ 383 data[0] = val >> 3; /* gain, high 5 bits */
287 data[1] = val >> 1; /* brightness, high 7 bits */ 384 data[1] = val >> 1; /* gain, high 7 bits */
288 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2); 385 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
289 386
290 return err; 387 return err;
291} 388}
292 389
293int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val) 390static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
294{ 391{
295 int err;
296 u8 data;
297 struct sd *sd = (struct sd *) gspca_dev; 392 struct sd *sd = (struct sd *) gspca_dev;
393 struct s5k83a_priv *sens_priv = sd->sensor_priv;
298 394
299 err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1); 395 *val = sens_priv->settings[BRIGHTNESS_IDX];
300 if (err < 0) 396 return 0;
301 return err;
302
303 *val = data;
304
305 return err;
306} 397}
307 398
308int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val) 399static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
309{ 400{
310 int err; 401 int err;
311 u8 data[1]; 402 u8 data[1];
312 struct sd *sd = (struct sd *) gspca_dev; 403 struct sd *sd = (struct sd *) gspca_dev;
404 struct s5k83a_priv *sens_priv = sd->sensor_priv;
313 405
406 sens_priv->settings[BRIGHTNESS_IDX] = val;
314 data[0] = val; 407 data[0] = val;
315 err = m5602_write_sensor(sd, S5K83A_WHITENESS, data, 1); 408 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
316
317 return err; 409 return err;
318} 410}
319 411
320int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 412static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
321{ 413{
322 int err;
323 u8 data[2];
324 struct sd *sd = (struct sd *) gspca_dev; 414 struct sd *sd = (struct sd *) gspca_dev;
415 struct s5k83a_priv *sens_priv = sd->sensor_priv;
325 416
326 err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2); 417 *val = sens_priv->settings[EXPOSURE_IDX];
327 if (err < 0) 418 return 0;
328 return err;
329
330 data[1] = data[1] & 0x3f;
331 if (data[1] > S5K83A_MAXIMUM_GAIN)
332 data[1] = S5K83A_MAXIMUM_GAIN;
333
334 *val = data[1];
335
336 return err;
337} 419}
338 420
339int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val) 421static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
340{ 422{
341 int err; 423 int err;
342 u8 data[2]; 424 u8 data[2];
343 struct sd *sd = (struct sd *) gspca_dev; 425 struct sd *sd = (struct sd *) gspca_dev;
426 struct s5k83a_priv *sens_priv = sd->sensor_priv;
344 427
428 sens_priv->settings[EXPOSURE_IDX] = val;
345 data[0] = 0; 429 data[0] = 0;
346 data[1] = val; 430 data[1] = val;
347 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2); 431 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
348 return err; 432 return err;
349} 433}
350 434
351int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 435static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
352{ 436{
353 int err;
354 u8 data[1];
355 struct sd *sd = (struct sd *) gspca_dev; 437 struct sd *sd = (struct sd *) gspca_dev;
438 struct s5k83a_priv *sens_priv = sd->sensor_priv;
356 439
357 data[0] = 0x05; 440 *val = sens_priv->settings[VFLIP_IDX];
358 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 441 return 0;
359 if (err < 0)
360 return err;
361
362 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
363 *val = (data[0] | 0x40) ? 1 : 0;
364
365 return err;
366} 442}
367 443
368int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 444static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
445 __s32 vflip, __s32 hflip)
369{ 446{
370 int err; 447 int err;
371 u8 data[1]; 448 u8 data[1];
@@ -376,69 +453,83 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
376 if (err < 0) 453 if (err < 0)
377 return err; 454 return err;
378 455
379 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); 456 /* six bit is vflip, seven is hflip */
380 if (err < 0) 457 data[0] = S5K83A_FLIP_MASK;
381 return err; 458 data[0] = (vflip) ? data[0] | 0x40 : data[0];
459 data[0] = (hflip) ? data[0] | 0x80 : data[0];
382 460
383 /* set or zero six bit, seven is hflip */
384 data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
385 : (data[0] & 0x80) | S5K83A_FLIP_MASK;
386 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1); 461 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
387 if (err < 0) 462 if (err < 0)
388 return err; 463 return err;
389 464
390 data[0] = (val) ? 0x0b : 0x0a; 465 data[0] = (vflip) ? 0x0b : 0x0a;
391 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1); 466 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
467 if (err < 0)
468 return err;
392 469
470 data[0] = (hflip) ? 0x0a : 0x0b;
471 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
393 return err; 472 return err;
394} 473}
395 474
396int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 475static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
397{ 476{
398 int err; 477 int err;
399 u8 data[1]; 478 u8 reg;
479 __s32 hflip;
400 struct sd *sd = (struct sd *) gspca_dev; 480 struct sd *sd = (struct sd *) gspca_dev;
481 struct s5k83a_priv *sens_priv = sd->sensor_priv;
401 482
402 data[0] = 0x05; 483 sens_priv->settings[VFLIP_IDX] = val;
403 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1); 484
485 s5k83a_get_hflip(gspca_dev, &hflip);
486
487 err = s5k83a_get_rotation(sd, &reg);
404 if (err < 0) 488 if (err < 0)
405 return err; 489 return err;
490 if (reg) {
491 val = !val;
492 hflip = !hflip;
493 }
406 494
407 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); 495 err = s5k83a_set_flip_real(gspca_dev, val, hflip);
408 *val = (data[0] | 0x80) ? 1 : 0;
409
410 return err; 496 return err;
411} 497}
412 498
413int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 499static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
500{
501 struct sd *sd = (struct sd *) gspca_dev;
502 struct s5k83a_priv *sens_priv = sd->sensor_priv;
503
504 *val = sens_priv->settings[HFLIP_IDX];
505 return 0;
506}
507
508static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
414{ 509{
415 int err; 510 int err;
416 u8 data[1]; 511 u8 reg;
512 __s32 vflip;
417 struct sd *sd = (struct sd *) gspca_dev; 513 struct sd *sd = (struct sd *) gspca_dev;
514 struct s5k83a_priv *sens_priv = sd->sensor_priv;
418 515
419 data[0] = 0x05; 516 sens_priv->settings[HFLIP_IDX] = val;
420 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
421 if (err < 0)
422 return err;
423 517
424 err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1); 518 s5k83a_get_vflip(gspca_dev, &vflip);
425 if (err < 0)
426 return err;
427 519
428 /* set or zero seven bit, six is vflip */ 520 err = s5k83a_get_rotation(sd, &reg);
429 data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
430 : (data[0] & 0x40) | S5K83A_FLIP_MASK;
431 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
432 if (err < 0) 521 if (err < 0)
433 return err; 522 return err;
523 if (reg) {
524 val = !val;
525 vflip = !vflip;
526 }
434 527
435 data[0] = (val) ? 0x0a : 0x0b; 528 err = s5k83a_set_flip_real(gspca_dev, vflip, val);
436 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
437
438 return err; 529 return err;
439} 530}
440 531
441int s5k83a_set_led_indication(struct sd *sd, u8 val) 532static int s5k83a_set_led_indication(struct sd *sd, u8 val)
442{ 533{
443 int err = 0; 534 int err = 0;
444 u8 data[1]; 535 u8 data[1];
@@ -454,5 +545,55 @@ int s5k83a_set_led_indication(struct sd *sd, u8 val)
454 545
455 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); 546 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
456 547
457 return (err < 0) ? err : 0; 548 return err;
549}
550
551/* Get camera rotation on Acer notebooks */
552static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
553{
554 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
555 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
556 return err;
557}
558
559static void s5k83a_dump_registers(struct sd *sd)
560{
561 int address;
562 u8 page, old_page;
563 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
564
565 for (page = 0; page < 16; page++) {
566 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
567 info("Dumping the s5k83a register state for page 0x%x", page);
568 for (address = 0; address <= 0xff; address++) {
569 u8 val = 0;
570 m5602_read_sensor(sd, address, &val, 1);
571 info("register 0x%x contains 0x%x",
572 address, val);
573 }
574 }
575 info("s5k83a register state dump complete");
576
577 for (page = 0; page < 16; page++) {
578 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
579 info("Probing for which registers that are read/write "
580 "for page 0x%x", page);
581 for (address = 0; address <= 0xff; address++) {
582 u8 old_val, ctrl_val, test_val = 0xff;
583
584 m5602_read_sensor(sd, address, &old_val, 1);
585 m5602_write_sensor(sd, address, &test_val, 1);
586 m5602_read_sensor(sd, address, &ctrl_val, 1);
587
588 if (ctrl_val == test_val)
589 info("register 0x%x is writeable", address);
590 else
591 info("register 0x%x is read only", address);
592
593 /* Restore original val */
594 m5602_write_sensor(sd, address, &old_val, 1);
595 }
596 }
597 info("Read/write register probing complete");
598 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
458} 599}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 819ab25272be..7814b078acde 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -21,20 +21,21 @@
21 21
22#include "m5602_sensor.h" 22#include "m5602_sensor.h"
23 23
24#define S5K83A_FLIP 0x01 24#define S5K83A_FLIP 0x01
25#define S5K83A_HFLIP_TUNE 0x03 25#define S5K83A_HFLIP_TUNE 0x03
26#define S5K83A_VFLIP_TUNE 0x05 26#define S5K83A_VFLIP_TUNE 0x05
27#define S5K83A_WHITENESS 0x0a 27#define S5K83A_BRIGHTNESS 0x0a
28#define S5K83A_GAIN 0x18 28#define S5K83A_EXPOSURE 0x18
29#define S5K83A_BRIGHTNESS 0x1b 29#define S5K83A_GAIN 0x1b
30#define S5K83A_PAGE_MAP 0xec 30#define S5K83A_PAGE_MAP 0xec
31 31
32#define S5K83A_DEFAULT_BRIGHTNESS 0x71 32#define S5K83A_DEFAULT_GAIN 0x71
33#define S5K83A_DEFAULT_WHITENESS 0x7e 33#define S5K83A_DEFAULT_BRIGHTNESS 0x7e
34#define S5K83A_DEFAULT_GAIN 0x00 34#define S5K83A_DEFAULT_EXPOSURE 0x00
35#define S5K83A_MAXIMUM_GAIN 0x3c 35#define S5K83A_MAXIMUM_EXPOSURE 0x3c
36#define S5K83A_FLIP_MASK 0x10 36#define S5K83A_FLIP_MASK 0x10
37#define S5K83A_GPIO_LED_MASK 0x10 37#define S5K83A_GPIO_LED_MASK 0x10
38#define S5K83A_GPIO_ROTATION_MASK 0x40
38 39
39/*****************************************************************************/ 40/*****************************************************************************/
40 41
@@ -46,20 +47,7 @@ int s5k83a_probe(struct sd *sd);
46int s5k83a_init(struct sd *sd); 47int s5k83a_init(struct sd *sd);
47int s5k83a_start(struct sd *sd); 48int s5k83a_start(struct sd *sd);
48int s5k83a_stop(struct sd *sd); 49int s5k83a_stop(struct sd *sd);
49int s5k83a_power_down(struct sd *sd); 50void s5k83a_disconnect(struct sd *sd);
50
51int s5k83a_set_led_indication(struct sd *sd, u8 val);
52
53int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
54int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
55int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
56int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val);
57int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
58int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
59int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
60int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
61int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
62int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
63 51
64static const struct m5602_sensor s5k83a = { 52static const struct m5602_sensor s5k83a = {
65 .name = "S5K83A", 53 .name = "S5K83A",
@@ -67,11 +55,18 @@ static const struct m5602_sensor s5k83a = {
67 .init = s5k83a_init, 55 .init = s5k83a_init,
68 .start = s5k83a_start, 56 .start = s5k83a_start,
69 .stop = s5k83a_stop, 57 .stop = s5k83a_stop,
70 .power_down = s5k83a_power_down, 58 .disconnect = s5k83a_disconnect,
71 .i2c_slave_id = 0x5a, 59 .i2c_slave_id = 0x5a,
72 .i2c_regW = 2, 60 .i2c_regW = 2,
73}; 61};
74 62
63struct s5k83a_priv {
64 /* We use another thread periodically
65 probing the orientation of the camera */
66 struct task_struct *rotation_thread;
67 s32 *settings;
68};
69
75static const unsigned char preinit_s5k83a[][4] = 70static const unsigned char preinit_s5k83a[][4] =
76{ 71{
77 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00}, 72 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
@@ -108,8 +103,6 @@ static const unsigned char preinit_s5k83a[][4] =
108 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, 103 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
109 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00}, 104 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
110 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00}, 105 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
111
112 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00}
113}; 106};
114 107
115/* This could probably be considerably shortened. 108/* This could probably be considerably shortened.
@@ -117,86 +110,8 @@ static const unsigned char preinit_s5k83a[][4] =
117*/ 110*/
118static const unsigned char init_s5k83a[][4] = 111static const unsigned char init_s5k83a[][4] =
119{ 112{
120 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, 113 /* The following sequence is useless after a clean boot
121 {SENSOR, 0xaf, 0x01, 0x00}, 114 but is necessary after resume from suspend */
122 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
123 {SENSOR, 0x7b, 0xff, 0x00},
124 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
125 {SENSOR, 0x01, 0x50, 0x00},
126 {SENSOR, 0x12, 0x20, 0x00},
127 {SENSOR, 0x17, 0x40, 0x00},
128 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
129 {SENSOR, 0x1c, 0x00, 0x00},
130 {SENSOR, 0x02, 0x70, 0x00},
131 {SENSOR, 0x03, 0x0b, 0x00},
132 {SENSOR, 0x04, 0xf0, 0x00},
133 {SENSOR, 0x05, 0x0b, 0x00},
134 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
135
136 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
137 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
138 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
139 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
140 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
141 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
142 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
143 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
144 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
145 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
146 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
147 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
148 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
149 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
150 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
151 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
152 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
153 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
154 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
155 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
156 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
157 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
158 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
159 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
160
161 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
162 {SENSOR, 0x06, 0x71, 0x00},
163 {SENSOR, 0x07, 0xe8, 0x00},
164 {SENSOR, 0x08, 0x02, 0x00},
165 {SENSOR, 0x09, 0x88, 0x00},
166 {SENSOR, 0x14, 0x00, 0x00},
167 {SENSOR, 0x15, 0x20, 0x00},
168 {SENSOR, 0x19, 0x00, 0x00},
169 {SENSOR, 0x1a, 0x98, 0x00},
170 {SENSOR, 0x0f, 0x02, 0x00},
171 {SENSOR, 0x10, 0xe5, 0x00},
172 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
173 {SENSOR_LONG, 0x14, 0x00, 0x20},
174 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
175 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
176
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
179 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
180 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
181 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
182 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
183 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
184 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
185 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
186 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
187 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
188 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
189 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
190 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
191 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
192 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
193 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
194 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
195 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
196 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
197 {BRIDGE, M5602_XB_HSYNC_PARA, 0x87, 0x00},
198
199 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
200 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, 115 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
201 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00}, 116 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
202 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00}, 117 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
@@ -216,7 +131,7 @@ static const unsigned char init_s5k83a[][4] =
216 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 131 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
217 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00}, 132 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
218 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00}, 133 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
219 {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00}, 134 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
220 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00}, 135 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
221 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00}, 136 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
222 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00}, 137 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
@@ -225,109 +140,34 @@ static const unsigned char init_s5k83a[][4] =
225 140
226 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00}, 141 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
227 {SENSOR, 0xaf, 0x01, 0x00}, 142 {SENSOR, 0xaf, 0x01, 0x00},
228 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, 143 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
229 /* ff ( init value )is very dark) || 71 and f0 better */
230 {SENSOR, 0x7b, 0xff, 0x00}, 144 {SENSOR, 0x7b, 0xff, 0x00},
231 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, 145 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
232 {SENSOR, 0x01, 0x50, 0x00}, 146 {SENSOR, 0x01, 0x50, 0x00},
233 {SENSOR, 0x12, 0x20, 0x00}, 147 {SENSOR, 0x12, 0x20, 0x00},
234 {SENSOR, 0x17, 0x40, 0x00}, 148 {SENSOR, 0x17, 0x40, 0x00},
235 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
236 {SENSOR, 0x1c, 0x00, 0x00}, 149 {SENSOR, 0x1c, 0x00, 0x00},
237 {SENSOR, 0x02, 0x70, 0x00}, 150 {SENSOR, 0x02, 0x70, 0x00},
238 /* some values like 0x10 give a blue-purple image */
239 {SENSOR, 0x03, 0x0b, 0x00}, 151 {SENSOR, 0x03, 0x0b, 0x00},
240 {SENSOR, 0x04, 0xf0, 0x00}, 152 {SENSOR, 0x04, 0xf0, 0x00},
241 {SENSOR, 0x05, 0x0b, 0x00}, 153 {SENSOR, 0x05, 0x0b, 0x00},
242 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
243
244 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
245 /* under 80 don't work, highter depend on value */
246 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
247
248 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
249 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
250 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
251 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
252 {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
257 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
258 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00},
259 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
260 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
261 {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
262 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
263 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
264 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
265 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00},
266
267 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
268 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
269 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
270
271 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
272 {SENSOR, 0x06, 0x71, 0x00}, 154 {SENSOR, 0x06, 0x71, 0x00},
273 {SENSOR, 0x07, 0xe8, 0x00}, 155 {SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
274 {SENSOR, 0x08, 0x02, 0x00}, 156 {SENSOR, 0x08, 0x02, 0x00},
275 {SENSOR, 0x09, 0x88, 0x00}, 157 {SENSOR, 0x09, 0x88, 0x00}, /* 648 */
276 {SENSOR, 0x14, 0x00, 0x00}, 158 {SENSOR, 0x14, 0x00, 0x00},
277 {SENSOR, 0x15, 0x20, 0x00}, 159 {SENSOR, 0x15, 0x20, 0x00}, /* 32 */
278 {SENSOR, 0x19, 0x00, 0x00}, 160 {SENSOR, 0x19, 0x00, 0x00},
279 {SENSOR, 0x1a, 0x98, 0x00}, 161 {SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
280 {SENSOR, 0x0f, 0x02, 0x00}, 162 {SENSOR, 0x0f, 0x02, 0x00},
281 {SENSOR, 0x10, 0xe5, 0x00}, 163 {SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
282 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00}, 164 /* normal colors
283 {SENSOR_LONG, 0x14, 0x00, 0x20}, 165 (this is value after boot, but after tries can be different) */
284 {SENSOR_LONG, 0x0d, 0x00, 0x7d}, 166 {SENSOR, 0x00, 0x06, 0x00},
285 {SENSOR_LONG, 0x1b, 0x0d, 0x05}, 167};
286
287 /* The following sequence is useless after a clean boot
288 but is necessary after resume from suspend */
289 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
290 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
291 {BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
292 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
293 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
294 {BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
295 {BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
296 {BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
297 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
298 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
299 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
300 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
301 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
302 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
303 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
304 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
305 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
306 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
307 {BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
308 {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
309 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
310 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
311 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
312 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
313 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
314
315 {SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
316 {SENSOR, 0xaf, 0x01, 0x00},
317 {SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
318 {SENSOR, 0x7b, 0xff, 0x00},
319 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
320 {SENSOR, 0x01, 0x50, 0x00},
321 {SENSOR, 0x12, 0x20, 0x00},
322 {SENSOR, 0x17, 0x40, 0x00},
323 {SENSOR, S5K83A_BRIGHTNESS, 0x0f, 0x00},
324 {SENSOR, 0x1c, 0x00, 0x00},
325 {SENSOR, 0x02, 0x70, 0x00},
326 {SENSOR, 0x03, 0x0b, 0x00},
327 {SENSOR, 0x04, 0xf0, 0x00},
328 {SENSOR, 0x05, 0x0b, 0x00},
329 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
330 168
169static const unsigned char start_s5k83a[][4] =
170{
331 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00}, 171 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
332 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 172 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
333 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00}, 173 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
@@ -340,7 +180,7 @@ static const unsigned char init_s5k83a[][4] =
340 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 180 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
341 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 181 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
342 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00}, 182 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
343 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, 183 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
344 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 184 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
345 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00}, 185 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
346 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 186 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
@@ -348,50 +188,10 @@ static const unsigned char init_s5k83a[][4] =
348 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 188 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
349 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00}, 189 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
350 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00}, 190 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
351 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, 191 {BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
352 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00}, 192 {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
353 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00}, 193 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
354 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00}, 194 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
355
356 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
357 {SENSOR, 0x06, 0x71, 0x00},
358 {SENSOR, 0x07, 0xe8, 0x00},
359 {SENSOR, 0x08, 0x02, 0x00},
360 {SENSOR, 0x09, 0x88, 0x00},
361 {SENSOR, 0x14, 0x00, 0x00},
362 {SENSOR, 0x15, 0x20, 0x00},
363 {SENSOR, 0x19, 0x00, 0x00},
364 {SENSOR, 0x1a, 0x98, 0x00},
365 {SENSOR, 0x0f, 0x02, 0x00},
366
367 {SENSOR, 0x10, 0xe5, 0x00},
368 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
369 {SENSOR_LONG, 0x14, 0x00, 0x20},
370 {SENSOR_LONG, 0x0d, 0x00, 0x7d},
371 {SENSOR_LONG, 0x1b, 0x0d, 0x05},
372
373 /* normal colors
374 (this is value after boot, but after tries can be different) */
375 {SENSOR, 0x00, 0x06, 0x00},
376
377 /* set default brightness */
378 {SENSOR_LONG, 0x14, 0x00, 0x20},
379 {SENSOR_LONG, 0x0d, 0x01, 0x00},
380 {SENSOR_LONG, 0x1b, S5K83A_DEFAULT_BRIGHTNESS >> 3,
381 S5K83A_DEFAULT_BRIGHTNESS >> 1},
382
383 /* set default whiteness */
384 {SENSOR, S5K83A_WHITENESS, S5K83A_DEFAULT_WHITENESS, 0x00},
385
386 /* set default gain */
387 {SENSOR_LONG, 0x18, 0x00, S5K83A_DEFAULT_GAIN},
388
389 /* set default flip */
390 {SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
391 {SENSOR, S5K83A_FLIP, 0x00 | S5K83A_FLIP_MASK, 0x00},
392 {SENSOR, S5K83A_HFLIP_TUNE, 0x0b, 0x00},
393 {SENSOR, S5K83A_VFLIP_TUNE, 0x0a, 0x00}
394
395}; 195};
396 196
397#endif 197#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 0d3026936f2e..edff4f1f586f 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -21,13 +21,17 @@
21 21
22#include "m5602_bridge.h" 22#include "m5602_bridge.h"
23 23
24#define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0)
25#define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1)
26
24/* Enumerates all supported sensors */ 27/* Enumerates all supported sensors */
25enum sensors { 28enum sensors {
26 OV9650_SENSOR = 1, 29 OV9650_SENSOR = 1,
27 S5K83A_SENSOR = 2, 30 S5K83A_SENSOR = 2,
28 S5K4AA_SENSOR = 3, 31 S5K4AA_SENSOR = 3,
29 MT9M111_SENSOR = 4, 32 MT9M111_SENSOR = 4,
30 PO1030_SENSOR = 5 33 PO1030_SENSOR = 5,
34 OV7660_SENSOR = 6,
31}; 35};
32 36
33/* Enumerates all possible instruction types */ 37/* Enumerates all possible instruction types */
@@ -61,9 +65,6 @@ struct m5602_sensor {
61 65
62 /* Executed when the device is disconnected */ 66 /* Executed when the device is disconnected */
63 void (*disconnect)(struct sd *sd); 67 void (*disconnect)(struct sd *sd);
64
65 /* Performs a power down sequence */
66 int (*power_down)(struct sd *sd);
67}; 68};
68 69
69#endif 70#endif
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 2a901a4a6f00..30132513400c 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -321,6 +321,7 @@ static const struct sd_desc sd_desc = {
321/* -- module initialisation -- */ 321/* -- module initialisation -- */
322static const __devinitdata struct usb_device_id device_table[] = { 322static const __devinitdata struct usb_device_id device_table[] = {
323 {USB_DEVICE(0x08ca, 0x0111)}, 323 {USB_DEVICE(0x08ca, 0x0111)},
324 {USB_DEVICE(0x093a, 0x010f)},
324 {} 325 {}
325}; 326};
326MODULE_DEVICE_TABLE(usb, device_table); 327MODULE_DEVICE_TABLE(usb, device_table);
@@ -347,8 +348,11 @@ static struct usb_driver sd_driver = {
347/* -- module insert / remove -- */ 348/* -- module insert / remove -- */
348static int __init sd_mod_init(void) 349static int __init sd_mod_init(void)
349{ 350{
350 if (usb_register(&sd_driver) < 0) 351 int ret;
351 return -1; 352
353 ret = usb_register(&sd_driver);
354 if (ret < 0)
355 return ret;
352 PDEBUG(D_PROBE, "registered"); 356 PDEBUG(D_PROBE, "registered");
353 return 0; 357 return 0;
354} 358}
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 1fff37b79891..188866ac6cef 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10;
50struct sd { 50struct sd {
51 struct gspca_dev gspca_dev; /* !! must be the first item */ 51 struct gspca_dev gspca_dev; /* !! must be the first item */
52 52
53 char bridge;
54#define BRIDGE_OV511 0
55#define BRIDGE_OV511PLUS 1
56#define BRIDGE_OV518 2
57#define BRIDGE_OV518PLUS 3
58#define BRIDGE_OV519 4
59
53 /* Determined by sensor type */ 60 /* Determined by sensor type */
54 __u8 sif; 61 __u8 sif;
55 62
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 94static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 95static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 96static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
97static void setbrightness(struct gspca_dev *gspca_dev);
98static void setcontrast(struct gspca_dev *gspca_dev);
99static void setcolors(struct gspca_dev *gspca_dev);
90 100
91static struct ctrl sd_ctrls[] = { 101static struct ctrl sd_ctrls[] = {
92 { 102 {
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
164 }, 174 },
165}; 175};
166 176
167static const struct v4l2_pix_format vga_mode[] = { 177static const struct v4l2_pix_format ov519_vga_mode[] = {
168 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 178 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
169 .bytesperline = 320, 179 .bytesperline = 320,
170 .sizeimage = 320 * 240 * 3 / 8 + 590, 180 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = {
176 .colorspace = V4L2_COLORSPACE_JPEG, 186 .colorspace = V4L2_COLORSPACE_JPEG,
177 .priv = 0}, 187 .priv = 0},
178}; 188};
179static const struct v4l2_pix_format sif_mode[] = { 189static const struct v4l2_pix_format ov519_sif_mode[] = {
180 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
181 .bytesperline = 176, 191 .bytesperline = 176,
182 .sizeimage = 176 * 144 * 3 / 8 + 590, 192 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = {
189 .priv = 0}, 199 .priv = 0},
190}; 200};
191 201
202static const struct v4l2_pix_format ov518_vga_mode[] = {
203 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
204 .bytesperline = 320,
205 .sizeimage = 320 * 240 * 3 / 8 + 590,
206 .colorspace = V4L2_COLORSPACE_JPEG,
207 .priv = 1},
208 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
209 .bytesperline = 640,
210 .sizeimage = 640 * 480 * 3 / 8 + 590,
211 .colorspace = V4L2_COLORSPACE_JPEG,
212 .priv = 0},
213};
214static const struct v4l2_pix_format ov518_sif_mode[] = {
215 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
216 .bytesperline = 176,
217 .sizeimage = 40000,
218 .colorspace = V4L2_COLORSPACE_JPEG,
219 .priv = 1},
220 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
221 .bytesperline = 352,
222 .sizeimage = 352 * 288 * 3 / 8 + 590,
223 .colorspace = V4L2_COLORSPACE_JPEG,
224 .priv = 0},
225};
226
227
228/* Registers common to OV511 / OV518 */
229#define R51x_SYS_RESET 0x50
230#define R51x_SYS_INIT 0x53
231#define R51x_SYS_SNAP 0x52
232#define R51x_SYS_CUST_ID 0x5F
233#define R51x_COMP_LUT_BEGIN 0x80
234
235/* OV511 Camera interface register numbers */
236#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
237#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
238
239/* OV518 Camera interface register numbers */
240#define R518_GPIO_OUT 0x56 /* OV518(+) only */
241#define R518_GPIO_CTL 0x57 /* OV518(+) only */
242
192/* OV519 Camera interface register numbers */ 243/* OV519 Camera interface register numbers */
193#define OV519_R10_H_SIZE 0x10 244#define OV519_R10_H_SIZE 0x10
194#define OV519_R11_V_SIZE 0x11 245#define OV519_R11_V_SIZE 0x11
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = {
224 275
225/* OV7610 registers */ 276/* OV7610 registers */
226#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ 277#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
278#define OV7610_REG_BLUE 0x01 /* blue channel balance */
279#define OV7610_REG_RED 0x02 /* red channel balance */
227#define OV7610_REG_SAT 0x03 /* saturation */ 280#define OV7610_REG_SAT 0x03 /* saturation */
228#define OV8610_REG_HUE 0x04 /* 04 reserved */ 281#define OV8610_REG_HUE 0x04 /* 04 reserved */
229#define OV7610_REG_CNT 0x05 /* Y contrast */ 282#define OV7610_REG_CNT 0x05 /* Y contrast */
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
846static int reg_w(struct sd *sd, __u16 index, __u8 value) 899static int reg_w(struct sd *sd, __u16 index, __u8 value)
847{ 900{
848 int ret; 901 int ret;
902 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1;
849 903
850 sd->gspca_dev.usb_buf[0] = value; 904 sd->gspca_dev.usb_buf[0] = value;
851 ret = usb_control_msg(sd->gspca_dev.dev, 905 ret = usb_control_msg(sd->gspca_dev.dev,
852 usb_sndctrlpipe(sd->gspca_dev.dev, 0), 906 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
853 1, /* REQ_IO (ov518/519) */ 907 req,
854 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 908 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
855 0, index, 909 0, index,
856 sd->gspca_dev.usb_buf, 1, 500); 910 sd->gspca_dev.usb_buf, 1, 500);
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
864static int reg_r(struct sd *sd, __u16 index) 918static int reg_r(struct sd *sd, __u16 index)
865{ 919{
866 int ret; 920 int ret;
921 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1;
867 922
868 ret = usb_control_msg(sd->gspca_dev.dev, 923 ret = usb_control_msg(sd->gspca_dev.dev,
869 usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 924 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
870 1, /* REQ_IO */ 925 req,
871 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 926 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
872 0, index, sd->gspca_dev.usb_buf, 1, 500); 927 0, index, sd->gspca_dev.usb_buf, 1, 500);
873 928
@@ -924,6 +979,28 @@ static int reg_w_mask(struct sd *sd,
924} 979}
925 980
926/* 981/*
982 * Writes multiple (n) byte value to a single register. Only valid with certain
983 * registers (0x30 and 0xc4 - 0xce).
984 */
985static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
986{
987 int ret;
988
989 *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
990
991 ret = usb_control_msg(sd->gspca_dev.dev,
992 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
993 1 /* REG_IO */,
994 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
995 0, index,
996 sd->gspca_dev.usb_buf, n, 500);
997 if (ret < 0)
998 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
999 return ret;
1000}
1001
1002
1003/*
927 * The OV518 I2C I/O procedure is different, hence, this function. 1004 * The OV518 I2C I/O procedure is different, hence, this function.
928 * This is normally only called from i2c_w(). Note that this function 1005 * This is normally only called from i2c_w(). Note that this function
929 * always succeeds regardless of whether the sensor is present and working. 1006 * always succeeds regardless of whether the sensor is present and working.
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd)
1014{ 1091{
1015 PDEBUG(D_STREAM, "stopping"); 1092 PDEBUG(D_STREAM, "stopping");
1016 sd->stopped = 1; 1093 sd->stopped = 1;
1017 return reg_w(sd, OV519_SYS_RESET1, 0x0f); 1094 switch (sd->bridge) {
1095 case BRIDGE_OV511:
1096 case BRIDGE_OV511PLUS:
1097 return reg_w(sd, R51x_SYS_RESET, 0x3d);
1098 case BRIDGE_OV518:
1099 case BRIDGE_OV518PLUS:
1100 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
1101 case BRIDGE_OV519:
1102 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
1103 }
1104
1105 return 0;
1018} 1106}
1019 1107
1020/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not 1108/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
1021 * actually stopped (for performance). */ 1109 * actually stopped (for performance). */
1022static inline int ov51x_restart(struct sd *sd) 1110static inline int ov51x_restart(struct sd *sd)
1023{ 1111{
1112 int rc;
1113
1024 PDEBUG(D_STREAM, "restarting"); 1114 PDEBUG(D_STREAM, "restarting");
1025 if (!sd->stopped) 1115 if (!sd->stopped)
1026 return 0; 1116 return 0;
1027 sd->stopped = 0; 1117 sd->stopped = 0;
1028 1118
1029 /* Reinitialize the stream */ 1119 /* Reinitialize the stream */
1030 return reg_w(sd, OV519_SYS_RESET1, 0x00); 1120 switch (sd->bridge) {
1121 case BRIDGE_OV511:
1122 case BRIDGE_OV511PLUS:
1123 return reg_w(sd, R51x_SYS_RESET, 0x00);
1124 case BRIDGE_OV518:
1125 case BRIDGE_OV518PLUS:
1126 rc = reg_w(sd, 0x2f, 0x80);
1127 if (rc < 0)
1128 return rc;
1129 return reg_w(sd, R51x_SYS_RESET, 0x00);
1130 case BRIDGE_OV519:
1131 return reg_w(sd, OV519_SYS_RESET1, 0x00);
1132 }
1133
1134 return 0;
1031} 1135}
1032 1136
1033/* This does an initial reset of an OmniVision sensor and ensures that I2C 1137/* This does an initial reset of an OmniVision sensor and ensures that I2C
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd)
1287/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1391/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1288static void ov51x_led_control(struct sd *sd, int on) 1392static void ov51x_led_control(struct sd *sd, int on)
1289{ 1393{
1290 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ 1394 switch (sd->bridge) {
1395 /* OV511 has no LED control */
1396 case BRIDGE_OV511PLUS:
1397 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
1398 break;
1399 case BRIDGE_OV518:
1400 case BRIDGE_OV518PLUS:
1401 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
1402 break;
1403 case BRIDGE_OV519:
1404 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1405 break;
1406 }
1291} 1407}
1292 1408
1293/* this function is called at probe time */ 1409/* OV518 quantization tables are 8x4 (instead of 8x8) */
1294static int sd_config(struct gspca_dev *gspca_dev, 1410static int ov518_upload_quan_tables(struct sd *sd)
1295 const struct usb_device_id *id) 1411{
1412 const unsigned char yQuanTable518[] = {
1413 5, 4, 5, 6, 6, 7, 7, 7,
1414 5, 5, 5, 5, 6, 7, 7, 7,
1415 6, 6, 6, 6, 7, 7, 7, 8,
1416 7, 7, 6, 7, 7, 7, 8, 8
1417 };
1418
1419 const unsigned char uvQuanTable518[] = {
1420 6, 6, 6, 7, 7, 7, 7, 7,
1421 6, 6, 6, 7, 7, 7, 7, 7,
1422 6, 6, 6, 7, 7, 7, 7, 8,
1423 7, 7, 7, 7, 7, 7, 8, 8
1424 };
1425
1426 const unsigned char *pYTable = yQuanTable518;
1427 const unsigned char *pUVTable = uvQuanTable518;
1428 unsigned char val0, val1;
1429 int i, rc, reg = R51x_COMP_LUT_BEGIN;
1430
1431 PDEBUG(D_PROBE, "Uploading quantization tables");
1432
1433 for (i = 0; i < 16; i++) {
1434 val0 = *pYTable++;
1435 val1 = *pYTable++;
1436 val0 &= 0x0f;
1437 val1 &= 0x0f;
1438 val0 |= val1 << 4;
1439 rc = reg_w(sd, reg, val0);
1440 if (rc < 0)
1441 return rc;
1442
1443 val0 = *pUVTable++;
1444 val1 = *pUVTable++;
1445 val0 &= 0x0f;
1446 val1 &= 0x0f;
1447 val0 |= val1 << 4;
1448 rc = reg_w(sd, reg + 16, val0);
1449 if (rc < 0)
1450 return rc;
1451
1452 reg++;
1453 }
1454
1455 return 0;
1456}
1457
1458/* This initializes the OV518/OV518+ and the sensor */
1459static int ov518_configure(struct gspca_dev *gspca_dev)
1296{ 1460{
1297 struct sd *sd = (struct sd *) gspca_dev; 1461 struct sd *sd = (struct sd *) gspca_dev;
1298 struct cam *cam; 1462 int rc;
1463
1464 /* For 518 and 518+ */
1465 static struct ov_regvals init_518[] = {
1466 { R51x_SYS_RESET, 0x40 },
1467 { R51x_SYS_INIT, 0xe1 },
1468 { R51x_SYS_RESET, 0x3e },
1469 { R51x_SYS_INIT, 0xe1 },
1470 { R51x_SYS_RESET, 0x00 },
1471 { R51x_SYS_INIT, 0xe1 },
1472 { 0x46, 0x00 },
1473 { 0x5d, 0x03 },
1474 };
1475
1476 static struct ov_regvals norm_518[] = {
1477 { R51x_SYS_SNAP, 0x02 }, /* Reset */
1478 { R51x_SYS_SNAP, 0x01 }, /* Enable */
1479 { 0x31, 0x0f },
1480 { 0x5d, 0x03 },
1481 { 0x24, 0x9f },
1482 { 0x25, 0x90 },
1483 { 0x20, 0x00 },
1484 { 0x51, 0x04 },
1485 { 0x71, 0x19 },
1486 { 0x2f, 0x80 },
1487 };
1488
1489 static struct ov_regvals norm_518_p[] = {
1490 { R51x_SYS_SNAP, 0x02 }, /* Reset */
1491 { R51x_SYS_SNAP, 0x01 }, /* Enable */
1492 { 0x31, 0x0f },
1493 { 0x5d, 0x03 },
1494 { 0x24, 0x9f },
1495 { 0x25, 0x90 },
1496 { 0x20, 0x60 },
1497 { 0x51, 0x02 },
1498 { 0x71, 0x19 },
1499 { 0x40, 0xff },
1500 { 0x41, 0x42 },
1501 { 0x46, 0x00 },
1502 { 0x33, 0x04 },
1503 { 0x21, 0x19 },
1504 { 0x3f, 0x10 },
1505 { 0x2f, 0x80 },
1506 };
1507
1508 /* First 5 bits of custom ID reg are a revision ID on OV518 */
1509 PDEBUG(D_PROBE, "Device revision %d",
1510 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
1511
1512 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
1513 if (rc < 0)
1514 return rc;
1515
1516 /* Set LED GPIO pin to output mode */
1517 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
1518 if (rc < 0)
1519 return rc;
1299 1520
1521 switch (sd->bridge) {
1522 case BRIDGE_OV518:
1523 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
1524 if (rc < 0)
1525 return rc;
1526 break;
1527 case BRIDGE_OV518PLUS:
1528 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
1529 if (rc < 0)
1530 return rc;
1531 break;
1532 }
1533
1534 rc = ov518_upload_quan_tables(sd);
1535 if (rc < 0) {
1536 PDEBUG(D_ERR, "Error uploading quantization tables");
1537 return rc;
1538 }
1539
1540 rc = reg_w(sd, 0x2f, 0x80);
1541 if (rc < 0)
1542 return rc;
1543
1544 return 0;
1545}
1546
1547static int ov519_configure(struct sd *sd)
1548{
1300 static const struct ov_regvals init_519[] = { 1549 static const struct ov_regvals init_519[] = {
1301 { 0x5a, 0x6d }, /* EnableSystem */ 1550 { 0x5a, 0x6d }, /* EnableSystem */
1302 { 0x53, 0x9b }, 1551 { 0x53, 0x9b },
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
1313 /* windows reads 0x55 at this point*/ 1562 /* windows reads 0x55 at this point*/
1314 }; 1563 };
1315 1564
1316 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) 1565 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
1566}
1567
1568/* this function is called at probe time */
1569static int sd_config(struct gspca_dev *gspca_dev,
1570 const struct usb_device_id *id)
1571{
1572 struct sd *sd = (struct sd *) gspca_dev;
1573 struct cam *cam;
1574 int ret = 0;
1575
1576 sd->bridge = id->driver_info;
1577
1578 switch (sd->bridge) {
1579 case BRIDGE_OV518:
1580 case BRIDGE_OV518PLUS:
1581 ret = ov518_configure(gspca_dev);
1582 break;
1583 case BRIDGE_OV519:
1584 ret = ov519_configure(sd);
1585 break;
1586 }
1587
1588 if (ret)
1317 goto error; 1589 goto error;
1590
1318 ov51x_led_control(sd, 0); /* turn LED off */ 1591 ov51x_led_control(sd, 0); /* turn LED off */
1319 1592
1320 /* Test for 76xx */ 1593 /* Test for 76xx */
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev,
1360 } 1633 }
1361 1634
1362 cam = &gspca_dev->cam; 1635 cam = &gspca_dev->cam;
1363 if (!sd->sif) { 1636 switch (sd->bridge) {
1364 cam->cam_mode = vga_mode; 1637 case BRIDGE_OV518:
1365 cam->nmodes = ARRAY_SIZE(vga_mode); 1638 case BRIDGE_OV518PLUS:
1366 } else { 1639 if (!sd->sif) {
1367 cam->cam_mode = sif_mode; 1640 cam->cam_mode = ov518_vga_mode;
1368 cam->nmodes = ARRAY_SIZE(sif_mode); 1641 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
1642 } else {
1643 cam->cam_mode = ov518_sif_mode;
1644 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
1645 }
1646 break;
1647 case BRIDGE_OV519:
1648 if (!sd->sif) {
1649 cam->cam_mode = ov519_vga_mode;
1650 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
1651 } else {
1652 cam->cam_mode = ov519_sif_mode;
1653 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
1654 }
1655 break;
1369 } 1656 }
1370 sd->brightness = BRIGHTNESS_DEF; 1657 sd->brightness = BRIGHTNESS_DEF;
1371 sd->contrast = CONTRAST_DEF; 1658 sd->contrast = CONTRAST_DEF;
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev)
1422 return 0; 1709 return 0;
1423} 1710}
1424 1711
1712/* Sets up the OV518/OV518+ with the given image parameters
1713 *
1714 * OV518 needs a completely different approach, until we can figure out what
1715 * the individual registers do. Also, only 15 FPS is supported now.
1716 *
1717 * Do not put any sensor-specific code in here (including I2C I/O functions)
1718 */
1719static int ov518_mode_init_regs(struct sd *sd)
1720{
1721 int hsegs, vsegs;
1722
1723 /******** Set the mode ********/
1724
1725 reg_w(sd, 0x2b, 0);
1726 reg_w(sd, 0x2c, 0);
1727 reg_w(sd, 0x2d, 0);
1728 reg_w(sd, 0x2e, 0);
1729 reg_w(sd, 0x3b, 0);
1730 reg_w(sd, 0x3c, 0);
1731 reg_w(sd, 0x3d, 0);
1732 reg_w(sd, 0x3e, 0);
1733
1734 if (sd->bridge == BRIDGE_OV518) {
1735 /* Set 8-bit (YVYU) input format */
1736 reg_w_mask(sd, 0x20, 0x08, 0x08);
1737
1738 /* Set 12-bit (4:2:0) output format */
1739 reg_w_mask(sd, 0x28, 0x80, 0xf0);
1740 reg_w_mask(sd, 0x38, 0x80, 0xf0);
1741 } else {
1742 reg_w(sd, 0x28, 0x80);
1743 reg_w(sd, 0x38, 0x80);
1744 }
1745
1746 hsegs = sd->gspca_dev.width / 16;
1747 vsegs = sd->gspca_dev.height / 4;
1748
1749 reg_w(sd, 0x29, hsegs);
1750 reg_w(sd, 0x2a, vsegs);
1751
1752 reg_w(sd, 0x39, hsegs);
1753 reg_w(sd, 0x3a, vsegs);
1754
1755 /* Windows driver does this here; who knows why */
1756 reg_w(sd, 0x2f, 0x80);
1757
1758 /******** Set the framerate (to 30 FPS) ********/
1759 if (sd->bridge == BRIDGE_OV518PLUS)
1760 sd->clockdiv = 1;
1761 else
1762 sd->clockdiv = 0;
1763
1764 /* Mode independent, but framerate dependent, regs */
1765 reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */
1766 reg_w(sd, 0x22, 0x18);
1767 reg_w(sd, 0x23, 0xff);
1768
1769 if (sd->bridge == BRIDGE_OV518PLUS)
1770 reg_w(sd, 0x21, 0x19);
1771 else
1772 reg_w(sd, 0x71, 0x17); /* Compression-related? */
1773
1774 /* FIXME: Sensor-specific */
1775 /* Bit 5 is what matters here. Of course, it is "reserved" */
1776 i2c_w(sd, 0x54, 0x23);
1777
1778 reg_w(sd, 0x2f, 0x80);
1779
1780 if (sd->bridge == BRIDGE_OV518PLUS) {
1781 reg_w(sd, 0x24, 0x94);
1782 reg_w(sd, 0x25, 0x90);
1783 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
1784 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
1785 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
1786 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
1787 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
1788 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
1789 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
1790 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
1791 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
1792 } else {
1793 reg_w(sd, 0x24, 0x9f);
1794 reg_w(sd, 0x25, 0x90);
1795 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
1796 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
1797 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
1798 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
1799 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
1800 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
1801 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
1802 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
1803 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
1804 }
1805
1806 reg_w(sd, 0x2f, 0x80);
1807
1808 return 0;
1809}
1810
1811
1425/* Sets up the OV519 with the given image parameters 1812/* Sets up the OV519 with the given image parameters
1426 * 1813 *
1427 * OV519 needs a completely different approach, until we can figure out what 1814 * OV519 needs a completely different approach, until we can figure out what
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd)
1740 hwebase = 0x3a; 2127 hwebase = 0x3a;
1741 vwsbase = 0x05; 2128 vwsbase = 0x05;
1742 vwebase = 0x06; 2129 vwebase = 0x06;
2130 if (qvga) {
2131 /* HDG: this fixes U and V getting swapped */
2132 hwsbase--;
2133 vwsbase--;
2134 }
1743 break; 2135 break;
1744 case SEN_OV7620: 2136 case SEN_OV7620:
1745 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ 2137 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd)
1855static int sd_start(struct gspca_dev *gspca_dev) 2247static int sd_start(struct gspca_dev *gspca_dev)
1856{ 2248{
1857 struct sd *sd = (struct sd *) gspca_dev; 2249 struct sd *sd = (struct sd *) gspca_dev;
1858 int ret; 2250 int ret = 0;
1859 2251
1860 ret = ov519_mode_init_regs(sd); 2252 switch (sd->bridge) {
2253 case BRIDGE_OV518:
2254 case BRIDGE_OV518PLUS:
2255 ret = ov518_mode_init_regs(sd);
2256 break;
2257 case BRIDGE_OV519:
2258 ret = ov519_mode_init_regs(sd);
2259 break;
2260 }
1861 if (ret < 0) 2261 if (ret < 0)
1862 goto out; 2262 goto out;
2263
1863 ret = set_ov_sensor_window(sd); 2264 ret = set_ov_sensor_window(sd);
1864 if (ret < 0) 2265 if (ret < 0)
1865 goto out; 2266 goto out;
1866 2267
2268 setcontrast(gspca_dev);
2269 setbrightness(gspca_dev);
2270 setcolors(gspca_dev);
2271
1867 ret = ov51x_restart(sd); 2272 ret = ov51x_restart(sd);
1868 if (ret < 0) 2273 if (ret < 0)
1869 goto out; 2274 goto out;
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1882 ov51x_led_control(sd, 0); 2287 ov51x_led_control(sd, 0);
1883} 2288}
1884 2289
1885static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2290static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2291 struct gspca_frame *frame, /* target */
2292 __u8 *data, /* isoc packet */
2293 int len) /* iso packet length */
2294{
2295 PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len);
2296
2297 if (len & 7) {
2298 len--;
2299 PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]);
2300 }
2301
2302 /* A false positive here is likely, until OVT gives me
2303 * the definitive SOF/EOF format */
2304 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
2305 gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
2306 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
2307 }
2308
2309 /* intermediate packet */
2310 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
2311}
2312
2313static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
1886 struct gspca_frame *frame, /* target */ 2314 struct gspca_frame *frame, /* target */
1887 __u8 *data, /* isoc packet */ 2315 __u8 *data, /* isoc packet */
1888 int len) /* iso packet length */ 2316 int len) /* iso packet length */
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1926 data, len); 2354 data, len);
1927} 2355}
1928 2356
2357static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2358 struct gspca_frame *frame, /* target */
2359 __u8 *data, /* isoc packet */
2360 int len) /* iso packet length */
2361{
2362 struct sd *sd = (struct sd *) gspca_dev;
2363
2364 switch (sd->bridge) {
2365 case BRIDGE_OV511:
2366 case BRIDGE_OV511PLUS:
2367 break;
2368 case BRIDGE_OV518:
2369 case BRIDGE_OV518PLUS:
2370 ov518_pkt_scan(gspca_dev, frame, data, len);
2371 break;
2372 case BRIDGE_OV519:
2373 ov519_pkt_scan(gspca_dev, frame, data, len);
2374 break;
2375 }
2376}
2377
1929/* -- management routines -- */ 2378/* -- management routines -- */
1930 2379
1931static void setbrightness(struct gspca_dev *gspca_dev) 2380static void setbrightness(struct gspca_dev *gspca_dev)
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1970 break; 2419 break;
1971 case SEN_OV6630: 2420 case SEN_OV6630:
1972 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); 2421 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
2422 break;
1973 case SEN_OV8610: { 2423 case SEN_OV8610: {
1974 static const __u8 ctab[] = { 2424 static const __u8 ctab[] = {
1975 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f 2425 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = {
2136 2586
2137/* -- module initialisation -- */ 2587/* -- module initialisation -- */
2138static const __devinitdata struct usb_device_id device_table[] = { 2588static const __devinitdata struct usb_device_id device_table[] = {
2139 {USB_DEVICE(0x041e, 0x4052)}, 2589 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
2140 {USB_DEVICE(0x041e, 0x405f)}, 2590 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
2141 {USB_DEVICE(0x041e, 0x4060)}, 2591 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
2142 {USB_DEVICE(0x041e, 0x4061)}, 2592 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
2143 {USB_DEVICE(0x041e, 0x4064)}, 2593 {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
2144 {USB_DEVICE(0x041e, 0x4068)}, 2594 {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
2145 {USB_DEVICE(0x045e, 0x028c)}, 2595 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
2146 {USB_DEVICE(0x054c, 0x0154)}, 2596 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
2147 {USB_DEVICE(0x054c, 0x0155)}, 2597 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
2148 {USB_DEVICE(0x05a9, 0x0519)}, 2598 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
2149 {USB_DEVICE(0x05a9, 0x0530)}, 2599 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
2150 {USB_DEVICE(0x05a9, 0x4519)}, 2600 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
2151 {USB_DEVICE(0x05a9, 0x8519)}, 2601 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
2602 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
2603 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
2152 {} 2604 {}
2153}; 2605};
2154 2606
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 19e0bc60de14..4b528b372911 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -60,10 +60,23 @@ struct sd {
60static struct ctrl sd_ctrls[] = { 60static struct ctrl sd_ctrls[] = {
61}; 61};
62 62
63static const struct v4l2_pix_format vga_mode[] = { 63static const struct v4l2_pix_format vga_yuyv_mode[] = {
64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
65 .bytesperline = 640 * 2, 65 .bytesperline = 640 * 2,
66 .sizeimage = 640 * 480 * 2, 66 .sizeimage = 640 * 480 * 2,
67 .colorspace = V4L2_COLORSPACE_SRGB,
68 .priv = 0},
69};
70
71static const struct v4l2_pix_format vga_jpeg_mode[] = {
72 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
73 .bytesperline = 320,
74 .sizeimage = 320 * 240 * 3 / 8 + 590,
75 .colorspace = V4L2_COLORSPACE_JPEG,
76 .priv = 1},
77 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
78 .bytesperline = 640,
79 .sizeimage = 640 * 480 * 3 / 8 + 590,
67 .colorspace = V4L2_COLORSPACE_JPEG, 80 .colorspace = V4L2_COLORSPACE_JPEG,
68 .priv = 0}, 81 .priv = 0},
69}; 82};
@@ -244,7 +257,7 @@ static const u8 bridge_init_ov965x[][2] = {
244}; 257};
245 258
246static const u8 sensor_init_ov965x[][2] = { 259static const u8 sensor_init_ov965x[][2] = {
247 {0x12, 0x80}, /* com7 - reset */ 260 {0x12, 0x80}, /* com7 - SSCB reset */
248 {0x00, 0x00}, /* gain */ 261 {0x00, 0x00}, /* gain */
249 {0x01, 0x80}, /* blue */ 262 {0x01, 0x80}, /* blue */
250 {0x02, 0x80}, /* red */ 263 {0x02, 0x80}, /* red */
@@ -254,10 +267,10 @@ static const u8 sensor_init_ov965x[][2] = {
254 {0x0e, 0x61}, /* com5 */ 267 {0x0e, 0x61}, /* com5 */
255 {0x0f, 0x42}, /* com6 */ 268 {0x0f, 0x42}, /* com6 */
256 {0x11, 0x00}, /* clkrc */ 269 {0x11, 0x00}, /* clkrc */
257 {0x12, 0x02}, /* com7 */ 270 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
258 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 271 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
259 {0x14, 0x28}, /* com9 */ 272 {0x14, 0x28}, /* com9 */
260 {0x16, 0x24}, /* rsvd16 */ 273 {0x16, 0x24}, /* reg16 */
261 {0x17, 0x1d}, /* hstart*/ 274 {0x17, 0x1d}, /* hstart*/
262 {0x18, 0xbd}, /* hstop */ 275 {0x18, 0xbd}, /* hstop */
263 {0x19, 0x01}, /* vstrt */ 276 {0x19, 0x01}, /* vstrt */
@@ -269,24 +282,24 @@ static const u8 sensor_init_ov965x[][2] = {
269 {0x27, 0x08}, /* bbias */ 282 {0x27, 0x08}, /* bbias */
270 {0x28, 0x08}, /* gbbias */ 283 {0x28, 0x08}, /* gbbias */
271 {0x29, 0x15}, /* gr com */ 284 {0x29, 0x15}, /* gr com */
272 {0x2a, 0x00}, 285 {0x2a, 0x00}, /* exhch */
273 {0x2b, 0x00}, 286 {0x2b, 0x00}, /* exhcl */
274 {0x2c, 0x08}, /* rbias */ 287 {0x2c, 0x08}, /* rbias */
275 {0x32, 0xff}, /* href */ 288 {0x32, 0xff}, /* href */
276 {0x33, 0x00}, /* chlf */ 289 {0x33, 0x00}, /* chlf */
277 {0x34, 0x3f}, /* arblm */ 290 {0x34, 0x3f}, /* aref1 */
278 {0x35, 0x00}, /* rsvd35 */ 291 {0x35, 0x00}, /* aref2 */
279 {0x36, 0xf8}, /* rsvd36 */ 292 {0x36, 0xf8}, /* aref3 */
280 {0x38, 0x72}, /* acom38 */ 293 {0x38, 0x72}, /* adc2 */
281 {0x39, 0x57}, /* ofon */ 294 {0x39, 0x57}, /* aref4 */
282 {0x3a, 0x80}, /* tslb */ 295 {0x3a, 0x80}, /* tslb - yuyv */
283 {0x3b, 0xc4}, 296 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
284 {0x3d, 0x99}, /* com13 */ 297 {0x3d, 0x99}, /* com13 */
285 {0x3f, 0xc1}, 298 {0x3f, 0xc1}, /* edge */
286 {0x40, 0xc0}, /* com15 */ 299 {0x40, 0xc0}, /* com15 */
287 {0x41, 0x40}, /* com16 */ 300 {0x41, 0x40}, /* com16 */
288 {0x42, 0xc0}, 301 {0x42, 0xc0}, /* com17 */
289 {0x43, 0x0a}, 302 {0x43, 0x0a}, /* rsvd */
290 {0x44, 0xf0}, 303 {0x44, 0xf0},
291 {0x45, 0x46}, 304 {0x45, 0x46},
292 {0x46, 0x62}, 305 {0x46, 0x62},
@@ -297,22 +310,22 @@ static const u8 sensor_init_ov965x[][2] = {
297 {0x4c, 0x7f}, 310 {0x4c, 0x7f},
298 {0x4d, 0x7f}, 311 {0x4d, 0x7f},
299 {0x4e, 0x7f}, 312 {0x4e, 0x7f},
300 {0x4f, 0x98}, 313 {0x4f, 0x98}, /* matrix */
301 {0x50, 0x98}, 314 {0x50, 0x98},
302 {0x51, 0x00}, 315 {0x51, 0x00},
303 {0x52, 0x28}, 316 {0x52, 0x28},
304 {0x53, 0x70}, 317 {0x53, 0x70},
305 {0x54, 0x98}, 318 {0x54, 0x98},
306 {0x58, 0x1a}, 319 {0x58, 0x1a}, /* matrix coef sign */
307 {0x59, 0x85}, 320 {0x59, 0x85}, /* AWB control */
308 {0x5a, 0xa9}, 321 {0x5a, 0xa9},
309 {0x5b, 0x64}, 322 {0x5b, 0x64},
310 {0x5c, 0x84}, 323 {0x5c, 0x84},
311 {0x5d, 0x53}, 324 {0x5d, 0x53},
312 {0x5e, 0x0e}, 325 {0x5e, 0x0e},
313 {0x5f, 0xf0}, 326 {0x5f, 0xf0}, /* AWB blue limit */
314 {0x60, 0xf0}, 327 {0x60, 0xf0}, /* AWB red limit */
315 {0x61, 0xf0}, 328 {0x61, 0xf0}, /* AWB green limit */
316 {0x62, 0x00}, /* lcc1 */ 329 {0x62, 0x00}, /* lcc1 */
317 {0x63, 0x00}, /* lcc2 */ 330 {0x63, 0x00}, /* lcc2 */
318 {0x64, 0x02}, /* lcc3 */ 331 {0x64, 0x02}, /* lcc3 */
@@ -324,15 +337,15 @@ static const u8 sensor_init_ov965x[][2] = {
324 {0x6d, 0x55}, 337 {0x6d, 0x55},
325 {0x6e, 0x00}, 338 {0x6e, 0x00},
326 {0x6f, 0x9d}, 339 {0x6f, 0x9d},
327 {0x70, 0x21}, 340 {0x70, 0x21}, /* dnsth */
328 {0x71, 0x78}, 341 {0x71, 0x78},
329 {0x72, 0x00}, 342 {0x72, 0x00}, /* poidx */
330 {0x73, 0x01}, 343 {0x73, 0x01}, /* pckdv */
331 {0x74, 0x3a}, 344 {0x74, 0x3a}, /* xindx */
332 {0x75, 0x35}, 345 {0x75, 0x35}, /* yindx */
333 {0x76, 0x01}, 346 {0x76, 0x01},
334 {0x77, 0x02}, 347 {0x77, 0x02},
335 {0x7a, 0x12}, 348 {0x7a, 0x12}, /* gamma curve */
336 {0x7b, 0x08}, 349 {0x7b, 0x08},
337 {0x7c, 0x16}, 350 {0x7c, 0x16},
338 {0x7d, 0x30}, 351 {0x7d, 0x30},
@@ -349,33 +362,33 @@ static const u8 sensor_init_ov965x[][2] = {
349 {0x88, 0xe6}, 362 {0x88, 0xe6},
350 {0x89, 0xf2}, 363 {0x89, 0xf2},
351 {0x8a, 0x03}, 364 {0x8a, 0x03},
352 {0x8c, 0x89}, 365 {0x8c, 0x89}, /* com19 */
353 {0x14, 0x28}, /* com9 */ 366 {0x14, 0x28}, /* com9 */
354 {0x90, 0x7d}, 367 {0x90, 0x7d},
355 {0x91, 0x7b}, 368 {0x91, 0x7b},
356 {0x9d, 0x03}, 369 {0x9d, 0x03}, /* lcc6 */
357 {0x9e, 0x04}, 370 {0x9e, 0x04}, /* lcc7 */
358 {0x9f, 0x7a}, 371 {0x9f, 0x7a},
359 {0xa0, 0x79}, 372 {0xa0, 0x79},
360 {0xa1, 0x40}, /* aechm */ 373 {0xa1, 0x40}, /* aechm */
361 {0xa4, 0x50}, 374 {0xa4, 0x50}, /* com21 */
362 {0xa5, 0x68}, /* com26 */ 375 {0xa5, 0x68}, /* com26 */
363 {0xa6, 0x4a}, 376 {0xa6, 0x4a}, /* AWB green */
364 {0xa8, 0xc1}, /* acoma8 */ 377 {0xa8, 0xc1}, /* refa8 */
365 {0xa9, 0xef}, /* acoma9 */ 378 {0xa9, 0xef}, /* refa9 */
366 {0xaa, 0x92}, 379 {0xaa, 0x92},
367 {0xab, 0x04}, 380 {0xab, 0x04},
368 {0xac, 0x80}, 381 {0xac, 0x80}, /* black level control */
369 {0xad, 0x80}, 382 {0xad, 0x80},
370 {0xae, 0x80}, 383 {0xae, 0x80},
371 {0xaf, 0x80}, 384 {0xaf, 0x80},
372 {0xb2, 0xf2}, 385 {0xb2, 0xf2},
373 {0xb3, 0x20}, 386 {0xb3, 0x20},
374 {0xb4, 0x20}, 387 {0xb4, 0x20}, /* ctrlb4 */
375 {0xb5, 0x00}, 388 {0xb5, 0x00},
376 {0xb6, 0xaf}, 389 {0xb6, 0xaf},
377 {0xbb, 0xae}, 390 {0xbb, 0xae},
378 {0xbc, 0x7f}, 391 {0xbc, 0x7f}, /* ADC channel offsets */
379 {0xdb, 0x7f}, 392 {0xdb, 0x7f},
380 {0xbe, 0x7f}, 393 {0xbe, 0x7f},
381 {0xbf, 0x7f}, 394 {0xbf, 0x7f},
@@ -384,7 +397,7 @@ static const u8 sensor_init_ov965x[][2] = {
384 {0xc2, 0x01}, 397 {0xc2, 0x01},
385 {0xc3, 0x4e}, 398 {0xc3, 0x4e},
386 {0xc6, 0x85}, 399 {0xc6, 0x85},
387 {0xc7, 0x80}, 400 {0xc7, 0x80}, /* com24 */
388 {0xc9, 0xe0}, 401 {0xc9, 0xe0},
389 {0xca, 0xe8}, 402 {0xca, 0xe8},
390 {0xcb, 0xf0}, 403 {0xcb, 0xf0},
@@ -399,11 +412,11 @@ static const u8 sensor_init_ov965x[][2] = {
399 {0x58, 0x1a}, 412 {0x58, 0x1a},
400 {0xff, 0x41}, /* read 41, write ff 00 */ 413 {0xff, 0x41}, /* read 41, write ff 00 */
401 {0x41, 0x40}, /* com16 */ 414 {0x41, 0x40}, /* com16 */
402 {0xc5, 0x03}, 415 {0xc5, 0x03}, /* 60 Hz banding filter */
403 {0x6a, 0x02}, 416 {0x6a, 0x02}, /* 50 Hz banding filter */
404 417
405 {0x12, 0x62}, /* com7 - VGA + CIF */ 418 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
406 {0x36, 0xfa}, /* rsvd36 */ 419 {0x36, 0xfa}, /* aref3 */
407 {0x69, 0x0a}, /* hv */ 420 {0x69, 0x0a}, /* hv */
408 {0x8c, 0x89}, /* com22 */ 421 {0x8c, 0x89}, /* com22 */
409 {0x14, 0x28}, /* com9 */ 422 {0x14, 0x28}, /* com9 */
@@ -442,8 +455,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
442 {0x52, 0x3c}, 455 {0x52, 0x3c},
443 {0x53, 0x00}, 456 {0x53, 0x00},
444 {0x54, 0x00}, 457 {0x54, 0x00},
445 {0x55, 0x00}, 458 {0x55, 0x00}, /* brightness */
446 {0x57, 0x00}, 459 {0x57, 0x00}, /* contrast 2 */
447 {0x5c, 0x00}, 460 {0x5c, 0x00},
448 {0x5a, 0xa0}, 461 {0x5a, 0xa0},
449 {0x5b, 0x78}, 462 {0x5b, 0x78},
@@ -489,9 +502,66 @@ static const u8 sensor_init_ov965x_2[][2] = {
489 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 502 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
490}; 503};
491 504
505static const u8 sensor_start_ov965x[][2] = {
506 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
507 {0x36, 0xfa}, /* aref3 */
508 {0x69, 0x0a}, /* hv */
509 {0x8c, 0x89}, /* com22 */
510 {0x14, 0x28}, /* com9 */
511 {0x3e, 0x0c}, /* com14 */
512 {0x41, 0x40}, /* com16 */
513 {0x72, 0x00},
514 {0x73, 0x00},
515 {0x74, 0x3a},
516 {0x75, 0x35},
517 {0x76, 0x01},
518 {0xc7, 0x80}, /* com24 */
519 {0x03, 0x12}, /* vref */
520 {0x17, 0x16}, /* hstart */
521 {0x18, 0x02}, /* hstop */
522 {0x19, 0x01}, /* vstrt */
523 {0x1a, 0x3d}, /* vstop */
524 {0x32, 0xff}, /* href */
525 {0xc0, 0xaa},
526 {}
527};
528
492static const u8 bridge_start_ov965x[][2] = { 529static const u8 bridge_start_ov965x[][2] = {
530 {0x94, 0xaa},
531 {0xf1, 0x60},
532 {0xe5, 0x04},
533 {0xc0, 0x50},
534 {0xc1, 0x3c},
535 {0x8c, 0x00},
536 {0x8d, 0x1c},
537 {0x34, 0x05},
538 {}
539};
540
541static const u8 bridge_start_ov965x_vga[][2] = {
542 {0xc2, 0x0c},
543 {0xc3, 0xf9},
544 {0xda, 0x01},
545 {0x50, 0x00},
546 {0x51, 0xa0},
547 {0x52, 0x3c},
548 {0x53, 0x00},
549 {0x54, 0x00},
550 {0x55, 0x00},
551 {0x57, 0x00},
552 {0x5c, 0x00},
553 {0x5a, 0xa0},
554 {0x5b, 0x78},
555 {0x35, 0x02},
556 {0xd9, 0x10},
557 {0x94, 0x11},
558 {}
559};
560
561static const u8 bridge_start_ov965x_cif[][2] = {
493 {0xc2, 0x4c}, 562 {0xc2, 0x4c},
494 {0xc3, 0xf9}, 563 {0xc3, 0xf9},
564 {0xda, 0x00},
495 {0x50, 0x00}, 565 {0x50, 0x00},
496 {0x51, 0xa0}, 566 {0x51, 0xa0},
497 {0x52, 0x78}, 567 {0x52, 0x78},
@@ -500,30 +570,54 @@ static const u8 bridge_start_ov965x[][2] = {
500 {0x55, 0x00}, 570 {0x55, 0x00},
501 {0x57, 0x00}, 571 {0x57, 0x00},
502 {0x5c, 0x00}, 572 {0x5c, 0x00},
503 {0x5a, 0x28}, 573 {0x5a, 0x50},
504 {0x5b, 0x1e}, 574 {0x5b, 0x3c},
505 {0x35, 0x00}, 575 {0x35, 0x02},
506 {0xd9, 0x21}, 576 {0xd9, 0x10},
507 {0x94, 0x11}, 577 {0x94, 0x11},
578 {}
508}; 579};
509 580
510static const u8 sensor_start_ov965x[][2] = { 581static const u8 sensor_start_ov965x_vga[][2] = {
511 {0x3b, 0xe4}, 582 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
583 {0x1e, 0x04}, /* mvfp */
584 {0x13, 0xe0}, /* com8 */
585 {0x00, 0x00},
586 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
587 {0x11, 0x03}, /* clkrc */
588 {0x6b, 0x5a}, /* dblv */
589 {0x6a, 0x05}, /* 50 Hz banding filter */
590 {0xc5, 0x07}, /* 60 Hz banding filter */
591 {0xa2, 0x4b}, /* bd50 */
592 {0xa3, 0x3e}, /* bd60 */
593
594 {0x2d, 0x00}, /* advfl */
595 {}
596};
597
598static const u8 sensor_start_ov965x_cif[][2] = {
599 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
512 {0x1e, 0x04}, /* mvfp */ 600 {0x1e, 0x04}, /* mvfp */
513 {0x13, 0xe0}, /* com8 */ 601 {0x13, 0xe0}, /* com8 */
514 {0x00, 0x00}, 602 {0x00, 0x00},
515 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 603 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
516 {0x11, 0x01}, /* clkrc */ 604 {0x11, 0x01}, /* clkrc */
517 {0x6b, 0x5a}, /* dblv */ 605 {0x6b, 0x5a}, /* dblv */
518 {0x6a, 0x02}, 606 {0x6a, 0x02}, /* 50 Hz banding filter */
519 {0xc5, 0x03}, 607 {0xc5, 0x03}, /* 60 Hz banding filter */
520 {0xa2, 0x96}, 608 {0xa2, 0x96}, /* bd50 */
521 {0xa3, 0x7d}, 609 {0xa3, 0x7d}, /* bd60 */
610
522 {0xff, 0x13}, /* read 13, write ff 00 */ 611 {0xff, 0x13}, /* read 13, write ff 00 */
523 {0x13, 0xe7}, 612 {0x13, 0xe7},
524 {0x3a, 0x80}, 613 {0x3a, 0x80}, /* tslb - yuyv */
614 {}
615};
616
617static const u8 sensor_start_ov965x_2[][2] = {
525 {0xff, 0x42}, /* read 42, write ff 00 */ 618 {0xff, 0x42}, /* read 42, write ff 00 */
526 {0x42, 0xc1}, 619 {0x42, 0xc1}, /* com17 - 50 Hz filter */
620 {}
527}; 621};
528 622
529 623
@@ -705,11 +799,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
705 799
706 cam = &gspca_dev->cam; 800 cam = &gspca_dev->cam;
707 801
708 cam->cam_mode = vga_mode; 802 if (sd->sensor == SENSOR_OV772X) {
709 cam->nmodes = ARRAY_SIZE(vga_mode); 803 cam->cam_mode = vga_yuyv_mode;
804 cam->nmodes = ARRAY_SIZE(vga_yuyv_mode);
710 805
711 cam->bulk_size = 16384; 806 cam->bulk = 1;
712 cam->bulk_nurbs = 2; 807 cam->bulk_size = 16384;
808 cam->bulk_nurbs = 2;
809 } else { /* ov965x */
810 cam->cam_mode = vga_jpeg_mode;
811 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
812 }
713 813
714 return 0; 814 return 0;
715} 815}
@@ -778,6 +878,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
778static int sd_start(struct gspca_dev *gspca_dev) 878static int sd_start(struct gspca_dev *gspca_dev)
779{ 879{
780 struct sd *sd = (struct sd *) gspca_dev; 880 struct sd *sd = (struct sd *) gspca_dev;
881 int mode;
781 882
782 switch (sd->sensor) { 883 switch (sd->sensor) {
783 case SENSOR_OV772X: 884 case SENSOR_OV772X:
@@ -786,13 +887,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
786 break; 887 break;
787 default: 888 default:
788/* case SENSOR_OV965X: */ 889/* case SENSOR_OV965X: */
789 reg_w_array(gspca_dev, bridge_start_ov965x, 890
790 ARRAY_SIZE(bridge_start_ov965x));
791 sccb_w_array(gspca_dev, sensor_start_ov965x, 891 sccb_w_array(gspca_dev, sensor_start_ov965x,
792 ARRAY_SIZE(sensor_start_ov965x)); 892 ARRAY_SIZE(sensor_start_ov965x));
893 reg_w_array(gspca_dev, bridge_start_ov965x,
894 ARRAY_SIZE(bridge_start_ov965x));
895 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
896 if (mode != 0) { /* 320x240 */
897 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
898 ARRAY_SIZE(bridge_start_ov965x_cif));
899 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
900 ARRAY_SIZE(sensor_start_ov965x_cif));
901 } else { /* 640x480 */
902 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
903 ARRAY_SIZE(bridge_start_ov965x_vga));
904 sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
905 ARRAY_SIZE(sensor_start_ov965x_vga));
906 }
907 sccb_w_array(gspca_dev, sensor_start_ov965x_2,
908 ARRAY_SIZE(sensor_start_ov965x_2));
909 ov534_reg_write(gspca_dev, 0xe0, 0x00);
793 ov534_reg_write(gspca_dev, 0xe0, 0x00); 910 ov534_reg_write(gspca_dev, 0xe0, 0x00);
794 ov534_set_led(gspca_dev, 1); 911 ov534_set_led(gspca_dev, 1);
795/*fixme: other sensor start omitted*/
796 } 912 }
797 return 0; 913 return 0;
798} 914}
@@ -832,9 +948,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
832 __u32 this_pts; 948 __u32 this_pts;
833 u16 this_fid; 949 u16 this_fid;
834 int remaining_len = len; 950 int remaining_len = len;
951 int payload_len;
835 952
953 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
836 do { 954 do {
837 len = min(remaining_len, 2040); /*fixme: was 2048*/ 955 len = min(remaining_len, payload_len);
838 956
839 /* Payloads are prefixed with a UVC-style header. We 957 /* Payloads are prefixed with a UVC-style header. We
840 consider a frame to start when the FID toggles, or the PTS 958 consider a frame to start when the FID toggles, or the PTS
@@ -864,30 +982,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
864 982
865 /* If PTS or FID has changed, start a new frame. */ 983 /* If PTS or FID has changed, start a new frame. */
866 if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 984 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
867 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 985 if (gspca_dev->last_packet_type == INTER_PACKET)
868 NULL, 0); 986 frame = gspca_frame_add(gspca_dev,
987 LAST_PACKET, frame,
988 NULL, 0);
869 sd->last_pts = this_pts; 989 sd->last_pts = this_pts;
870 sd->last_fid = this_fid; 990 sd->last_fid = this_fid;
871 } 991 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
872
873 /* Add the data from this payload */
874 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
875 data + 12, len - 12); 992 data + 12, len - 12);
876
877 /* If this packet is marked as EOF, end the frame */ 993 /* If this packet is marked as EOF, end the frame */
878 if (data[1] & UVC_STREAM_EOF) { 994 } else if (data[1] & UVC_STREAM_EOF) {
879 sd->last_pts = 0; 995 sd->last_pts = 0;
880
881 if (frame->data_end - frame->data !=
882 gspca_dev->width * gspca_dev->height * 2) {
883 PDEBUG(D_PACK, "short frame");
884 goto discard;
885 }
886
887 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 996 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
888 NULL, 0); 997 data + 12, len - 12);
998 } else {
999
1000 /* Add the data from this payload */
1001 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1002 data + 12, len - 12);
889 } 1003 }
890 1004
1005
891 /* Done this payload */ 1006 /* Done this payload */
892 goto scan_next; 1007 goto scan_next;
893 1008
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 153d0a91d4b5..cf3af8de6e97 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -877,6 +877,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
877 cam->cam_mode = sif_mode; 877 cam->cam_mode = sif_mode;
878 cam->nmodes = ARRAY_SIZE(sif_mode); 878 cam->nmodes = ARRAY_SIZE(sif_mode);
879 } 879 }
880 cam->npkt = 36; /* 36 packets per ISOC message */
881
880 sd->brightness = BRIGHTNESS_DEF; 882 sd->brightness = BRIGHTNESS_DEF;
881 sd->gain = GAIN_DEF; 883 sd->gain = GAIN_DEF;
882 sd->exposure = EXPOSURE_DEF; 884 sd->exposure = EXPOSURE_DEF;
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index c72e19d3ac37..dc6a6f11354a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -62,7 +62,6 @@ struct sd {
62#define BRIDGE_SN9C105 1 62#define BRIDGE_SN9C105 1
63#define BRIDGE_SN9C110 2 63#define BRIDGE_SN9C110 2
64#define BRIDGE_SN9C120 3 64#define BRIDGE_SN9C120 3
65#define BRIDGE_SN9C325 4
66 u8 sensor; /* Type of image sensor chip */ 65 u8 sensor; /* Type of image sensor chip */
67#define SENSOR_HV7131R 0 66#define SENSOR_HV7131R 0
68#define SENSOR_MI0360 1 67#define SENSOR_MI0360 1
@@ -354,9 +353,9 @@ static const u8 sn_ov7648[0x1c] = {
354 353
355static const u8 sn_ov7660[0x1c] = { 354static const u8 sn_ov7660[0x1c] = {
356/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 355/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
357 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 356 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
358/* reg8 reg9 rega regb regc regd rege regf */ 357/* reg8 reg9 rega regb regc regd rege regf */
359 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 358 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 359/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
361 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 360 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
362/* reg18 reg19 reg1a reg1b */ 361/* reg18 reg19 reg1a reg1b */
@@ -757,6 +756,7 @@ static const u8 ov7660_sensor_init[][8] = {
757 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 756 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
758 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 757 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
759 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ 758 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
759 {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
760/****** (some exchanges in the win trace) ******/ 760/****** (some exchanges in the win trace) ******/
761 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ 761 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
762 /* bits[3..0]reserved */ 762 /* bits[3..0]reserved */
@@ -1065,9 +1065,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1065 struct sd *sd = (struct sd *) gspca_dev; 1065 struct sd *sd = (struct sd *) gspca_dev;
1066 const u8 *reg9a; 1066 const u8 *reg9a;
1067 static const u8 reg9a_def[] = 1067 static const u8 reg9a_def[] =
1068 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; 1068 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1069 static const u8 reg9a_sn9c325[] = 1069 static const u8 reg9a_spec[] =
1070 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; 1070 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1071 static const u8 regd4[] = {0x60, 0x00, 0x00}; 1071 static const u8 regd4[] = {0x60, 0x00, 0x00};
1072 1072
1073 reg_w1(gspca_dev, 0xf1, 0x00); 1073 reg_w1(gspca_dev, 0xf1, 0x00);
@@ -1077,9 +1077,10 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1077 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 1077 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1078 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); 1078 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1079 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ 1079 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
1080 switch (sd->bridge) { 1080 switch (sd->sensor) {
1081 case BRIDGE_SN9C325: 1081 case SENSOR_OV7660:
1082 reg9a = reg9a_sn9c325; 1082 case SENSOR_SP80708:
1083 reg9a = reg9a_spec;
1083 break; 1084 break;
1084 default: 1085 default:
1085 reg9a = reg9a_def; 1086 reg9a = reg9a_def;
@@ -1104,7 +1105,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1104 reg_w1(gspca_dev, 0x17, 0x64); 1105 reg_w1(gspca_dev, 0x17, 0x64);
1105 reg_w1(gspca_dev, 0x01, 0x42); 1106 reg_w1(gspca_dev, 0x01, 0x42);
1106 break; 1107 break;
1107/*jfm: from win trace */
1108 case SENSOR_OV7630: 1108 case SENSOR_OV7630:
1109 reg_w1(gspca_dev, 0x01, 0x61); 1109 reg_w1(gspca_dev, 0x01, 0x61);
1110 reg_w1(gspca_dev, 0x17, 0xe2); 1110 reg_w1(gspca_dev, 0x17, 0xe2);
@@ -1114,18 +1114,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1114 case SENSOR_OV7648: 1114 case SENSOR_OV7648:
1115 reg_w1(gspca_dev, 0x01, 0x63); 1115 reg_w1(gspca_dev, 0x01, 0x63);
1116 reg_w1(gspca_dev, 0x17, 0x20); 1116 reg_w1(gspca_dev, 0x17, 0x20);
1117 reg_w1(gspca_dev, 0x01, 0x62);
1117 reg_w1(gspca_dev, 0x01, 0x42); 1118 reg_w1(gspca_dev, 0x01, 0x42);
1118 break; 1119 break;
1119/*jfm: from win trace */
1120 case SENSOR_OV7660: 1120 case SENSOR_OV7660:
1121 if (sd->bridge == BRIDGE_SN9C120) { 1121 reg_w1(gspca_dev, 0x01, 0x61);
1122 reg_w1(gspca_dev, 0x01, 0x61); 1122 reg_w1(gspca_dev, 0x17, 0x20);
1123 reg_w1(gspca_dev, 0x17, 0x20); 1123 reg_w1(gspca_dev, 0x01, 0x60);
1124 reg_w1(gspca_dev, 0x01, 0x60); 1124 reg_w1(gspca_dev, 0x01, 0x40);
1125 reg_w1(gspca_dev, 0x01, 0x40); 1125 break;
1126 break;
1127 }
1128 /* fall thru */
1129 case SENSOR_SP80708: 1126 case SENSOR_SP80708:
1130 reg_w1(gspca_dev, 0x01, 0x63); 1127 reg_w1(gspca_dev, 0x01, 0x63);
1131 reg_w1(gspca_dev, 0x17, 0x20); 1128 reg_w1(gspca_dev, 0x17, 0x20);
@@ -1134,6 +1131,9 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1134 mdelay(100); 1131 mdelay(100);
1135 reg_w1(gspca_dev, 0x02, 0x62); 1132 reg_w1(gspca_dev, 0x02, 0x62);
1136 break; 1133 break;
1134/* case SENSOR_HV7131R: */
1135/* case SENSOR_MI0360: */
1136/* case SENSOR_MO4000: */
1137 default: 1137 default:
1138 reg_w1(gspca_dev, 0x01, 0x43); 1138 reg_w1(gspca_dev, 0x01, 0x43);
1139 reg_w1(gspca_dev, 0x17, 0x61); 1139 reg_w1(gspca_dev, 0x17, 0x61);
@@ -1280,6 +1280,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1280 cam = &gspca_dev->cam; 1280 cam = &gspca_dev->cam;
1281 cam->cam_mode = vga_mode; 1281 cam->cam_mode = vga_mode;
1282 cam->nmodes = ARRAY_SIZE(vga_mode); 1282 cam->nmodes = ARRAY_SIZE(vga_mode);
1283 cam->npkt = 24; /* 24 packets per ISOC message */
1283 1284
1284 sd->bridge = id->driver_info >> 16; 1285 sd->bridge = id->driver_info >> 16;
1285 sd->sensor = id->driver_info >> 8; 1286 sd->sensor = id->driver_info >> 8;
@@ -1683,13 +1684,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1683 case SENSOR_OV7648: 1684 case SENSOR_OV7648:
1684 reg17 = 0x20; 1685 reg17 = 0x20;
1685 break; 1686 break;
1686/*jfm: from win trace */
1687 case SENSOR_OV7660: 1687 case SENSOR_OV7660:
1688 if (sd->bridge == BRIDGE_SN9C120) { 1688 reg17 = 0xa0;
1689 reg17 = 0xa0; 1689 break;
1690 break;
1691 }
1692 /* fall thru */
1693 default: 1690 default:
1694 reg17 = 0x60; 1691 reg17 = 0x60;
1695 break; 1692 break;
@@ -1714,16 +1711,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
1714 reg_w1(gspca_dev, 0x9a, 0x0a); 1711 reg_w1(gspca_dev, 0x9a, 0x0a);
1715 reg_w1(gspca_dev, 0x99, 0x60); 1712 reg_w1(gspca_dev, 0x99, 0x60);
1716 break; 1713 break;
1714 case SENSOR_OV7660:
1715 reg_w1(gspca_dev, 0x9a, 0x05);
1716 if (sd->bridge == BRIDGE_SN9C105)
1717 reg_w1(gspca_dev, 0x99, 0xff);
1718 else
1719 reg_w1(gspca_dev, 0x99, 0x5b);
1720 break;
1717 case SENSOR_SP80708: 1721 case SENSOR_SP80708:
1718 reg_w1(gspca_dev, 0x9a, 0x05); 1722 reg_w1(gspca_dev, 0x9a, 0x05);
1719 reg_w1(gspca_dev, 0x99, 0x59); 1723 reg_w1(gspca_dev, 0x99, 0x59);
1720 break; 1724 break;
1721 case SENSOR_OV7660:
1722 if (sd->bridge == BRIDGE_SN9C120) {
1723 reg_w1(gspca_dev, 0x9a, 0x05);
1724 break;
1725 }
1726 /* fall thru */
1727 default: 1725 default:
1728 reg_w1(gspca_dev, 0x9a, 0x08); 1726 reg_w1(gspca_dev, 0x9a, 0x08);
1729 reg_w1(gspca_dev, 0x99, 0x59); 1727 reg_w1(gspca_dev, 0x99, 0x59);
@@ -2193,6 +2191,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2193 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, 2191 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2194 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, 2192 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2195 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, 2193 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2194 {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
2196 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, 2195 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2197/* bw600.inf: 2196/* bw600.inf:
2198 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ 2197 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
@@ -2211,7 +2210,12 @@ static const __devinitdata struct usb_device_id device_table[] = {
2211#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2210#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2212 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, 2211 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2213#endif 2212#endif
2213 {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
2214/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 2214/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2215 {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
2216 {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
2217 {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
2218 {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
2215/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 2219/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2216/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 2220/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2217 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/ 2221 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 6f38fa6d86b6..8806b2ff82be 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -32,9 +32,6 @@ 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 packet[ISO_MAX_SIZE + 128];
36 /* !! no more than 128 ff in an ISO packet */
37
38 unsigned char brightness; 35 unsigned char brightness;
39 unsigned char contrast; 36 unsigned char contrast;
40 unsigned char colors; 37 unsigned char colors;
@@ -906,7 +903,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
906{ 903{
907 struct sd *sd = (struct sd *) gspca_dev; 904 struct sd *sd = (struct sd *) gspca_dev;
908 int i; 905 int i;
909 __u8 *s, *d;
910 static __u8 ffd9[] = {0xff, 0xd9}; 906 static __u8 ffd9[] = {0xff, 0xd9};
911 907
912/* frames are jpeg 4.1.1 without 0xff escape */ 908/* frames are jpeg 4.1.1 without 0xff escape */
@@ -930,22 +926,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
930 } 926 }
931 927
932 /* add 0x00 after 0xff */ 928 /* add 0x00 after 0xff */
933 for (i = len; --i >= 0; ) 929 i = 0;
934 if (data[i] == 0xff) 930 do {
935 break; 931 if (data[i] == 0xff) {
936 if (i < 0) { /* no 0xff */ 932 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
937 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 933 data, i + 1);
938 return; 934 len -= i;
939 } 935 data += i;
940 s = data; 936 *data = 0x00;
941 d = sd->packet; 937 i = 0;
942 for (i = 0; i < len; i++) { 938 }
943 *d++ = *s++; 939 i++;
944 if (s[-1] == 0xff) 940 } while (i < len);
945 *d++ = 0x00; 941 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
946 }
947 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
948 sd->packet, d - sd->packet);
949} 942}
950 943
951static void setbrightness(struct gspca_dev *gspca_dev) 944static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2acec58b1b97..ea8c9fe2e961 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -637,19 +637,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
637 cam->nmodes = ARRAY_SIZE(vga_mode) - 1; 637 cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
638 sd->brightness = BRIGHTNESS_DEF; 638 sd->brightness = BRIGHTNESS_DEF;
639 639
640 if (sd->subtype == Nxultra) {
641 if (write_vector(gspca_dev, spca505b_init_data))
642 return -EIO;
643 } else {
644 if (write_vector(gspca_dev, spca505_init_data))
645 return -EIO;
646 }
647 return 0; 640 return 0;
648} 641}
649 642
650/* this function is called at probe and resume time */ 643/* this function is called at probe and resume time */
651static int sd_init(struct gspca_dev *gspca_dev) 644static int sd_init(struct gspca_dev *gspca_dev)
652{ 645{
646 struct sd *sd = (struct sd *) gspca_dev;
647
648 if (write_vector(gspca_dev,
649 sd->subtype == Nxultra
650 ? spca505b_init_data
651 : spca505_init_data))
652 return -EIO;
653 return 0; 653 return 0;
654} 654}
655 655
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index adacf8437661..2ed2669bac3e 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SPCA508 chip based cameras subdriver 2 * SPCA508 chip based cameras subdriver
3 * 3 *
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -30,9 +30,9 @@ MODULE_LICENSE("GPL");
30struct sd { 30struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */ 31 struct gspca_dev gspca_dev; /* !! must be the first item */
32 32
33 unsigned char brightness; 33 u8 brightness;
34 34
35 char subtype; 35 u8 subtype;
36#define CreativeVista 0 36#define CreativeVista 0
37#define HamaUSBSightcam 1 37#define HamaUSBSightcam 1
38#define HamaUSBSightcam2 2 38#define HamaUSBSightcam2 2
@@ -86,58 +86,34 @@ static const struct v4l2_pix_format sif_mode[] = {
86}; 86};
87 87
88/* Frame packet header offsets for the spca508 */ 88/* Frame packet header offsets for the spca508 */
89#define SPCA508_OFFSET_TYPE 1
90#define SPCA508_OFFSET_COMPRESS 2
91#define SPCA508_OFFSET_FRAMSEQ 8
92#define SPCA508_OFFSET_WIN1LUM 11
93#define SPCA508_OFFSET_DATA 37 89#define SPCA508_OFFSET_DATA 37
94 90
95#define SPCA508_SNAPBIT 0x20
96#define SPCA508_SNAPCTRL 0x40
97/*************** I2c ****************/
98#define SPCA508_INDEX_I2C_BASE 0x8800
99
100/* 91/*
101 * Initialization data: this is the first set-up data written to the 92 * Initialization data: this is the first set-up data written to the
102 * device (before the open data). 93 * device (before the open data).
103 */ 94 */
104static const u16 spca508_init_data[][2] = 95static const u16 spca508_init_data[][2] =
105{ 96{
106 /* line URB value, index */ 97 {0x0000, 0x870b},
107 /* 44274 1804 */ {0x0000, 0x870b}, 98
108 99 {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
109 /* 44299 1805 */ {0x0020, 0x8112}, 100 {0x0003, 0x8111}, /* Reset compression & memory */
110 /* Video drop enable, ISO streaming disable */ 101 {0x0000, 0x8110}, /* Disable all outputs */
111 /* 44324 1806 */ {0x0003, 0x8111}, 102 /* READ {0x0000, 0x8114} -> 0000: 00 */
112 /* Reset compression & memory */ 103 {0x0000, 0x8114}, /* SW GPIO data */
113 /* 44349 1807 */ {0x0000, 0x8110}, 104 {0x0008, 0x8110}, /* Enable charge pump output */
114 /* Disable all outputs */ 105 {0x0002, 0x8116}, /* 200 kHz pump clock */
115 /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ 106 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
116 /* 44398 1809 */ {0x0000, 0x8114}, 107 {0x0003, 0x8111}, /* Reset compression & memory */
117 /* SW GPIO data */ 108 {0x0000, 0x8111}, /* Normal mode (not reset) */
118 /* 44423 1810 */ {0x0008, 0x8110}, 109 {0x0098, 0x8110},
119 /* Enable charge pump output */ 110 /* Enable charge pump output, sync.serial,external 2x clock */
120 /* 44527 1811 */ {0x0002, 0x8116}, 111 {0x000d, 0x8114}, /* SW GPIO data */
121 /* 200 kHz pump clock */ 112 {0x0002, 0x8116}, /* 200 kHz pump clock */
122 /* 44555 1812 */ 113 {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
123 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
124 /* 44590 1813 */ {0x0003, 0x8111},
125 /* Reset compression & memory */
126 /* 44615 1814 */ {0x0000, 0x8111},
127 /* Normal mode (not reset) */
128 /* 44640 1815 */ {0x0098, 0x8110},
129 /* Enable charge pump output, sync.serial,external 2x clock */
130 /* 44665 1816 */ {0x000d, 0x8114},
131 /* SW GPIO data */
132 /* 44690 1817 */ {0x0002, 0x8116},
133 /* 200 kHz pump clock */
134 /* 44715 1818 */ {0x0020, 0x8112},
135 /* Video drop enable, ISO streaming disable */
136/* --------------------------------------- */ 114/* --------------------------------------- */
137 /* 44740 1819 */ {0x000f, 0x8402}, 115 {0x000f, 0x8402}, /* memory bank */
138 /* memory bank */ 116 {0x0000, 0x8403}, /* ... address */
139 /* 44765 1820 */ {0x0000, 0x8403},
140 /* ... address */
141/* --------------------------------------- */ 117/* --------------------------------------- */
142/* 0x88__ is Synchronous Serial Interface. */ 118/* 0x88__ is Synchronous Serial Interface. */
143/* TBD: This table could be expressed more compactly */ 119/* TBD: This table could be expressed more compactly */
@@ -145,446 +121,384 @@ static const u16 spca508_init_data[][2] =
145/* TBD: Should see if the values in spca50x_i2c_data */ 121/* TBD: Should see if the values in spca50x_i2c_data */
146/* would work with the VQ110 instead of the values */ 122/* would work with the VQ110 instead of the values */
147/* below. */ 123/* below. */
148 /* 44790 1821 */ {0x00c0, 0x8804}, 124 {0x00c0, 0x8804}, /* SSI slave addr */
149 /* SSI slave addr */ 125 {0x0008, 0x8802}, /* 375 Khz SSI clock */
150 /* 44815 1822 */ {0x0008, 0x8802}, 126 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
151 /* 375 Khz SSI clock */ 127 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
152 /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 128 {0x0008, 0x8802}, /* 375 Khz SSI clock */
153 /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 129 {0x0012, 0x8801}, /* SSI reg addr */
154 /* 44888 1825 */ {0x0008, 0x8802}, 130 {0x0080, 0x8800}, /* SSI data to write */
155 /* 375 Khz SSI clock */ 131 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
156 /* 44913 1826 */ {0x0012, 0x8801}, 132 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
157 /* SSI reg addr */ 133 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
158 /* 44938 1827 */ {0x0080, 0x8800}, 134 {0x0008, 0x8802}, /* 375 Khz SSI clock */
159 /* SSI data to write */ 135 {0x0012, 0x8801}, /* SSI reg addr */
160 /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 136 {0x0000, 0x8800}, /* SSI data to write */
161 /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 137 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
162 /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 138 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
163 /* 45035 1831 */ {0x0008, 0x8802}, 139 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
164 /* 375 Khz SSI clock */ 140 {0x0008, 0x8802}, /* 375 Khz SSI clock */
165 /* 45060 1832 */ {0x0012, 0x8801}, 141 {0x0011, 0x8801}, /* SSI reg addr */
166 /* SSI reg addr */ 142 {0x0040, 0x8800}, /* SSI data to write */
167 /* 45085 1833 */ {0x0000, 0x8800}, 143 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
168 /* SSI data to write */ 144 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
169 /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 145 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
170 /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 146 {0x0008, 0x8802},
171 /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 147 {0x0013, 0x8801},
172 /* 45182 1837 */ {0x0008, 0x8802}, 148 {0x0000, 0x8800},
173 /* 375 Khz SSI clock */ 149 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
174 /* 45207 1838 */ {0x0011, 0x8801}, 150 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
175 /* SSI reg addr */ 151 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
176 /* 45232 1839 */ {0x0040, 0x8800}, 152 {0x0008, 0x8802},
177 /* SSI data to write */ 153 {0x0014, 0x8801},
178 /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 154 {0x0000, 0x8800},
179 /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 155 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
180 /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 156 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
181 /* 45329 1843 */ {0x0008, 0x8802}, 157 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
182 /* 45354 1844 */ {0x0013, 0x8801}, 158 {0x0008, 0x8802},
183 /* 45379 1845 */ {0x0000, 0x8800}, 159 {0x0015, 0x8801},
184 /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 160 {0x0001, 0x8800},
185 /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 161 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
186 /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 162 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
187 /* 45476 1849 */ {0x0008, 0x8802}, 163 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
188 /* 45501 1850 */ {0x0014, 0x8801}, 164 {0x0008, 0x8802},
189 /* 45526 1851 */ {0x0000, 0x8800}, 165 {0x0016, 0x8801},
190 /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 166 {0x0003, 0x8800},
191 /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 167 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
192 /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 168 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
193 /* 45623 1855 */ {0x0008, 0x8802}, 169 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
194 /* 45648 1856 */ {0x0015, 0x8801}, 170 {0x0008, 0x8802},
195 /* 45673 1857 */ {0x0001, 0x8800}, 171 {0x0017, 0x8801},
196 /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 172 {0x0036, 0x8800},
197 /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 173 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
198 /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 174 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
199 /* 45770 1861 */ {0x0008, 0x8802}, 175 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
200 /* 45795 1862 */ {0x0016, 0x8801}, 176 {0x0008, 0x8802},
201 /* 45820 1863 */ {0x0003, 0x8800}, 177 {0x0018, 0x8801},
202 /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 178 {0x00ec, 0x8800},
203 /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 179 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
204 /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 180 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
205 /* 45917 1867 */ {0x0008, 0x8802}, 181 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
206 /* 45942 1868 */ {0x0017, 0x8801}, 182 {0x0008, 0x8802},
207 /* 45967 1869 */ {0x0036, 0x8800}, 183 {0x001a, 0x8801},
208 /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 184 {0x0094, 0x8800},
209 /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 185 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
210 /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 186 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
211 /* 46064 1873 */ {0x0008, 0x8802}, 187 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
212 /* 46089 1874 */ {0x0018, 0x8801}, 188 {0x0008, 0x8802},
213 /* 46114 1875 */ {0x00ec, 0x8800}, 189 {0x001b, 0x8801},
214 /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 190 {0x0000, 0x8800},
215 /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 191 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
216 /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 192 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
217 /* 46211 1879 */ {0x0008, 0x8802}, 193 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
218 /* 46236 1880 */ {0x001a, 0x8801}, 194 {0x0008, 0x8802},
219 /* 46261 1881 */ {0x0094, 0x8800}, 195 {0x0027, 0x8801},
220 /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 196 {0x00a2, 0x8800},
221 /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 197 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
222 /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 198 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
223 /* 46358 1885 */ {0x0008, 0x8802}, 199 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
224 /* 46383 1886 */ {0x001b, 0x8801}, 200 {0x0008, 0x8802},
225 /* 46408 1887 */ {0x0000, 0x8800}, 201 {0x0028, 0x8801},
226 /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 202 {0x0040, 0x8800},
227 /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 203 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
228 /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 204 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
229 /* 46505 1891 */ {0x0008, 0x8802}, 205 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
230 /* 46530 1892 */ {0x0027, 0x8801}, 206 {0x0008, 0x8802},
231 /* 46555 1893 */ {0x00a2, 0x8800}, 207 {0x002a, 0x8801},
232 /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 208 {0x0084, 0x8800},
233 /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 209 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
234 /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 210 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
235 /* 46652 1897 */ {0x0008, 0x8802}, 211 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
236 /* 46677 1898 */ {0x0028, 0x8801}, 212 {0x0008, 0x8802},
237 /* 46702 1899 */ {0x0040, 0x8800}, 213 {0x002b, 0x8801},
238 /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 214 {0x00a8, 0x8800},
239 /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 215 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
240 /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 216 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
241 /* 46799 1903 */ {0x0008, 0x8802}, 217 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
242 /* 46824 1904 */ {0x002a, 0x8801}, 218 {0x0008, 0x8802},
243 /* 46849 1905 */ {0x0084, 0x8800}, 219 {0x002c, 0x8801},
244 /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 220 {0x00fe, 0x8800},
245 /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 221 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
246 /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 222 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
247 /* 46946 1909 */ {0x0008, 0x8802}, 223 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
248 /* 46971 1910 */ {0x002b, 0x8801}, 224 {0x0008, 0x8802},
249 /* 46996 1911 */ {0x00a8, 0x8800}, 225 {0x002d, 0x8801},
250 /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 226 {0x0003, 0x8800},
251 /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 227 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
252 /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 228 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
253 /* 47093 1915 */ {0x0008, 0x8802}, 229 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
254 /* 47118 1916 */ {0x002c, 0x8801}, 230 {0x0008, 0x8802},
255 /* 47143 1917 */ {0x00fe, 0x8800}, 231 {0x0038, 0x8801},
256 /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 232 {0x0083, 0x8800},
257 /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 233 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
258 /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 234 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
259 /* 47240 1921 */ {0x0008, 0x8802}, 235 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
260 /* 47265 1922 */ {0x002d, 0x8801}, 236 {0x0008, 0x8802},
261 /* 47290 1923 */ {0x0003, 0x8800}, 237 {0x0033, 0x8801},
262 /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 238 {0x0081, 0x8800},
263 /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 239 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
264 /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 240 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
265 /* 47387 1927 */ {0x0008, 0x8802}, 241 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
266 /* 47412 1928 */ {0x0038, 0x8801}, 242 {0x0008, 0x8802},
267 /* 47437 1929 */ {0x0083, 0x8800}, 243 {0x0034, 0x8801},
268 /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 244 {0x004a, 0x8800},
269 /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 245 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
270 /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 246 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
271 /* 47534 1933 */ {0x0008, 0x8802}, 247 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
272 /* 47559 1934 */ {0x0033, 0x8801}, 248 {0x0008, 0x8802},
273 /* 47584 1935 */ {0x0081, 0x8800}, 249 {0x0039, 0x8801},
274 /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 250 {0x0000, 0x8800},
275 /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 251 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
276 /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 252 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
277 /* 47681 1939 */ {0x0008, 0x8802}, 253 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
278 /* 47706 1940 */ {0x0034, 0x8801}, 254 {0x0008, 0x8802},
279 /* 47731 1941 */ {0x004a, 0x8800}, 255 {0x0010, 0x8801},
280 /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 256 {0x00a8, 0x8800},
281 /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 257 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
282 /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 258 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
283 /* 47828 1945 */ {0x0008, 0x8802}, 259 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
284 /* 47853 1946 */ {0x0039, 0x8801}, 260 {0x0008, 0x8802},
285 /* 47878 1947 */ {0x0000, 0x8800}, 261 {0x0006, 0x8801},
286 /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 262 {0x0058, 0x8800},
287 /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 263 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
288 /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 264 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
289 /* 47975 1951 */ {0x0008, 0x8802}, 265 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
290 /* 48000 1952 */ {0x0010, 0x8801}, 266 {0x0008, 0x8802},
291 /* 48025 1953 */ {0x00a8, 0x8800}, 267 {0x0000, 0x8801},
292 /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 268 {0x0004, 0x8800},
293 /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 269 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
294 /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 270 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
295 /* 48122 1957 */ {0x0008, 0x8802}, 271 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
296 /* 48147 1958 */ {0x0006, 0x8801}, 272 {0x0008, 0x8802},
297 /* 48172 1959 */ {0x0058, 0x8800}, 273 {0x0040, 0x8801},
298 /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 274 {0x0080, 0x8800},
299 /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 275 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
300 /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 276 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
301 /* 48269 1963 */ {0x0008, 0x8802}, 277 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
302 /* 48294 1964 */ {0x0000, 0x8801}, 278 {0x0008, 0x8802},
303 /* 48319 1965 */ {0x0004, 0x8800}, 279 {0x0041, 0x8801},
304 /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 280 {0x000c, 0x8800},
305 /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 281 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
306 /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 282 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
307 /* 48416 1969 */ {0x0008, 0x8802}, 283 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
308 /* 48441 1970 */ {0x0040, 0x8801}, 284 {0x0008, 0x8802},
309 /* 48466 1971 */ {0x0080, 0x8800}, 285 {0x0042, 0x8801},
310 /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 286 {0x000c, 0x8800},
311 /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 287 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
312 /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 288 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
313 /* 48563 1975 */ {0x0008, 0x8802}, 289 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
314 /* 48588 1976 */ {0x0041, 0x8801}, 290 {0x0008, 0x8802},
315 /* 48613 1977 */ {0x000c, 0x8800}, 291 {0x0043, 0x8801},
316 /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 292 {0x0028, 0x8800},
317 /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 293 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
318 /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 294 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
319 /* 48710 1981 */ {0x0008, 0x8802}, 295 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
320 /* 48735 1982 */ {0x0042, 0x8801}, 296 {0x0008, 0x8802},
321 /* 48760 1983 */ {0x000c, 0x8800}, 297 {0x0044, 0x8801},
322 /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 298 {0x0080, 0x8800},
323 /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 299 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
324 /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 300 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
325 /* 48857 1987 */ {0x0008, 0x8802}, 301 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
326 /* 48882 1988 */ {0x0043, 0x8801}, 302 {0x0008, 0x8802},
327 /* 48907 1989 */ {0x0028, 0x8800}, 303 {0x0045, 0x8801},
328 /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 304 {0x0020, 0x8800},
329 /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 305 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
330 /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 306 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
331 /* 49004 1993 */ {0x0008, 0x8802}, 307 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
332 /* 49029 1994 */ {0x0044, 0x8801}, 308 {0x0008, 0x8802},
333 /* 49054 1995 */ {0x0080, 0x8800}, 309 {0x0046, 0x8801},
334 /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 310 {0x0020, 0x8800},
335 /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 311 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
336 /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 312 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
337 /* 49151 1999 */ {0x0008, 0x8802}, 313 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
338 /* 49176 2000 */ {0x0045, 0x8801}, 314 {0x0008, 0x8802},
339 /* 49201 2001 */ {0x0020, 0x8800}, 315 {0x0047, 0x8801},
340 /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 316 {0x0080, 0x8800},
341 /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 317 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
342 /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 318 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
343 /* 49298 2005 */ {0x0008, 0x8802}, 319 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
344 /* 49323 2006 */ {0x0046, 0x8801}, 320 {0x0008, 0x8802},
345 /* 49348 2007 */ {0x0020, 0x8800}, 321 {0x0048, 0x8801},
346 /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 322 {0x004c, 0x8800},
347 /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 323 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
348 /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 324 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
349 /* 49445 2011 */ {0x0008, 0x8802}, 325 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
350 /* 49470 2012 */ {0x0047, 0x8801}, 326 {0x0008, 0x8802},
351 /* 49495 2013 */ {0x0080, 0x8800}, 327 {0x0049, 0x8801},
352 /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 328 {0x0084, 0x8800},
353 /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 329 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
354 /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 330 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
355 /* 49592 2017 */ {0x0008, 0x8802}, 331 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
356 /* 49617 2018 */ {0x0048, 0x8801}, 332 {0x0008, 0x8802},
357 /* 49642 2019 */ {0x004c, 0x8800}, 333 {0x004a, 0x8801},
358 /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 334 {0x0084, 0x8800},
359 /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 335 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
360 /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 336 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
361 /* 49739 2023 */ {0x0008, 0x8802}, 337 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
362 /* 49764 2024 */ {0x0049, 0x8801}, 338 {0x0008, 0x8802},
363 /* 49789 2025 */ {0x0084, 0x8800}, 339 {0x004b, 0x8801},
364 /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 340 {0x0084, 0x8800},
365 /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 341 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
366 /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
367 /* 49886 2029 */ {0x0008, 0x8802},
368 /* 49911 2030 */ {0x004a, 0x8801},
369 /* 49936 2031 */ {0x0084, 0x8800},
370 /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
371 /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
372 /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
373 /* 50033 2035 */ {0x0008, 0x8802},
374 /* 50058 2036 */ {0x004b, 0x8801},
375 /* 50083 2037 */ {0x0084, 0x8800},
376 /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
377 /* --------------------------------------- */ 342 /* --------------------------------------- */
378 /* 50132 2039 */ {0x0012, 0x8700}, 343 {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
379 /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ 344 {0x0000, 0x8701}, /* CKx1 clock delay adj */
380 /* 50157 2040 */ {0x0000, 0x8701}, 345 {0x0000, 0x8701}, /* CKx1 clock delay adj */
381 /* CKx1 clock delay adj */ 346 {0x0001, 0x870c}, /* CKOx2 output */
382 /* 50182 2041 */ {0x0000, 0x8701},
383 /* CKx1 clock delay adj */
384 /* 50207 2042 */ {0x0001, 0x870c},
385 /* CKOx2 output */
386 /* --------------------------------------- */ 347 /* --------------------------------------- */
387 /* 50232 2043 */ {0x0080, 0x8600}, 348 {0x0080, 0x8600}, /* Line memory read counter (L) */
388 /* Line memory read counter (L) */ 349 {0x0001, 0x8606}, /* reserved */
389 /* 50257 2044 */ {0x0001, 0x8606}, 350 {0x0064, 0x8607}, /* Line memory read counter (H) 0x6480=25,728 */
390 /* reserved */ 351 {0x002a, 0x8601}, /* CDSP sharp interpolation mode,
391 /* 50282 2045 */ {0x0064, 0x8607},
392 /* Line memory read counter (H) 0x6480=25,728 */
393 /* 50307 2046 */ {0x002a, 0x8601},
394 /* CDSP sharp interpolation mode,
395 * line sel for color sep, edge enhance enab */ 352 * line sel for color sep, edge enhance enab */
396 /* 50332 2047 */ {0x0000, 0x8602}, 353 {0x0000, 0x8602}, /* optical black level for user settng = 0 */
397 /* optical black level for user settng = 0 */ 354 {0x0080, 0x8600}, /* Line memory read counter (L) */
398 /* 50357 2048 */ {0x0080, 0x8600}, 355 {0x000a, 0x8603}, /* optical black level calc mode:
399 /* Line memory read counter (L) */ 356 * auto; optical black offset = 10 */
400 /* 50382 2049 */ {0x000a, 0x8603}, 357 {0x00df, 0x865b}, /* Horiz offset for valid pixels (L)=0xdf */
401 /* optical black level calc mode: auto; optical black offset = 10 */ 358 {0x0012, 0x865c}, /* Vert offset for valid lines (L)=0x12 */
402 /* 50407 2050 */ {0x00df, 0x865b},
403 /* Horiz offset for valid pixels (L)=0xdf */
404 /* 50432 2051 */ {0x0012, 0x865c},
405 /* Vert offset for valid lines (L)=0x12 */
406 359
407/* The following two lines seem to be the "wrong" resolution. */ 360/* The following two lines seem to be the "wrong" resolution. */
408/* But perhaps these indicate the actual size of the sensor */ 361/* But perhaps these indicate the actual size of the sensor */
409/* rather than the size of the current video mode. */ 362/* rather than the size of the current video mode. */
410 /* 50457 2052 */ {0x0058, 0x865d}, 363 {0x0058, 0x865d}, /* Horiz valid pixels (*4) (L) = 352 */
411 /* Horiz valid pixels (*4) (L) = 352 */ 364 {0x0048, 0x865e}, /* Vert valid lines (*4) (L) = 288 */
412 /* 50482 2053 */ {0x0048, 0x865e}, 365
413 /* Vert valid lines (*4) (L) = 288 */ 366 {0x0015, 0x8608}, /* A11 Coef ... */
414 367 {0x0030, 0x8609},
415 /* 50507 2054 */ {0x0015, 0x8608}, 368 {0x00fb, 0x860a},
416 /* A11 Coef ... */ 369 {0x003e, 0x860b},
417 /* 50532 2055 */ {0x0030, 0x8609}, 370 {0x00ce, 0x860c},
418 /* 50557 2056 */ {0x00fb, 0x860a}, 371 {0x00f4, 0x860d},
419 /* 50582 2057 */ {0x003e, 0x860b}, 372 {0x00eb, 0x860e},
420 /* 50607 2058 */ {0x00ce, 0x860c}, 373 {0x00dc, 0x860f},
421 /* 50632 2059 */ {0x00f4, 0x860d}, 374 {0x0039, 0x8610},
422 /* 50657 2060 */ {0x00eb, 0x860e}, 375 {0x0001, 0x8611}, /* R offset for white balance ... */
423 /* 50682 2061 */ {0x00dc, 0x860f}, 376 {0x0000, 0x8612},
424 /* 50707 2062 */ {0x0039, 0x8610}, 377 {0x0001, 0x8613},
425 /* 50732 2063 */ {0x0001, 0x8611}, 378 {0x0000, 0x8614},
426 /* R offset for white balance ... */ 379 {0x005b, 0x8651}, /* R gain for white balance ... */
427 /* 50757 2064 */ {0x0000, 0x8612}, 380 {0x0040, 0x8652},
428 /* 50782 2065 */ {0x0001, 0x8613}, 381 {0x0060, 0x8653},
429 /* 50807 2066 */ {0x0000, 0x8614}, 382 {0x0040, 0x8654},
430 /* 50832 2067 */ {0x005b, 0x8651}, 383 {0x0000, 0x8655},
431 /* R gain for white balance ... */ 384 {0x0001, 0x863f}, /* Fixed gamma correction enable, USB control,
432 /* 50857 2068 */ {0x0040, 0x8652}, 385 * lum filter disable, lum noise clip disable */
433 /* 50882 2069 */ {0x0060, 0x8653}, 386 {0x00a1, 0x8656}, /* Window1 size 256x256, Windows2 size 64x64,
434 /* 50907 2070 */ {0x0040, 0x8654}, 387 * gamma look-up disable,
435 /* 50932 2071 */ {0x0000, 0x8655}, 388 * new edge enhancement enable */
436 /* 50957 2072 */ {0x0001, 0x863f}, 389 {0x0018, 0x8657}, /* Edge gain high thresh */
437 /* Fixed gamma correction enable, USB control, 390 {0x0020, 0x8658}, /* Edge gain low thresh */
438 * lum filter disable, lum noise clip disable */ 391 {0x000a, 0x8659}, /* Edge bandwidth high threshold */
439 /* 50982 2073 */ {0x00a1, 0x8656}, 392 {0x0005, 0x865a}, /* Edge bandwidth low threshold */
440 /* Window1 size 256x256, Windows2 size 64x64,
441 * gamma look-up disable, new edge enhancement enable */
442 /* 51007 2074 */ {0x0018, 0x8657},
443 /* Edge gain high thresh */
444 /* 51032 2075 */ {0x0020, 0x8658},
445 /* Edge gain low thresh */
446 /* 51057 2076 */ {0x000a, 0x8659},
447 /* Edge bandwidth high threshold */
448 /* 51082 2077 */ {0x0005, 0x865a},
449 /* Edge bandwidth low threshold */
450 /* -------------------------------- */ 393 /* -------------------------------- */
451 /* 51107 2078 */ {0x0030, 0x8112}, 394 {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */
452 /* Video drop enable, ISO streaming enable */ 395 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
453 /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 396 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
454 /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 397 {0xa908, 0x8802},
455 /* 51180 2081 */ {0xa908, 0x8802}, 398 {0x0034, 0x8801}, /* SSI reg addr */
456 /* 51205 2082 */ {0x0034, 0x8801}, 399 {0x00ca, 0x8800},
457 /* SSI reg addr */
458 /* 51230 2083 */ {0x00ca, 0x8800},
459 /* SSI data to write */ 400 /* SSI data to write */
460 /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 401 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
461 /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 402 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
462 /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 403 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
463 /* 51327 2087 */ {0x1f08, 0x8802}, 404 {0x1f08, 0x8802},
464 /* 51352 2088 */ {0x0006, 0x8801}, 405 {0x0006, 0x8801},
465 /* 51377 2089 */ {0x0080, 0x8800}, 406 {0x0080, 0x8800},
466 /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 407 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
467 408
468/* ----- Read back coefs we wrote earlier. */ 409/* ----- Read back coefs we wrote earlier. */
469 /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ 410 /* READ { 0x0000, 0x8608 } -> 0000: 15 */
470 /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ 411 /* READ { 0x0000, 0x8609 } -> 0000: 30 */
471 /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ 412 /* READ { 0x0000, 0x860a } -> 0000: fb */
472 /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ 413 /* READ { 0x0000, 0x860b } -> 0000: 3e */
473 /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ 414 /* READ { 0x0000, 0x860c } -> 0000: ce */
474 /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ 415 /* READ { 0x0000, 0x860d } -> 0000: f4 */
475 /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ 416 /* READ { 0x0000, 0x860e } -> 0000: eb */
476 /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ 417 /* READ { 0x0000, 0x860f } -> 0000: dc */
477 /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ 418 /* READ { 0x0000, 0x8610 } -> 0000: 39 */
478 /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 419 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
479 /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ 420 /* READ { 0x0001, 0x8802 } -> 0000: 08 */
480 /* 51690 2102 */ {0xb008, 0x8802}, 421 {0xb008, 0x8802},
481 /* 51715 2103 */ {0x0006, 0x8801}, 422 {0x0006, 0x8801},
482 /* 51740 2104 */ {0x007d, 0x8800}, 423 {0x007d, 0x8800},
483 /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 424 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
484 425
485 426
486 /* This chunk is seemingly redundant with */ 427 /* This chunk is seemingly redundant with */
487 /* earlier commands (A11 Coef...), but if I disable it, */ 428 /* earlier commands (A11 Coef...), but if I disable it, */
488 /* the image appears too dark. Maybe there was some kind of */ 429 /* the image appears too dark. Maybe there was some kind of */
489 /* reset since the earlier commands, so this is necessary again. */ 430 /* reset since the earlier commands, so this is necessary again. */
490 /* 51789 2106 */ {0x0015, 0x8608}, 431 {0x0015, 0x8608},
491 /* 51814 2107 */ {0x0030, 0x8609}, 432 {0x0030, 0x8609},
492 /* 51839 2108 */ {0xfffb, 0x860a}, 433 {0xfffb, 0x860a},
493 /* 51864 2109 */ {0x003e, 0x860b}, 434 {0x003e, 0x860b},
494 /* 51889 2110 */ {0xffce, 0x860c}, 435 {0xffce, 0x860c},
495 /* 51914 2111 */ {0xfff4, 0x860d}, 436 {0xfff4, 0x860d},
496 /* 51939 2112 */ {0xffeb, 0x860e}, 437 {0xffeb, 0x860e},
497 /* 51964 2113 */ {0xffdc, 0x860f}, 438 {0xffdc, 0x860f},
498 /* 51989 2114 */ {0x0039, 0x8610}, 439 {0x0039, 0x8610},
499 /* 52014 2115 */ {0x0018, 0x8657}, 440 {0x0018, 0x8657},
500 441
501 /* 52039 2116 */ {0x0000, 0x8508}, 442 {0x0000, 0x8508}, /* Disable compression. */
502 /* Disable compression. */
503 /* Previous line was: 443 /* Previous line was:
504 * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ 444 {0x0021, 0x8508}, * Enable compression. */
505 /* 52064 2117 */ {0x0032, 0x850b}, 445 {0x0032, 0x850b}, /* compression stuff */
506 /* compression stuff */ 446 {0x0003, 0x8509}, /* compression stuff */
507 /* 52089 2118 */ {0x0003, 0x8509}, 447 {0x0011, 0x850a}, /* compression stuff */
508 /* compression stuff */ 448 {0x0021, 0x850d}, /* compression stuff */
509 /* 52114 2119 */ {0x0011, 0x850a}, 449 {0x0010, 0x850c}, /* compression stuff */
510 /* compression stuff */ 450 {0x0003, 0x8500}, /* *** Video mode: 160x120 */
511 /* 52139 2120 */ {0x0021, 0x850d}, 451 {0x0001, 0x8501}, /* Hardware-dominated snap control */
512 /* compression stuff */ 452 {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128,
513 /* 52164 2121 */ {0x0010, 0x850c}, 453 * gamma look-up disable,
514 /* compression stuff */ 454 * new edge enhancement enable */
515 /* 52189 2122 */ {0x0003, 0x8500}, 455 {0x0018, 0x8617}, /* Window1 start X (*2) */
516 /* *** Video mode: 160x120 */ 456 {0x0008, 0x8618}, /* Window1 start Y (*2) */
517 /* 52214 2123 */ {0x0001, 0x8501}, 457 {0x0061, 0x8656}, /* Window1 size 128x128, Windows2 size 128x128,
518 /* Hardware-dominated snap control */ 458 * gamma look-up disable,
519 /* 52239 2124 */ {0x0061, 0x8656}, 459 * new edge enhancement enable */
520 /* Window1 size 128x128, Windows2 size 128x128, 460 {0x0058, 0x8619}, /* Window2 start X (*2) */
521 * gamma look-up disable, new edge enhancement enable */ 461 {0x0008, 0x861a}, /* Window2 start Y (*2) */
522 /* 52264 2125 */ {0x0018, 0x8617}, 462 {0x00ff, 0x8615}, /* High lum thresh for white balance */
523 /* Window1 start X (*2) */ 463 {0x0000, 0x8616}, /* Low lum thresh for white balance */
524 /* 52289 2126 */ {0x0008, 0x8618}, 464 {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
525 /* Window1 start Y (*2) */ 465 {0x0012, 0x8700}, /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
526 /* 52314 2127 */ {0x0061, 0x8656}, 466 /* READ { 0x0000, 0x8656 } -> 0000: 61 */
527 /* Window1 size 128x128, Windows2 size 128x128, 467 {0x0028, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
528 * gamma look-up disable, new edge enhancement enable */ 468 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
529 /* 52339 2128 */ {0x0058, 0x8619}, 469 /* READ { 0x0001, 0x8802 } -> 0000: 28 */
530 /* Window2 start X (*2) */ 470 {0x1f28, 0x8802}, /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
531 /* 52364 2129 */ {0x0008, 0x861a}, 471 {0x0010, 0x8801}, /* SSI reg addr */
532 /* Window2 start Y (*2) */ 472 {0x003e, 0x8800}, /* SSI data to write */
533 /* 52389 2130 */ {0x00ff, 0x8615}, 473 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
534 /* High lum thresh for white balance */ 474 {0x0028, 0x8802},
535 /* 52414 2131 */ {0x0000, 0x8616}, 475 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
536 /* Low lum thresh for white balance */ 476 /* READ { 0x0001, 0x8802 } -> 0000: 28 */
537 /* 52439 2132 */ {0x0012, 0x8700}, 477 {0x1f28, 0x8802},
538 /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ 478 {0x0000, 0x8801},
539 /* 52464 2133 */ {0x0012, 0x8700}, 479 {0x001f, 0x8800},
540 /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ 480 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
541 /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ 481 {0x0001, 0x8602}, /* optical black level for user settning = 1 */
542 /* 52513 2135 */ {0x0028, 0x8802},
543 /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
544 /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
545 /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
546 /* 52586 2138 */ {0x1f28, 0x8802},
547 /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
548 /* 52611 2139 */ {0x0010, 0x8801},
549 /* SSI reg addr */
550 /* 52636 2140 */ {0x003e, 0x8800},
551 /* SSI data to write */
552 /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
553 /* 52685 2142 */ {0x0028, 0x8802},
554 /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
555 /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
556 /* 52758 2145 */ {0x1f28, 0x8802},
557 /* 52783 2146 */ {0x0000, 0x8801},
558 /* 52808 2147 */ {0x001f, 0x8800},
559 /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
560 /* 52857 2149 */ {0x0001, 0x8602},
561 /* optical black level for user settning = 1 */
562 482
563 /* Original: */ 483 /* Original: */
564 /* 52882 2150 */ {0x0023, 0x8700}, 484 {0x0023, 0x8700}, /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
565 /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ 485 {0x000f, 0x8602}, /* optical black level for user settning = 15 */
566 /* 52907 2151 */ {0x000f, 0x8602}, 486
567 /* optical black level for user settning = 15 */ 487 {0x0028, 0x8802},
568 488 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
569 /* 52932 2152 */ {0x0028, 0x8802}, 489 /* READ { 0x0001, 0x8802 } -> 0000: 28 */
570 /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 490 {0x1f28, 0x8802},
571 /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ 491 {0x0010, 0x8801},
572 /* 53005 2155 */ {0x1f28, 0x8802}, 492 {0x007b, 0x8800},
573 /* 53030 2156 */ {0x0010, 0x8801}, 493 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
574 /* 53055 2157 */ {0x007b, 0x8800}, 494 {0x002f, 0x8651}, /* R gain for white balance ... */
575 /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ 495 {0x0080, 0x8653},
576 /* 53104 2159 */ {0x002f, 0x8651}, 496 /* READ { 0x0000, 0x8655 } -> 0000: 00 */
577 /* R gain for white balance ... */ 497 {0x0000, 0x8655},
578 /* 53129 2160 */ {0x0080, 0x8653}, 498
579 /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ 499 {0x0030, 0x8112}, /* Video drop enable, ISO streaming enable */
580 /* 53178 2162 */ {0x0000, 0x8655}, 500 {0x0020, 0x8112}, /* Video drop enable, ISO streaming disable */
581 501 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
582 /* 53203 2163 */ {0x0030, 0x8112},
583 /* Video drop enable, ISO streaming enable */
584 /* 53228 2164 */ {0x0020, 0x8112},
585 /* Video drop enable, ISO streaming disable */
586 /* 53252 2165 */
587 /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
588 {} 502 {}
589}; 503};
590 504
@@ -592,27 +506,27 @@ static const u16 spca508_init_data[][2] =
592 * Initialization data for Intel EasyPC Camera CS110 506 * Initialization data for Intel EasyPC Camera CS110
593 */ 507 */
594static const u16 spca508cs110_init_data[][2] = { 508static const u16 spca508cs110_init_data[][2] = {
595 {0x0000, 0x870b}, /* Reset CTL3 */ 509 {0x0000, 0x870b}, /* Reset CTL3 */
596 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ 510 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
597 {0x0000, 0x8111}, /* Normal operation on reset */ 511 {0x0000, 0x8111}, /* Normal operation on reset */
598 {0x0090, 0x8110}, 512 {0x0090, 0x8110},
599 /* External Clock 2x & Synchronous Serial Interface Output */ 513 /* External Clock 2x & Synchronous Serial Interface Output */
600 {0x0020, 0x8112}, /* Video Drop packet enable */ 514 {0x0020, 0x8112}, /* Video Drop packet enable */
601 {0x0000, 0x8114}, /* Software GPIO output data */ 515 {0x0000, 0x8114}, /* Software GPIO output data */
602 {0x0001, 0x8114}, 516 {0x0001, 0x8114},
603 {0x0001, 0x8114}, 517 {0x0001, 0x8114},
604 {0x0001, 0x8114}, 518 {0x0001, 0x8114},
605 {0x0003, 0x8114}, 519 {0x0003, 0x8114},
606 520
607 /* Initial sequence Synchronous Serial Interface */ 521 /* Initial sequence Synchronous Serial Interface */
608 {0x000f, 0x8402}, /* Memory bank Address */ 522 {0x000f, 0x8402}, /* Memory bank Address */
609 {0x0000, 0x8403}, /* Memory bank Address */ 523 {0x0000, 0x8403}, /* Memory bank Address */
610 {0x00ba, 0x8804}, /* SSI Slave address */ 524 {0x00ba, 0x8804}, /* SSI Slave address */
611 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ 525 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
612 {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ 526 {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */
613 527
614 {0x0001, 0x8801}, 528 {0x0001, 0x8801},
615 {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ 529 {0x000a, 0x8805}, /* a - NWG: Dunno what this is about */
616 {0x0000, 0x8800}, 530 {0x0000, 0x8800},
617 {0x0010, 0x8802}, 531 {0x0010, 0x8802},
618 532
@@ -646,459 +560,459 @@ static const u16 spca508cs110_init_data[][2] = {
646 {0x0000, 0x8800}, 560 {0x0000, 0x8800},
647 {0x0010, 0x8802}, 561 {0x0010, 0x8802},
648 562
649 {0x0002, 0x8704}, /* External input CKIx1 */ 563 {0x0002, 0x8704}, /* External input CKIx1 */
650 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ 564 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
651 {0x009a, 0x8600}, /* Line memory Read Counter (L) */ 565 {0x009a, 0x8600}, /* Line memory Read Counter (L) */
652 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ 566 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
653 {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ 567 {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */
654 {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ 568 {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */
655 569
656 {0x0006, 0x8660}, /* Nibble data + input order */ 570 {0x0006, 0x8660}, /* Nibble data + input order */
657 571
658 {0x000a, 0x8602}, /* Optical black level set to 0x0a */ 572 {0x000a, 0x8602}, /* Optical black level set to 0x0a */
659/* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ 573 {0x0000, 0x8603}, /* Optical black level Offset */
660 574
661/* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ 575/* {0x0000, 0x8611}, * 0 R Offset for white Balance */
662/* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ 576/* {0x0000, 0x8612}, * 1 Gr Offset for white Balance */
663/* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ 577/* {0x0000, 0x8613}, * 1f B Offset for white Balance */
664/* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ 578/* {0x0000, 0x8614}, * f0 Gb Offset for white Balance */
665 579
666 {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ 580 {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */
667 {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ 581 {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */
668 {0x0035, 0x8653}, /* 26 RED gain for white balance */ 582 {0x0035, 0x8653}, /* 26 RED gain for white balance */
669 {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ 583 {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */
670 {0x0041, 0x863f}, 584 {0x0041, 0x863f},
671 /* Fixed Gamma correction enabled (makes colours look better) */ 585 /* Fixed Gamma correction enabled (makes colours look better) */
672 586
673/* 2422 */ {0x0000, 0x8655}, 587 {0x0000, 0x8655},
674 /* High bits for white balance*****brightness control*** */ 588 /* High bits for white balance*****brightness control*** */
675 {} 589 {}
676}; 590};
677 591
678static const u16 spca508_sightcam_init_data[][2] = { 592static const u16 spca508_sightcam_init_data[][2] = {
679/* This line seems to setup the frame/canvas */ 593/* This line seems to setup the frame/canvas */
680 /*368 */ {0x000f, 0x8402}, 594 {0x000f, 0x8402},
681 595
682/* Theese 6 lines are needed to startup the webcam */ 596/* Theese 6 lines are needed to startup the webcam */
683 /*398 */ {0x0090, 0x8110}, 597 {0x0090, 0x8110},
684 /*399 */ {0x0001, 0x8114}, 598 {0x0001, 0x8114},
685 /*400 */ {0x0001, 0x8114}, 599 {0x0001, 0x8114},
686 /*401 */ {0x0001, 0x8114}, 600 {0x0001, 0x8114},
687 /*402 */ {0x0003, 0x8114}, 601 {0x0003, 0x8114},
688 /*403 */ {0x0080, 0x8804}, 602 {0x0080, 0x8804},
689 603
690/* This part seems to make the pictures darker? (autobrightness?) */ 604/* This part seems to make the pictures darker? (autobrightness?) */
691 /*436 */ {0x0001, 0x8801}, 605 {0x0001, 0x8801},
692 /*437 */ {0x0004, 0x8800}, 606 {0x0004, 0x8800},
693 /*439 */ {0x0003, 0x8801}, 607 {0x0003, 0x8801},
694 /*440 */ {0x00e0, 0x8800}, 608 {0x00e0, 0x8800},
695 /*442 */ {0x0004, 0x8801}, 609 {0x0004, 0x8801},
696 /*443 */ {0x00b4, 0x8800}, 610 {0x00b4, 0x8800},
697 /*445 */ {0x0005, 0x8801}, 611 {0x0005, 0x8801},
698 /*446 */ {0x0000, 0x8800}, 612 {0x0000, 0x8800},
699 613
700 /*448 */ {0x0006, 0x8801}, 614 {0x0006, 0x8801},
701 /*449 */ {0x00e0, 0x8800}, 615 {0x00e0, 0x8800},
702 /*451 */ {0x0007, 0x8801}, 616 {0x0007, 0x8801},
703 /*452 */ {0x000c, 0x8800}, 617 {0x000c, 0x8800},
704 618
705/* This section is just needed, it probably 619/* This section is just needed, it probably
706 * does something like the previous section, 620 * does something like the previous section,
707 * but the cam won't start if it's not included. 621 * but the cam won't start if it's not included.
708 */ 622 */
709 /*484 */ {0x0014, 0x8801}, 623 {0x0014, 0x8801},
710 /*485 */ {0x0008, 0x8800}, 624 {0x0008, 0x8800},
711 /*487 */ {0x0015, 0x8801}, 625 {0x0015, 0x8801},
712 /*488 */ {0x0067, 0x8800}, 626 {0x0067, 0x8800},
713 /*490 */ {0x0016, 0x8801}, 627 {0x0016, 0x8801},
714 /*491 */ {0x0000, 0x8800}, 628 {0x0000, 0x8800},
715 /*493 */ {0x0017, 0x8801}, 629 {0x0017, 0x8801},
716 /*494 */ {0x0020, 0x8800}, 630 {0x0020, 0x8800},
717 /*496 */ {0x0018, 0x8801}, 631 {0x0018, 0x8801},
718 /*497 */ {0x0044, 0x8800}, 632 {0x0044, 0x8800},
719 633
720/* Makes the picture darker - and the 634/* Makes the picture darker - and the
721 * cam won't start if not included 635 * cam won't start if not included
722 */ 636 */
723 /*505 */ {0x001e, 0x8801}, 637 {0x001e, 0x8801},
724 /*506 */ {0x00ea, 0x8800}, 638 {0x00ea, 0x8800},
725 /*508 */ {0x001f, 0x8801}, 639 {0x001f, 0x8801},
726 /*509 */ {0x0001, 0x8800}, 640 {0x0001, 0x8800},
727 /*511 */ {0x0003, 0x8801}, 641 {0x0003, 0x8801},
728 /*512 */ {0x00e0, 0x8800}, 642 {0x00e0, 0x8800},
729 643
730/* seems to place the colors ontop of each other #1 */ 644/* seems to place the colors ontop of each other #1 */
731 /*517 */ {0x0006, 0x8704}, 645 {0x0006, 0x8704},
732 /*518 */ {0x0001, 0x870c}, 646 {0x0001, 0x870c},
733 /*519 */ {0x0016, 0x8600}, 647 {0x0016, 0x8600},
734 /*520 */ {0x0002, 0x8606}, 648 {0x0002, 0x8606},
735 649
736/* if not included the pictures becomes _very_ dark */ 650/* if not included the pictures becomes _very_ dark */
737 /*521 */ {0x0064, 0x8607}, 651 {0x0064, 0x8607},
738 /*522 */ {0x003a, 0x8601}, 652 {0x003a, 0x8601},
739 /*523 */ {0x0000, 0x8602}, 653 {0x0000, 0x8602},
740 654
741/* seems to place the colors ontop of each other #2 */ 655/* seems to place the colors ontop of each other #2 */
742 /*524 */ {0x0016, 0x8600}, 656 {0x0016, 0x8600},
743 /*525 */ {0x0018, 0x8617}, 657 {0x0018, 0x8617},
744 /*526 */ {0x0008, 0x8618}, 658 {0x0008, 0x8618},
745 /*527 */ {0x00a1, 0x8656}, 659 {0x00a1, 0x8656},
746 660
747/* webcam won't start if not included */ 661/* webcam won't start if not included */
748 /*528 */ {0x0007, 0x865b}, 662 {0x0007, 0x865b},
749 /*529 */ {0x0001, 0x865c}, 663 {0x0001, 0x865c},
750 /*530 */ {0x0058, 0x865d}, 664 {0x0058, 0x865d},
751 /*531 */ {0x0048, 0x865e}, 665 {0x0048, 0x865e},
752 666
753/* adjusts the colors */ 667/* adjusts the colors */
754 /*541 */ {0x0049, 0x8651}, 668 {0x0049, 0x8651},
755 /*542 */ {0x0040, 0x8652}, 669 {0x0040, 0x8652},
756 /*543 */ {0x004c, 0x8653}, 670 {0x004c, 0x8653},
757 /*544 */ {0x0040, 0x8654}, 671 {0x0040, 0x8654},
758 {} 672 {}
759}; 673};
760 674
761static const u16 spca508_sightcam2_init_data[][2] = { 675static const u16 spca508_sightcam2_init_data[][2] = {
762/* 35 */ {0x0020, 0x8112}, 676 {0x0020, 0x8112},
763 677
764/* 36 */ {0x000f, 0x8402}, 678 {0x000f, 0x8402},
765/* 37 */ {0x0000, 0x8403}, 679 {0x0000, 0x8403},
766 680
767/* 38 */ {0x0008, 0x8201}, 681 {0x0008, 0x8201},
768/* 39 */ {0x0008, 0x8200}, 682 {0x0008, 0x8200},
769/* 40 */ {0x0001, 0x8200}, 683 {0x0001, 0x8200},
770/* 43 */ {0x0009, 0x8201}, 684 {0x0009, 0x8201},
771/* 44 */ {0x0008, 0x8200}, 685 {0x0008, 0x8200},
772/* 45 */ {0x0001, 0x8200}, 686 {0x0001, 0x8200},
773/* 48 */ {0x000a, 0x8201}, 687 {0x000a, 0x8201},
774/* 49 */ {0x0008, 0x8200}, 688 {0x0008, 0x8200},
775/* 50 */ {0x0001, 0x8200}, 689 {0x0001, 0x8200},
776/* 53 */ {0x000b, 0x8201}, 690 {0x000b, 0x8201},
777/* 54 */ {0x0008, 0x8200}, 691 {0x0008, 0x8200},
778/* 55 */ {0x0001, 0x8200}, 692 {0x0001, 0x8200},
779/* 58 */ {0x000c, 0x8201}, 693 {0x000c, 0x8201},
780/* 59 */ {0x0008, 0x8200}, 694 {0x0008, 0x8200},
781/* 60 */ {0x0001, 0x8200}, 695 {0x0001, 0x8200},
782/* 63 */ {0x000d, 0x8201}, 696 {0x000d, 0x8201},
783/* 64 */ {0x0008, 0x8200}, 697 {0x0008, 0x8200},
784/* 65 */ {0x0001, 0x8200}, 698 {0x0001, 0x8200},
785/* 68 */ {0x000e, 0x8201}, 699 {0x000e, 0x8201},
786/* 69 */ {0x0008, 0x8200}, 700 {0x0008, 0x8200},
787/* 70 */ {0x0001, 0x8200}, 701 {0x0001, 0x8200},
788/* 73 */ {0x0007, 0x8201}, 702 {0x0007, 0x8201},
789/* 74 */ {0x0008, 0x8200}, 703 {0x0008, 0x8200},
790/* 75 */ {0x0001, 0x8200}, 704 {0x0001, 0x8200},
791/* 78 */ {0x000f, 0x8201}, 705 {0x000f, 0x8201},
792/* 79 */ {0x0008, 0x8200}, 706 {0x0008, 0x8200},
793/* 80 */ {0x0001, 0x8200}, 707 {0x0001, 0x8200},
794 708
795/* 84 */ {0x0018, 0x8660}, 709 {0x0018, 0x8660},
796/* 85 */ {0x0010, 0x8201}, 710 {0x0010, 0x8201},
797 711
798/* 86 */ {0x0008, 0x8200}, 712 {0x0008, 0x8200},
799/* 87 */ {0x0001, 0x8200}, 713 {0x0001, 0x8200},
800/* 90 */ {0x0011, 0x8201}, 714 {0x0011, 0x8201},
801/* 91 */ {0x0008, 0x8200}, 715 {0x0008, 0x8200},
802/* 92 */ {0x0001, 0x8200}, 716 {0x0001, 0x8200},
803 717
804/* 95 */ {0x0000, 0x86b0}, 718 {0x0000, 0x86b0},
805/* 96 */ {0x0034, 0x86b1}, 719 {0x0034, 0x86b1},
806/* 97 */ {0x0000, 0x86b2}, 720 {0x0000, 0x86b2},
807/* 98 */ {0x0049, 0x86b3}, 721 {0x0049, 0x86b3},
808/* 99 */ {0x0000, 0x86b4}, 722 {0x0000, 0x86b4},
809/* 100 */ {0x0000, 0x86b4}, 723 {0x0000, 0x86b4},
810 724
811/* 101 */ {0x0012, 0x8201}, 725 {0x0012, 0x8201},
812/* 102 */ {0x0008, 0x8200}, 726 {0x0008, 0x8200},
813/* 103 */ {0x0001, 0x8200}, 727 {0x0001, 0x8200},
814/* 106 */ {0x0013, 0x8201}, 728 {0x0013, 0x8201},
815/* 107 */ {0x0008, 0x8200}, 729 {0x0008, 0x8200},
816/* 108 */ {0x0001, 0x8200}, 730 {0x0001, 0x8200},
817 731
818/* 111 */ {0x0001, 0x86b0}, 732 {0x0001, 0x86b0},
819/* 112 */ {0x00aa, 0x86b1}, 733 {0x00aa, 0x86b1},
820/* 113 */ {0x0000, 0x86b2}, 734 {0x0000, 0x86b2},
821/* 114 */ {0x00e4, 0x86b3}, 735 {0x00e4, 0x86b3},
822/* 115 */ {0x0000, 0x86b4}, 736 {0x0000, 0x86b4},
823/* 116 */ {0x0000, 0x86b4}, 737 {0x0000, 0x86b4},
824 738
825/* 118 */ {0x0018, 0x8660}, 739 {0x0018, 0x8660},
826 740
827/* 119 */ {0x0090, 0x8110}, 741 {0x0090, 0x8110},
828/* 120 */ {0x0001, 0x8114}, 742 {0x0001, 0x8114},
829/* 121 */ {0x0001, 0x8114}, 743 {0x0001, 0x8114},
830/* 122 */ {0x0001, 0x8114}, 744 {0x0001, 0x8114},
831/* 123 */ {0x0003, 0x8114}, 745 {0x0003, 0x8114},
832 746
833/* 124 */ {0x0080, 0x8804}, 747 {0x0080, 0x8804},
834/* 157 */ {0x0003, 0x8801}, 748 {0x0003, 0x8801},
835/* 158 */ {0x0012, 0x8800}, 749 {0x0012, 0x8800},
836/* 160 */ {0x0004, 0x8801}, 750 {0x0004, 0x8801},
837/* 161 */ {0x0005, 0x8800}, 751 {0x0005, 0x8800},
838/* 163 */ {0x0005, 0x8801}, 752 {0x0005, 0x8801},
839/* 164 */ {0x0000, 0x8800}, 753 {0x0000, 0x8800},
840/* 166 */ {0x0006, 0x8801}, 754 {0x0006, 0x8801},
841/* 167 */ {0x0000, 0x8800}, 755 {0x0000, 0x8800},
842/* 169 */ {0x0007, 0x8801}, 756 {0x0007, 0x8801},
843/* 170 */ {0x0000, 0x8800}, 757 {0x0000, 0x8800},
844/* 172 */ {0x0008, 0x8801}, 758 {0x0008, 0x8801},
845/* 173 */ {0x0005, 0x8800}, 759 {0x0005, 0x8800},
846/* 175 */ {0x000a, 0x8700}, 760 {0x000a, 0x8700},
847/* 176 */ {0x000e, 0x8801}, 761 {0x000e, 0x8801},
848/* 177 */ {0x0004, 0x8800}, 762 {0x0004, 0x8800},
849/* 179 */ {0x0005, 0x8801}, 763 {0x0005, 0x8801},
850/* 180 */ {0x0047, 0x8800}, 764 {0x0047, 0x8800},
851/* 182 */ {0x0006, 0x8801}, 765 {0x0006, 0x8801},
852/* 183 */ {0x0000, 0x8800}, 766 {0x0000, 0x8800},
853/* 185 */ {0x0007, 0x8801}, 767 {0x0007, 0x8801},
854/* 186 */ {0x00c0, 0x8800}, 768 {0x00c0, 0x8800},
855/* 188 */ {0x0008, 0x8801}, 769 {0x0008, 0x8801},
856/* 189 */ {0x0003, 0x8800}, 770 {0x0003, 0x8800},
857/* 191 */ {0x0013, 0x8801}, 771 {0x0013, 0x8801},
858/* 192 */ {0x0001, 0x8800}, 772 {0x0001, 0x8800},
859/* 194 */ {0x0009, 0x8801}, 773 {0x0009, 0x8801},
860/* 195 */ {0x0000, 0x8800}, 774 {0x0000, 0x8800},
861/* 197 */ {0x000a, 0x8801}, 775 {0x000a, 0x8801},
862/* 198 */ {0x0000, 0x8800}, 776 {0x0000, 0x8800},
863/* 200 */ {0x000b, 0x8801}, 777 {0x000b, 0x8801},
864/* 201 */ {0x0000, 0x8800}, 778 {0x0000, 0x8800},
865/* 203 */ {0x000c, 0x8801}, 779 {0x000c, 0x8801},
866/* 204 */ {0x0000, 0x8800}, 780 {0x0000, 0x8800},
867/* 206 */ {0x000e, 0x8801}, 781 {0x000e, 0x8801},
868/* 207 */ {0x0004, 0x8800}, 782 {0x0004, 0x8800},
869/* 209 */ {0x000f, 0x8801}, 783 {0x000f, 0x8801},
870/* 210 */ {0x0000, 0x8800}, 784 {0x0000, 0x8800},
871/* 212 */ {0x0010, 0x8801}, 785 {0x0010, 0x8801},
872/* 213 */ {0x0006, 0x8800}, 786 {0x0006, 0x8800},
873/* 215 */ {0x0011, 0x8801}, 787 {0x0011, 0x8801},
874/* 216 */ {0x0006, 0x8800}, 788 {0x0006, 0x8800},
875/* 218 */ {0x0012, 0x8801}, 789 {0x0012, 0x8801},
876/* 219 */ {0x0000, 0x8800}, 790 {0x0000, 0x8800},
877/* 221 */ {0x0013, 0x8801}, 791 {0x0013, 0x8801},
878/* 222 */ {0x0001, 0x8800}, 792 {0x0001, 0x8800},
879 793
880/* 224 */ {0x000a, 0x8700}, 794 {0x000a, 0x8700},
881/* 225 */ {0x0000, 0x8702}, 795 {0x0000, 0x8702},
882/* 226 */ {0x0000, 0x8703}, 796 {0x0000, 0x8703},
883/* 227 */ {0x00c2, 0x8704}, 797 {0x00c2, 0x8704},
884/* 228 */ {0x0001, 0x870c}, 798 {0x0001, 0x870c},
885 799
886/* 229 */ {0x0044, 0x8600}, 800 {0x0044, 0x8600},
887/* 230 */ {0x0002, 0x8606}, 801 {0x0002, 0x8606},
888/* 231 */ {0x0064, 0x8607}, 802 {0x0064, 0x8607},
889/* 232 */ {0x003a, 0x8601}, 803 {0x003a, 0x8601},
890/* 233 */ {0x0008, 0x8602}, 804 {0x0008, 0x8602},
891/* 234 */ {0x0044, 0x8600}, 805 {0x0044, 0x8600},
892/* 235 */ {0x0018, 0x8617}, 806 {0x0018, 0x8617},
893/* 236 */ {0x0008, 0x8618}, 807 {0x0008, 0x8618},
894/* 237 */ {0x00a1, 0x8656}, 808 {0x00a1, 0x8656},
895/* 238 */ {0x0004, 0x865b}, 809 {0x0004, 0x865b},
896/* 239 */ {0x0002, 0x865c}, 810 {0x0002, 0x865c},
897/* 240 */ {0x0058, 0x865d}, 811 {0x0058, 0x865d},
898/* 241 */ {0x0048, 0x865e}, 812 {0x0048, 0x865e},
899/* 242 */ {0x0012, 0x8608}, 813 {0x0012, 0x8608},
900/* 243 */ {0x002c, 0x8609}, 814 {0x002c, 0x8609},
901/* 244 */ {0x0002, 0x860a}, 815 {0x0002, 0x860a},
902/* 245 */ {0x002c, 0x860b}, 816 {0x002c, 0x860b},
903/* 246 */ {0x00db, 0x860c}, 817 {0x00db, 0x860c},
904/* 247 */ {0x00f9, 0x860d}, 818 {0x00f9, 0x860d},
905/* 248 */ {0x00f1, 0x860e}, 819 {0x00f1, 0x860e},
906/* 249 */ {0x00e3, 0x860f}, 820 {0x00e3, 0x860f},
907/* 250 */ {0x002c, 0x8610}, 821 {0x002c, 0x8610},
908/* 251 */ {0x006c, 0x8651}, 822 {0x006c, 0x8651},
909/* 252 */ {0x0041, 0x8652}, 823 {0x0041, 0x8652},
910/* 253 */ {0x0059, 0x8653}, 824 {0x0059, 0x8653},
911/* 254 */ {0x0040, 0x8654}, 825 {0x0040, 0x8654},
912/* 255 */ {0x00fa, 0x8611}, 826 {0x00fa, 0x8611},
913/* 256 */ {0x00ff, 0x8612}, 827 {0x00ff, 0x8612},
914/* 257 */ {0x00f8, 0x8613}, 828 {0x00f8, 0x8613},
915/* 258 */ {0x0000, 0x8614}, 829 {0x0000, 0x8614},
916/* 259 */ {0x0001, 0x863f}, 830 {0x0001, 0x863f},
917/* 260 */ {0x0000, 0x8640}, 831 {0x0000, 0x8640},
918/* 261 */ {0x0026, 0x8641}, 832 {0x0026, 0x8641},
919/* 262 */ {0x0045, 0x8642}, 833 {0x0045, 0x8642},
920/* 263 */ {0x0060, 0x8643}, 834 {0x0060, 0x8643},
921/* 264 */ {0x0075, 0x8644}, 835 {0x0075, 0x8644},
922/* 265 */ {0x0088, 0x8645}, 836 {0x0088, 0x8645},
923/* 266 */ {0x009b, 0x8646}, 837 {0x009b, 0x8646},
924/* 267 */ {0x00b0, 0x8647}, 838 {0x00b0, 0x8647},
925/* 268 */ {0x00c5, 0x8648}, 839 {0x00c5, 0x8648},
926/* 269 */ {0x00d2, 0x8649}, 840 {0x00d2, 0x8649},
927/* 270 */ {0x00dc, 0x864a}, 841 {0x00dc, 0x864a},
928/* 271 */ {0x00e5, 0x864b}, 842 {0x00e5, 0x864b},
929/* 272 */ {0x00eb, 0x864c}, 843 {0x00eb, 0x864c},
930/* 273 */ {0x00f0, 0x864d}, 844 {0x00f0, 0x864d},
931/* 274 */ {0x00f6, 0x864e}, 845 {0x00f6, 0x864e},
932/* 275 */ {0x00fa, 0x864f}, 846 {0x00fa, 0x864f},
933/* 276 */ {0x00ff, 0x8650}, 847 {0x00ff, 0x8650},
934/* 277 */ {0x0060, 0x8657}, 848 {0x0060, 0x8657},
935/* 278 */ {0x0010, 0x8658}, 849 {0x0010, 0x8658},
936/* 279 */ {0x0018, 0x8659}, 850 {0x0018, 0x8659},
937/* 280 */ {0x0005, 0x865a}, 851 {0x0005, 0x865a},
938/* 281 */ {0x0018, 0x8660}, 852 {0x0018, 0x8660},
939/* 282 */ {0x0003, 0x8509}, 853 {0x0003, 0x8509},
940/* 283 */ {0x0011, 0x850a}, 854 {0x0011, 0x850a},
941/* 284 */ {0x0032, 0x850b}, 855 {0x0032, 0x850b},
942/* 285 */ {0x0010, 0x850c}, 856 {0x0010, 0x850c},
943/* 286 */ {0x0021, 0x850d}, 857 {0x0021, 0x850d},
944/* 287 */ {0x0001, 0x8500}, 858 {0x0001, 0x8500},
945/* 288 */ {0x0000, 0x8508}, 859 {0x0000, 0x8508},
946/* 289 */ {0x0012, 0x8608}, 860 {0x0012, 0x8608},
947/* 290 */ {0x002c, 0x8609}, 861 {0x002c, 0x8609},
948/* 291 */ {0x0002, 0x860a}, 862 {0x0002, 0x860a},
949/* 292 */ {0x0039, 0x860b}, 863 {0x0039, 0x860b},
950/* 293 */ {0x00d0, 0x860c}, 864 {0x00d0, 0x860c},
951/* 294 */ {0x00f7, 0x860d}, 865 {0x00f7, 0x860d},
952/* 295 */ {0x00ed, 0x860e}, 866 {0x00ed, 0x860e},
953/* 296 */ {0x00db, 0x860f}, 867 {0x00db, 0x860f},
954/* 297 */ {0x0039, 0x8610}, 868 {0x0039, 0x8610},
955/* 298 */ {0x0012, 0x8657}, 869 {0x0012, 0x8657},
956/* 299 */ {0x000c, 0x8619}, 870 {0x000c, 0x8619},
957/* 300 */ {0x0004, 0x861a}, 871 {0x0004, 0x861a},
958/* 301 */ {0x00a1, 0x8656}, 872 {0x00a1, 0x8656},
959/* 302 */ {0x00c8, 0x8615}, 873 {0x00c8, 0x8615},
960/* 303 */ {0x0032, 0x8616}, 874 {0x0032, 0x8616},
961 875
962/* 306 */ {0x0030, 0x8112}, 876 {0x0030, 0x8112},
963/* 313 */ {0x0020, 0x8112}, 877 {0x0020, 0x8112},
964/* 314 */ {0x0020, 0x8112}, 878 {0x0020, 0x8112},
965/* 315 */ {0x000f, 0x8402}, 879 {0x000f, 0x8402},
966/* 316 */ {0x0000, 0x8403}, 880 {0x0000, 0x8403},
967 881
968/* 317 */ {0x0090, 0x8110}, 882 {0x0090, 0x8110},
969/* 318 */ {0x0001, 0x8114}, 883 {0x0001, 0x8114},
970/* 319 */ {0x0001, 0x8114}, 884 {0x0001, 0x8114},
971/* 320 */ {0x0001, 0x8114}, 885 {0x0001, 0x8114},
972/* 321 */ {0x0003, 0x8114}, 886 {0x0003, 0x8114},
973/* 322 */ {0x0080, 0x8804}, 887 {0x0080, 0x8804},
974 888
975/* 355 */ {0x0003, 0x8801}, 889 {0x0003, 0x8801},
976/* 356 */ {0x0012, 0x8800}, 890 {0x0012, 0x8800},
977/* 358 */ {0x0004, 0x8801}, 891 {0x0004, 0x8801},
978/* 359 */ {0x0005, 0x8800}, 892 {0x0005, 0x8800},
979/* 361 */ {0x0005, 0x8801}, 893 {0x0005, 0x8801},
980/* 362 */ {0x0047, 0x8800}, 894 {0x0047, 0x8800},
981/* 364 */ {0x0006, 0x8801}, 895 {0x0006, 0x8801},
982/* 365 */ {0x0000, 0x8800}, 896 {0x0000, 0x8800},
983/* 367 */ {0x0007, 0x8801}, 897 {0x0007, 0x8801},
984/* 368 */ {0x00c0, 0x8800}, 898 {0x00c0, 0x8800},
985/* 370 */ {0x0008, 0x8801}, 899 {0x0008, 0x8801},
986/* 371 */ {0x0003, 0x8800}, 900 {0x0003, 0x8800},
987/* 373 */ {0x000a, 0x8700}, 901 {0x000a, 0x8700},
988/* 374 */ {0x000e, 0x8801}, 902 {0x000e, 0x8801},
989/* 375 */ {0x0004, 0x8800}, 903 {0x0004, 0x8800},
990/* 377 */ {0x0005, 0x8801}, 904 {0x0005, 0x8801},
991/* 378 */ {0x0047, 0x8800}, 905 {0x0047, 0x8800},
992/* 380 */ {0x0006, 0x8801}, 906 {0x0006, 0x8801},
993/* 381 */ {0x0000, 0x8800}, 907 {0x0000, 0x8800},
994/* 383 */ {0x0007, 0x8801}, 908 {0x0007, 0x8801},
995/* 384 */ {0x00c0, 0x8800}, 909 {0x00c0, 0x8800},
996/* 386 */ {0x0008, 0x8801}, 910 {0x0008, 0x8801},
997/* 387 */ {0x0003, 0x8800}, 911 {0x0003, 0x8800},
998/* 389 */ {0x0013, 0x8801}, 912 {0x0013, 0x8801},
999/* 390 */ {0x0001, 0x8800}, 913 {0x0001, 0x8800},
1000/* 392 */ {0x0009, 0x8801}, 914 {0x0009, 0x8801},
1001/* 393 */ {0x0000, 0x8800}, 915 {0x0000, 0x8800},
1002/* 395 */ {0x000a, 0x8801}, 916 {0x000a, 0x8801},
1003/* 396 */ {0x0000, 0x8800}, 917 {0x0000, 0x8800},
1004/* 398 */ {0x000b, 0x8801}, 918 {0x000b, 0x8801},
1005/* 399 */ {0x0000, 0x8800}, 919 {0x0000, 0x8800},
1006/* 401 */ {0x000c, 0x8801}, 920 {0x000c, 0x8801},
1007/* 402 */ {0x0000, 0x8800}, 921 {0x0000, 0x8800},
1008/* 404 */ {0x000e, 0x8801}, 922 {0x000e, 0x8801},
1009/* 405 */ {0x0004, 0x8800}, 923 {0x0004, 0x8800},
1010/* 407 */ {0x000f, 0x8801}, 924 {0x000f, 0x8801},
1011/* 408 */ {0x0000, 0x8800}, 925 {0x0000, 0x8800},
1012/* 410 */ {0x0010, 0x8801}, 926 {0x0010, 0x8801},
1013/* 411 */ {0x0006, 0x8800}, 927 {0x0006, 0x8800},
1014/* 413 */ {0x0011, 0x8801}, 928 {0x0011, 0x8801},
1015/* 414 */ {0x0006, 0x8800}, 929 {0x0006, 0x8800},
1016/* 416 */ {0x0012, 0x8801}, 930 {0x0012, 0x8801},
1017/* 417 */ {0x0000, 0x8800}, 931 {0x0000, 0x8800},
1018/* 419 */ {0x0013, 0x8801}, 932 {0x0013, 0x8801},
1019/* 420 */ {0x0001, 0x8800}, 933 {0x0001, 0x8800},
1020/* 422 */ {0x000a, 0x8700}, 934 {0x000a, 0x8700},
1021/* 423 */ {0x0000, 0x8702}, 935 {0x0000, 0x8702},
1022/* 424 */ {0x0000, 0x8703}, 936 {0x0000, 0x8703},
1023/* 425 */ {0x00c2, 0x8704}, 937 {0x00c2, 0x8704},
1024/* 426 */ {0x0001, 0x870c}, 938 {0x0001, 0x870c},
1025/* 427 */ {0x0044, 0x8600}, 939 {0x0044, 0x8600},
1026/* 428 */ {0x0002, 0x8606}, 940 {0x0002, 0x8606},
1027/* 429 */ {0x0064, 0x8607}, 941 {0x0064, 0x8607},
1028/* 430 */ {0x003a, 0x8601}, 942 {0x003a, 0x8601},
1029/* 431 */ {0x0008, 0x8602}, 943 {0x0008, 0x8602},
1030/* 432 */ {0x0044, 0x8600}, 944 {0x0044, 0x8600},
1031/* 433 */ {0x0018, 0x8617}, 945 {0x0018, 0x8617},
1032/* 434 */ {0x0008, 0x8618}, 946 {0x0008, 0x8618},
1033/* 435 */ {0x00a1, 0x8656}, 947 {0x00a1, 0x8656},
1034/* 436 */ {0x0004, 0x865b}, 948 {0x0004, 0x865b},
1035/* 437 */ {0x0002, 0x865c}, 949 {0x0002, 0x865c},
1036/* 438 */ {0x0058, 0x865d}, 950 {0x0058, 0x865d},
1037/* 439 */ {0x0048, 0x865e}, 951 {0x0048, 0x865e},
1038/* 440 */ {0x0012, 0x8608}, 952 {0x0012, 0x8608},
1039/* 441 */ {0x002c, 0x8609}, 953 {0x002c, 0x8609},
1040/* 442 */ {0x0002, 0x860a}, 954 {0x0002, 0x860a},
1041/* 443 */ {0x002c, 0x860b}, 955 {0x002c, 0x860b},
1042/* 444 */ {0x00db, 0x860c}, 956 {0x00db, 0x860c},
1043/* 445 */ {0x00f9, 0x860d}, 957 {0x00f9, 0x860d},
1044/* 446 */ {0x00f1, 0x860e}, 958 {0x00f1, 0x860e},
1045/* 447 */ {0x00e3, 0x860f}, 959 {0x00e3, 0x860f},
1046/* 448 */ {0x002c, 0x8610}, 960 {0x002c, 0x8610},
1047/* 449 */ {0x006c, 0x8651}, 961 {0x006c, 0x8651},
1048/* 450 */ {0x0041, 0x8652}, 962 {0x0041, 0x8652},
1049/* 451 */ {0x0059, 0x8653}, 963 {0x0059, 0x8653},
1050/* 452 */ {0x0040, 0x8654}, 964 {0x0040, 0x8654},
1051/* 453 */ {0x00fa, 0x8611}, 965 {0x00fa, 0x8611},
1052/* 454 */ {0x00ff, 0x8612}, 966 {0x00ff, 0x8612},
1053/* 455 */ {0x00f8, 0x8613}, 967 {0x00f8, 0x8613},
1054/* 456 */ {0x0000, 0x8614}, 968 {0x0000, 0x8614},
1055/* 457 */ {0x0001, 0x863f}, 969 {0x0001, 0x863f},
1056/* 458 */ {0x0000, 0x8640}, 970 {0x0000, 0x8640},
1057/* 459 */ {0x0026, 0x8641}, 971 {0x0026, 0x8641},
1058/* 460 */ {0x0045, 0x8642}, 972 {0x0045, 0x8642},
1059/* 461 */ {0x0060, 0x8643}, 973 {0x0060, 0x8643},
1060/* 462 */ {0x0075, 0x8644}, 974 {0x0075, 0x8644},
1061/* 463 */ {0x0088, 0x8645}, 975 {0x0088, 0x8645},
1062/* 464 */ {0x009b, 0x8646}, 976 {0x009b, 0x8646},
1063/* 465 */ {0x00b0, 0x8647}, 977 {0x00b0, 0x8647},
1064/* 466 */ {0x00c5, 0x8648}, 978 {0x00c5, 0x8648},
1065/* 467 */ {0x00d2, 0x8649}, 979 {0x00d2, 0x8649},
1066/* 468 */ {0x00dc, 0x864a}, 980 {0x00dc, 0x864a},
1067/* 469 */ {0x00e5, 0x864b}, 981 {0x00e5, 0x864b},
1068/* 470 */ {0x00eb, 0x864c}, 982 {0x00eb, 0x864c},
1069/* 471 */ {0x00f0, 0x864d}, 983 {0x00f0, 0x864d},
1070/* 472 */ {0x00f6, 0x864e}, 984 {0x00f6, 0x864e},
1071/* 473 */ {0x00fa, 0x864f}, 985 {0x00fa, 0x864f},
1072/* 474 */ {0x00ff, 0x8650}, 986 {0x00ff, 0x8650},
1073/* 475 */ {0x0060, 0x8657}, 987 {0x0060, 0x8657},
1074/* 476 */ {0x0010, 0x8658}, 988 {0x0010, 0x8658},
1075/* 477 */ {0x0018, 0x8659}, 989 {0x0018, 0x8659},
1076/* 478 */ {0x0005, 0x865a}, 990 {0x0005, 0x865a},
1077/* 479 */ {0x0018, 0x8660}, 991 {0x0018, 0x8660},
1078/* 480 */ {0x0003, 0x8509}, 992 {0x0003, 0x8509},
1079/* 481 */ {0x0011, 0x850a}, 993 {0x0011, 0x850a},
1080/* 482 */ {0x0032, 0x850b}, 994 {0x0032, 0x850b},
1081/* 483 */ {0x0010, 0x850c}, 995 {0x0010, 0x850c},
1082/* 484 */ {0x0021, 0x850d}, 996 {0x0021, 0x850d},
1083/* 485 */ {0x0001, 0x8500}, 997 {0x0001, 0x8500},
1084/* 486 */ {0x0000, 0x8508}, 998 {0x0000, 0x8508},
1085 999
1086/* 487 */ {0x0012, 0x8608}, 1000 {0x0012, 0x8608},
1087/* 488 */ {0x002c, 0x8609}, 1001 {0x002c, 0x8609},
1088/* 489 */ {0x0002, 0x860a}, 1002 {0x0002, 0x860a},
1089/* 490 */ {0x0039, 0x860b}, 1003 {0x0039, 0x860b},
1090/* 491 */ {0x00d0, 0x860c}, 1004 {0x00d0, 0x860c},
1091/* 492 */ {0x00f7, 0x860d}, 1005 {0x00f7, 0x860d},
1092/* 493 */ {0x00ed, 0x860e}, 1006 {0x00ed, 0x860e},
1093/* 494 */ {0x00db, 0x860f}, 1007 {0x00db, 0x860f},
1094/* 495 */ {0x0039, 0x8610}, 1008 {0x0039, 0x8610},
1095/* 496 */ {0x0012, 0x8657}, 1009 {0x0012, 0x8657},
1096/* 497 */ {0x0064, 0x8619}, 1010 {0x0064, 0x8619},
1097 1011
1098/* This line starts it all, it is not needed here */ 1012/* This line starts it all, it is not needed here */
1099/* since it has been build into the driver */ 1013/* since it has been build into the driver */
1100/* jfm: don't start now */ 1014/* jfm: don't start now */
1101/* 590 * {0x0030, 0x8112}, */ 1015/* {0x0030, 0x8112}, */
1102 {} 1016 {}
1103}; 1017};
1104 1018
@@ -1109,14 +1023,14 @@ static const u16 spca508_vista_init_data[][2] = {
1109 {0x0008, 0x8200}, /* Clear register */ 1023 {0x0008, 0x8200}, /* Clear register */
1110 {0x0000, 0x870b}, /* Reset CTL3 */ 1024 {0x0000, 0x870b}, /* Reset CTL3 */
1111 {0x0020, 0x8112}, /* Video Drop packet enable */ 1025 {0x0020, 0x8112}, /* Video Drop packet enable */
1112 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ 1026 {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
1113 {0x0000, 0x8110}, /* Disable everything */ 1027 {0x0000, 0x8110}, /* Disable everything */
1114 {0x0000, 0x8114}, /* Software GPIO output data */ 1028 {0x0000, 0x8114}, /* Software GPIO output data */
1115 {0x0000, 0x8114}, 1029 {0x0000, 0x8114},
1116 1030
1117 {0x0003, 0x8111}, 1031 {0x0003, 0x8111},
1118 {0x0000, 0x8111}, 1032 {0x0000, 0x8111},
1119 {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ 1033 {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */
1120 {0x0020, 0x8112}, 1034 {0x0020, 0x8112},
1121 {0x0000, 0x8114}, 1035 {0x0000, 0x8114},
1122 {0x0001, 0x8114}, 1036 {0x0001, 0x8114},
@@ -1129,191 +1043,143 @@ static const u16 spca508_vista_init_data[][2] = {
1129 {0x00ba, 0x8804}, /* SSI Slave address */ 1043 {0x00ba, 0x8804}, /* SSI Slave address */
1130 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ 1044 {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
1131 1045
1132 /* READ { 0, 0x0001, 0x8803 } -> 1046 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1133 0000: 00 */ 1047 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1134 /* READ { 0, 0x0001, 0x8802 } ->
1135 0000: 10 */
1136 {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ 1048 {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */
1137 {0x0020, 0x8801}, /* Register address for SSI read/write */ 1049 {0x0020, 0x8801}, /* Register address for SSI read/write */
1138 {0x0044, 0x8805}, /* DATA2 */ 1050 {0x0044, 0x8805}, /* DATA2 */
1139 {0x0004, 0x8800}, /* DATA1 -> write triggered */ 1051 {0x0004, 0x8800}, /* DATA1 -> write triggered */
1140 /* READ { 0, 0x0001, 0x8803 } -> 1052 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1141 0000: 00 */
1142 1053
1143 /* READ { 0, 0x0001, 0x8803 } -> 1054 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1144 0000: 00 */ 1055 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1145 /* READ { 0, 0x0001, 0x8802 } ->
1146 0000: 10 */
1147 {0x0010, 0x8802}, 1056 {0x0010, 0x8802},
1148 {0x0009, 0x8801}, 1057 {0x0009, 0x8801},
1149 {0x0042, 0x8805}, 1058 {0x0042, 0x8805},
1150 {0x0001, 0x8800}, 1059 {0x0001, 0x8800},
1151 /* READ { 0, 0x0001, 0x8803 } -> 1060 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1152 0000: 00 */
1153 1061
1154 /* READ { 0, 0x0001, 0x8803 } -> 1062 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1155 0000: 00 */ 1063 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1156 /* READ { 0, 0x0001, 0x8802 } ->
1157 0000: 10 */
1158 {0x0010, 0x8802}, 1064 {0x0010, 0x8802},
1159 {0x003c, 0x8801}, 1065 {0x003c, 0x8801},
1160 {0x0001, 0x8805}, 1066 {0x0001, 0x8805},
1161 {0x0000, 0x8800}, 1067 {0x0000, 0x8800},
1162 /* READ { 0, 0x0001, 0x8803 } -> 1068 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1163 0000: 00 */
1164 1069
1165 /* READ { 0, 0x0001, 0x8803 } -> 1070 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1166 0000: 00 */ 1071 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1167 /* READ { 0, 0x0001, 0x8802 } ->
1168 0000: 10 */
1169 {0x0010, 0x8802}, 1072 {0x0010, 0x8802},
1170 {0x0001, 0x8801}, 1073 {0x0001, 0x8801},
1171 {0x000a, 0x8805}, 1074 {0x000a, 0x8805},
1172 {0x0000, 0x8800}, 1075 {0x0000, 0x8800},
1173 /* READ { 0, 0x0001, 0x8803 } -> 1076 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1174 0000: 00 */
1175 1077
1176 /* READ { 0, 0x0001, 0x8803 } -> 1078 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1177 0000: 00 */ 1079 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1178 /* READ { 0, 0x0001, 0x8802 } ->
1179 0000: 10 */
1180 {0x0010, 0x8802}, 1080 {0x0010, 0x8802},
1181 {0x0002, 0x8801}, 1081 {0x0002, 0x8801},
1182 {0x0000, 0x8805}, 1082 {0x0000, 0x8805},
1183 {0x0000, 0x8800}, 1083 {0x0000, 0x8800},
1184 /* READ { 0, 0x0001, 0x8803 } -> 1084 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1185 0000: 00 */
1186 1085
1187 /* READ { 0, 0x0001, 0x8803 } -> 1086 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1188 0000: 00 */ 1087 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1189 /* READ { 0, 0x0001, 0x8802 } ->
1190 0000: 10 */
1191 {0x0010, 0x8802}, 1088 {0x0010, 0x8802},
1192 {0x0003, 0x8801}, 1089 {0x0003, 0x8801},
1193 {0x0027, 0x8805}, 1090 {0x0027, 0x8805},
1194 {0x0001, 0x8800}, 1091 {0x0001, 0x8800},
1195 /* READ { 0, 0x0001, 0x8803 } -> 1092 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1196 0000: 00 */
1197 1093
1198 /* READ { 0, 0x0001, 0x8803 } -> 1094 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1199 0000: 00 */ 1095 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1200 /* READ { 0, 0x0001, 0x8802 } ->
1201 0000: 10 */
1202 {0x0010, 0x8802}, 1096 {0x0010, 0x8802},
1203 {0x0004, 0x8801}, 1097 {0x0004, 0x8801},
1204 {0x0065, 0x8805}, 1098 {0x0065, 0x8805},
1205 {0x0001, 0x8800}, 1099 {0x0001, 0x8800},
1206 /* READ { 0, 0x0001, 0x8803 } -> 1100 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1207 0000: 00 */
1208 1101
1209 /* READ { 0, 0x0001, 0x8803 } -> 1102 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1210 0000: 00 */ 1103 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1211 /* READ { 0, 0x0001, 0x8802 } ->
1212 0000: 10 */
1213 {0x0010, 0x8802}, 1104 {0x0010, 0x8802},
1214 {0x0005, 0x8801}, 1105 {0x0005, 0x8801},
1215 {0x0003, 0x8805}, 1106 {0x0003, 0x8805},
1216 {0x0000, 0x8800}, 1107 {0x0000, 0x8800},
1217 /* READ { 0, 0x0001, 0x8803 } -> 1108 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1218 0000: 00 */
1219 1109
1220 /* READ { 0, 0x0001, 0x8803 } -> 1110 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1221 0000: 00 */ 1111 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1222 /* READ { 0, 0x0001, 0x8802 } ->
1223 0000: 10 */
1224 {0x0010, 0x8802}, 1112 {0x0010, 0x8802},
1225 {0x0006, 0x8801}, 1113 {0x0006, 0x8801},
1226 {0x001c, 0x8805}, 1114 {0x001c, 0x8805},
1227 {0x0000, 0x8800}, 1115 {0x0000, 0x8800},
1228 /* READ { 0, 0x0001, 0x8803 } -> 1116 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1229 0000: 00 */
1230 1117
1231 /* READ { 0, 0x0001, 0x8803 } -> 1118 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1232 0000: 00 */ 1119 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1233 /* READ { 0, 0x0001, 0x8802 } ->
1234 0000: 10 */
1235 {0x0010, 0x8802}, 1120 {0x0010, 0x8802},
1236 {0x0007, 0x8801}, 1121 {0x0007, 0x8801},
1237 {0x002a, 0x8805}, 1122 {0x002a, 0x8805},
1238 {0x0000, 0x8800}, 1123 {0x0000, 0x8800},
1239 /* READ { 0, 0x0001, 0x8803 } -> 1124 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1240 0000: 00 */
1241 1125
1242 /* READ { 0, 0x0001, 0x8803 } -> 1126 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1243 0000: 00 */ 1127 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1244 /* READ { 0, 0x0001, 0x8802 } ->
1245 0000: 10 */
1246 {0x0010, 0x8802}, 1128 {0x0010, 0x8802},
1247 {0x000e, 0x8801}, 1129 {0x000e, 0x8801},
1248 {0x0000, 0x8805}, 1130 {0x0000, 0x8805},
1249 {0x0000, 0x8800}, 1131 {0x0000, 0x8800},
1250 /* READ { 0, 0x0001, 0x8803 } -> 1132 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1251 0000: 00 */
1252 1133
1253 /* READ { 0, 0x0001, 0x8803 } -> 1134 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1254 0000: 00 */ 1135 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1255 /* READ { 0, 0x0001, 0x8802 } ->
1256 0000: 10 */
1257 {0x0010, 0x8802}, 1136 {0x0010, 0x8802},
1258 {0x0028, 0x8801}, 1137 {0x0028, 0x8801},
1259 {0x002e, 0x8805}, 1138 {0x002e, 0x8805},
1260 {0x0000, 0x8800}, 1139 {0x0000, 0x8800},
1261 /* READ { 0, 0x0001, 0x8803 } -> 1140 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1262 0000: 00 */
1263 1141
1264 /* READ { 0, 0x0001, 0x8803 } -> 1142 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1265 0000: 00 */ 1143 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1266 /* READ { 0, 0x0001, 0x8802 } ->
1267 0000: 10 */
1268 {0x0010, 0x8802}, 1144 {0x0010, 0x8802},
1269 {0x0039, 0x8801}, 1145 {0x0039, 0x8801},
1270 {0x0013, 0x8805}, 1146 {0x0013, 0x8805},
1271 {0x0000, 0x8800}, 1147 {0x0000, 0x8800},
1272 /* READ { 0, 0x0001, 0x8803 } -> 1148 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1273 0000: 00 */
1274 1149
1275 /* READ { 0, 0x0001, 0x8803 } -> 1150 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1276 0000: 00 */ 1151 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1277 /* READ { 0, 0x0001, 0x8802 } ->
1278 0000: 10 */
1279 {0x0010, 0x8802}, 1152 {0x0010, 0x8802},
1280 {0x003b, 0x8801}, 1153 {0x003b, 0x8801},
1281 {0x000c, 0x8805}, 1154 {0x000c, 0x8805},
1282 {0x0000, 0x8800}, 1155 {0x0000, 0x8800},
1283 /* READ { 0, 0x0001, 0x8803 } -> 1156 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1284 0000: 00 */
1285 1157
1286 /* READ { 0, 0x0001, 0x8803 } -> 1158 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1287 0000: 00 */ 1159 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1288 /* READ { 0, 0x0001, 0x8802 } ->
1289 0000: 10 */
1290 {0x0010, 0x8802}, 1160 {0x0010, 0x8802},
1291 {0x0035, 0x8801}, 1161 {0x0035, 0x8801},
1292 {0x0028, 0x8805}, 1162 {0x0028, 0x8805},
1293 {0x0000, 0x8800}, 1163 {0x0000, 0x8800},
1294 /* READ { 0, 0x0001, 0x8803 } -> 1164 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1295 0000: 00 */
1296 1165
1297 /* READ { 0, 0x0001, 0x8803 } -> 1166 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1298 0000: 00 */ 1167 /* READ { 0x0001, 0x8802 } -> 0000: 10 */
1299 /* READ { 0, 0x0001, 0x8802 } ->
1300 0000: 10 */
1301 {0x0010, 0x8802}, 1168 {0x0010, 0x8802},
1302 {0x0009, 0x8801}, 1169 {0x0009, 0x8801},
1303 {0x0042, 0x8805}, 1170 {0x0042, 0x8805},
1304 {0x0001, 0x8800}, 1171 {0x0001, 0x8800},
1305 /* READ { 0, 0x0001, 0x8803 } -> 1172 /* READ { 0x0001, 0x8803 } -> 0000: 00 */
1306 0000: 00 */
1307 1173
1308 {0x0050, 0x8703}, 1174 {0x0050, 0x8703},
1309 {0x0002, 0x8704}, /* External input CKIx1 */ 1175 {0x0002, 0x8704}, /* External input CKIx1 */
1310 {0x0001, 0x870c}, /* Select CKOx2 output */ 1176 {0x0001, 0x870c}, /* Select CKOx2 output */
1311 {0x009a, 0x8600}, /* Line memory Read Counter (L) */ 1177 {0x009a, 0x8600}, /* Line memory Read Counter (L) */
1312 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ 1178 {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
1313 {0x0023, 0x8601}, 1179 {0x0023, 0x8601},
1314 {0x0010, 0x8602}, 1180 {0x0010, 0x8602},
1315 {0x000a, 0x8603}, 1181 {0x000a, 0x8603},
1316 {0x009A, 0x8600}, 1182 {0x009a, 0x8600},
1317 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ 1183 {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
1318 {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ 1184 {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
1319 {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ 1185 {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
@@ -1329,7 +1195,7 @@ static const u16 spca508_vista_init_data[][2] = {
1329 {0x0005, 0x860a}, /* ... */ 1195 {0x0005, 0x860a}, /* ... */
1330 {0x0025, 0x860b}, 1196 {0x0025, 0x860b},
1331 {0x00e1, 0x860c}, 1197 {0x00e1, 0x860c},
1332 {0x00fa, 0x860D}, 1198 {0x00fa, 0x860d},
1333 {0x00f4, 0x860e}, 1199 {0x00f4, 0x860e},
1334 {0x00e8, 0x860f}, 1200 {0x00e8, 0x860f},
1335 {0x0025, 0x8610}, /* A33 Coef. */ 1201 {0x0025, 0x8610}, /* A33 Coef. */
@@ -1344,11 +1210,12 @@ static const u16 spca508_vista_init_data[][2] = {
1344 {0x0040, 0x8654}, /* Gb gain for white balance (L) */ 1210 {0x0040, 0x8654}, /* Gb gain for white balance (L) */
1345 {0x0001, 0x863f}, /* Enable fixed gamma correction */ 1211 {0x0001, 0x863f}, /* Enable fixed gamma correction */
1346 1212
1347 {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ 1213 {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128,
1348 /* UV division: UV no change, Enable New edge enhancement */ 1214 * UV division: UV no change,
1215 * Enable New edge enhancement */
1349 {0x0018, 0x8657}, /* Edge gain high threshold */ 1216 {0x0018, 0x8657}, /* Edge gain high threshold */
1350 {0x0020, 0x8658}, /* Edge gain low threshold */ 1217 {0x0020, 0x8658}, /* Edge gain low threshold */
1351 {0x000A, 0x8659}, /* Edge bandwidth high threshold */ 1218 {0x000a, 0x8659}, /* Edge bandwidth high threshold */
1352 {0x0005, 0x865a}, /* Edge bandwidth low threshold */ 1219 {0x0005, 0x865a}, /* Edge bandwidth low threshold */
1353 {0x0064, 0x8607}, /* UV filter enable */ 1220 {0x0064, 0x8607}, /* UV filter enable */
1354 1221
@@ -1384,29 +1251,20 @@ static const u16 spca508_vista_init_data[][2] = {
1384 {0x0000, 0x86b4}, 1251 {0x0000, 0x86b4},
1385 {0x001e, 0x8660}, 1252 {0x001e, 0x8660},
1386 1253
1387 /* READ { 0, 0x0000, 0x8608 } -> 1254 /* READ { 0x0000, 0x8608 } -> 0000: 13 */
1388 0000: 13 */ 1255 /* READ { 0x0000, 0x8609 } -> 0000: 28 */
1389 /* READ { 0, 0x0000, 0x8609 } -> 1256 /* READ { 0x0000, 0x8610 } -> 0000: 05 */
1390 0000: 28 */ 1257 /* READ { 0x0000, 0x8611 } -> 0000: 25 */
1391 /* READ { 0, 0x0000, 0x8610 } -> 1258 /* READ { 0x0000, 0x8612 } -> 0000: e1 */
1392 0000: 05 */ 1259 /* READ { 0x0000, 0x8613 } -> 0000: fa */
1393 /* READ { 0, 0x0000, 0x8611 } -> 1260 /* READ { 0x0000, 0x8614 } -> 0000: f4 */
1394 0000: 25 */ 1261 /* READ { 0x0000, 0x8615 } -> 0000: e8 */
1395 /* READ { 0, 0x0000, 0x8612 } -> 1262 /* READ { 0x0000, 0x8616 } -> 0000: 25 */
1396 0000: e1 */
1397 /* READ { 0, 0x0000, 0x8613 } ->
1398 0000: fa */
1399 /* READ { 0, 0x0000, 0x8614 } ->
1400 0000: f4 */
1401 /* READ { 0, 0x0000, 0x8615 } ->
1402 0000: e8 */
1403 /* READ { 0, 0x0000, 0x8616 } ->
1404 0000: 25 */
1405 {} 1263 {}
1406}; 1264};
1407 1265
1408static int reg_write(struct usb_device *dev, 1266static int reg_write(struct usb_device *dev,
1409 __u16 index, __u16 value) 1267 u16 index, u16 value)
1410{ 1268{
1411 int ret; 1269 int ret;
1412 1270
@@ -1425,7 +1283,7 @@ static int reg_write(struct usb_device *dev,
1425/* read 1 byte */ 1283/* read 1 byte */
1426/* returns: negative is error, pos or zero is data */ 1284/* returns: negative is error, pos or zero is data */
1427static int reg_read(struct gspca_dev *gspca_dev, 1285static int reg_read(struct gspca_dev *gspca_dev,
1428 __u16 index) /* wIndex */ 1286 u16 index) /* wIndex */
1429{ 1287{
1430 int ret; 1288 int ret;
1431 1289
@@ -1447,16 +1305,16 @@ static int reg_read(struct gspca_dev *gspca_dev,
1447} 1305}
1448 1306
1449static int write_vector(struct gspca_dev *gspca_dev, 1307static int write_vector(struct gspca_dev *gspca_dev,
1450 const u16 data[][2]) 1308 const u16 (*data)[2])
1451{ 1309{
1452 struct usb_device *dev = gspca_dev->dev; 1310 struct usb_device *dev = gspca_dev->dev;
1453 int ret, i = 0; 1311 int ret;
1454 1312
1455 while (data[i][1] != 0) { 1313 while ((*data)[1] != 0) {
1456 ret = reg_write(dev, data[i][1], data[i][0]); 1314 ret = reg_write(dev, (*data)[1], (*data)[0]);
1457 if (ret < 0) 1315 if (ret < 0)
1458 return ret; 1316 return ret;
1459 i++; 1317 data++;
1460 } 1318 }
1461 return 0; 1319 return 0;
1462} 1320}
@@ -1468,6 +1326,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
1468 struct sd *sd = (struct sd *) gspca_dev; 1326 struct sd *sd = (struct sd *) gspca_dev;
1469 struct cam *cam; 1327 struct cam *cam;
1470 int data1, data2; 1328 int data1, data2;
1329 const u16 (*init_data)[2];
1330 static const u16 (*(init_data_tb[]))[2] = {
1331 spca508_vista_init_data, /* CreativeVista 0 */
1332 spca508_sightcam_init_data, /* HamaUSBSightcam 1 */
1333 spca508_sightcam2_init_data, /* HamaUSBSightcam2 2 */
1334 spca508cs110_init_data, /* IntelEasyPCCamera 3 */
1335 spca508cs110_init_data, /* MicroInnovationIC200 4 */
1336 spca508_init_data, /* ViewQuestVQ110 5 */
1337 };
1471 1338
1472 /* Read from global register the USB product and vendor IDs, just to 1339 /* Read from global register the USB product and vendor IDs, just to
1473 * prove that we can communicate with the device. This works, which 1340 * prove that we can communicate with the device. This works, which
@@ -1491,37 +1358,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
1491 sd->subtype = id->driver_info; 1358 sd->subtype = id->driver_info;
1492 sd->brightness = BRIGHTNESS_DEF; 1359 sd->brightness = BRIGHTNESS_DEF;
1493 1360
1494 switch (sd->subtype) { 1361 init_data = init_data_tb[sd->subtype];
1495 case ViewQuestVQ110: 1362 return write_vector(gspca_dev, init_data);
1496 if (write_vector(gspca_dev, spca508_init_data))
1497 return -1;
1498 break;
1499 default:
1500/* case MicroInnovationIC200: */
1501/* case IntelEasyPCCamera: */
1502 if (write_vector(gspca_dev, spca508cs110_init_data))
1503 return -1;
1504 break;
1505 case HamaUSBSightcam:
1506 if (write_vector(gspca_dev, spca508_sightcam_init_data))
1507 return -1;
1508 break;
1509 case HamaUSBSightcam2:
1510 if (write_vector(gspca_dev, spca508_sightcam2_init_data))
1511 return -1;
1512 break;
1513 case CreativeVista:
1514 if (write_vector(gspca_dev, spca508_vista_init_data))
1515 return -1;
1516 break;
1517 }
1518 return 0; /* success */
1519} 1363}
1520 1364
1521/* this function is called at probe and resume time */ 1365/* this function is called at probe and resume time */
1522static int sd_init(struct gspca_dev *gspca_dev) 1366static int sd_init(struct gspca_dev *gspca_dev)
1523{ 1367{
1524/* write_vector(gspca_dev, spca508_open_data); */
1525 return 0; 1368 return 0;
1526} 1369}
1527 1370
@@ -1529,7 +1372,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1529{ 1372{
1530 int mode; 1373 int mode;
1531 1374
1532 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1375 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1533 reg_write(gspca_dev->dev, 0x8500, mode); 1376 reg_write(gspca_dev->dev, 0x8500, mode);
1534 switch (mode) { 1377 switch (mode) {
1535 case 0: 1378 case 0:
@@ -1554,7 +1397,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1554 1397
1555static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1398static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1556 struct gspca_frame *frame, /* target */ 1399 struct gspca_frame *frame, /* target */
1557 __u8 *data, /* isoc packet */ 1400 u8 *data, /* isoc packet */
1558 int len) /* iso packet length */ 1401 int len) /* iso packet length */
1559{ 1402{
1560 switch (data[0]) { 1403 switch (data[0]) {
@@ -1567,7 +1410,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1567 data, len); 1410 data, len);
1568 break; 1411 break;
1569 case 0xff: /* drop */ 1412 case 0xff: /* drop */
1570/* gspca_dev->last_packet_type = DISCARD_PACKET; */
1571 break; 1413 break;
1572 default: 1414 default:
1573 data += 1; 1415 data += 1;
@@ -1581,7 +1423,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1581static void setbrightness(struct gspca_dev *gspca_dev) 1423static void setbrightness(struct gspca_dev *gspca_dev)
1582{ 1424{
1583 struct sd *sd = (struct sd *) gspca_dev; 1425 struct sd *sd = (struct sd *) gspca_dev;
1584 __u8 brightness = sd->brightness; 1426 u8 brightness = sd->brightness;
1585 1427
1586 /* MX seem contrast */ 1428 /* MX seem contrast */
1587 reg_write(gspca_dev->dev, 0x8651, brightness); 1429 reg_write(gspca_dev->dev, 0x8651, brightness);
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index c99c5e34e211..27e82b35f3e7 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -34,8 +34,8 @@ struct sd {
34 34
35 __u16 exposure; /* rev12a only */ 35 __u16 exposure; /* rev12a only */
36#define EXPOSURE_MIN 1 36#define EXPOSURE_MIN 1
37#define EXPOSURE_DEF 200 37#define EXPOSURE_DEF 700 /* == 10 fps */
38#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */ 38#define EXPOSURE_MAX (2047 + 325) /* see setexposure */
39 39
40 __u8 contrast; /* rev72a only */ 40 __u8 contrast; /* rev72a only */
41#define CONTRAST_MIN 0x00 41#define CONTRAST_MIN 0x00
@@ -48,9 +48,9 @@ struct sd {
48#define BRIGHTNESS_MAX 0x3f 48#define BRIGHTNESS_MAX 0x3f
49 49
50 __u8 white; 50 __u8 white;
51#define WHITE_MIN 1 51#define HUE_MIN 1
52#define WHITE_DEF 0x40 52#define HUE_DEF 0x40
53#define WHITE_MAX 0x7f 53#define HUE_MAX 0x7f
54 54
55 __u8 autogain; 55 __u8 autogain;
56#define AUTOGAIN_MIN 0 56#define AUTOGAIN_MIN 0
@@ -58,9 +58,9 @@ struct sd {
58#define AUTOGAIN_MAX 1 58#define AUTOGAIN_MAX 1
59 59
60 __u8 gain; /* rev12a only */ 60 __u8 gain; /* rev12a only */
61#define GAIN_MIN 0x0 61#define GAIN_MIN 0
62#define GAIN_DEF 0x24 62#define GAIN_DEF 63
63#define GAIN_MAX 0x24 63#define GAIN_MAX 255
64 64
65#define EXPO12A_DEF 3 65#define EXPO12A_DEF 3
66 __u8 expo12a; /* expo/gain? for rev 12a */ 66 __u8 expo12a; /* expo/gain? for rev 12a */
@@ -461,7 +461,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
461 } 461 }
462 sd->brightness = BRIGHTNESS_DEF; 462 sd->brightness = BRIGHTNESS_DEF;
463 sd->contrast = CONTRAST_DEF; 463 sd->contrast = CONTRAST_DEF;
464 sd->white = WHITE_DEF; 464 sd->white = HUE_DEF;
465 sd->exposure = EXPOSURE_DEF; 465 sd->exposure = EXPOSURE_DEF;
466 sd->autogain = AUTOGAIN_DEF; 466 sd->autogain = AUTOGAIN_DEF;
467 sd->gain = GAIN_DEF; 467 sd->gain = GAIN_DEF;
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
549static void setexposure(struct gspca_dev *gspca_dev) 549static void setexposure(struct gspca_dev *gspca_dev)
550{ 550{
551 struct sd *sd = (struct sd *) gspca_dev; 551 struct sd *sd = (struct sd *) gspca_dev;
552 int expo; 552 int i, expo = 0;
553 int clock_divider;
554 553
555 /* Register 0x8309 controls exposure for the spca561, 554 /* Register 0x8309 controls exposure for the spca561,
556 the basic exposure setting goes from 1-2047, where 1 is completely 555 the basic exposure setting goes from 1-2047, where 1 is completely
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev)
564 configure a divider for the base framerate which us used at the 563 configure a divider for the base framerate which us used at the
565 exposure setting of 1-300. These bits configure the base framerate 564 exposure setting of 1-300. These bits configure the base framerate
566 according to the following formula: fps = 60 / (value + 2) */ 565 according to the following formula: fps = 60 / (value + 2) */
567 if (sd->exposure < 2048) { 566
568 expo = sd->exposure; 567 /* We choose to use the high bits setting the fixed framerate divisor
569 clock_divider = 0; 568 asap, as setting high basic exposure setting without the fixed
570 } else { 569 divider in combination with high gains makes the cam stop */
571 /* Add 900 to make the 0 setting of the second part of the 570 int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
572 exposure equal to the 2047 setting of the first part. */ 571
573 expo = (sd->exposure - 2048) + 900; 572 for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
574 clock_divider = 3; 573 if (sd->exposure <= table[i + 1]) {
574 expo = sd->exposure - table[i];
575 if (i)
576 expo += 300;
577 expo |= i << 11;
578 break;
579 }
575 } 580 }
576 expo |= clock_divider << 11; 581
577 gspca_dev->usb_buf[0] = expo; 582 gspca_dev->usb_buf[0] = expo;
578 gspca_dev->usb_buf[1] = expo >> 8; 583 gspca_dev->usb_buf[1] = expo >> 8;
579 reg_w_buf(gspca_dev, 0x8309, 2); 584 reg_w_buf(gspca_dev, 0x8309, 2);
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev)
584{ 589{
585 struct sd *sd = (struct sd *) gspca_dev; 590 struct sd *sd = (struct sd *) gspca_dev;
586 591
587 gspca_dev->usb_buf[0] = sd->gain; 592 /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
593 sensitivity when set, so 31 + one of them set == 63, and 15
594 with both of them set == 63 */
595 if (sd->gain < 64)
596 gspca_dev->usb_buf[0] = sd->gain;
597 else if (sd->gain < 128)
598 gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
599 else
600 gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
601
588 gspca_dev->usb_buf[1] = 0; 602 gspca_dev->usb_buf[1] = 0;
589 reg_w_buf(gspca_dev, 0x8335, 2); 603 reg_w_buf(gspca_dev, 0x8335, 2);
590} 604}
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
629 reg_w_buf(gspca_dev, 0x8391, 8); 643 reg_w_buf(gspca_dev, 0x8391, 8);
630 reg_w_buf(gspca_dev, 0x8390, 8); 644 reg_w_buf(gspca_dev, 0x8390, 8);
631 setwhite(gspca_dev); 645 setwhite(gspca_dev);
632 setautogain(gspca_dev); 646 setgain(gspca_dev);
633/* setgain(gspca_dev); */
634 setexposure(gspca_dev); 647 setexposure(gspca_dev);
635 return 0; 648 return 0;
636} 649}
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
762 i2c_write(gspca_dev, expotimes | pixelclk, 0x09); 775 i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
763 } 776 }
764 break; 777 break;
765 case Rev012A:
766 reg_r(gspca_dev, 0x8330, 2);
767 if (gspca_dev->usb_buf[1] > 0x08) {
768 gspca_dev->usb_buf[0] = ++sd->expo12a;
769 gspca_dev->usb_buf[1] = 0;
770 reg_w_buf(gspca_dev, 0x8339, 2);
771 } else if (gspca_dev->usb_buf[1] < 0x02) {
772 gspca_dev->usb_buf[0] = --sd->expo12a;
773 gspca_dev->usb_buf[1] = 0;
774 reg_w_buf(gspca_dev, 0x8339, 2);
775 }
776 break;
777 } 778 }
778} 779}
779 780
@@ -928,13 +929,13 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
928static struct ctrl sd_ctrls_12a[] = { 929static struct ctrl sd_ctrls_12a[] = {
929 { 930 {
930 { 931 {
931 .id = V4L2_CID_DO_WHITE_BALANCE, 932 .id = V4L2_CID_HUE,
932 .type = V4L2_CTRL_TYPE_INTEGER, 933 .type = V4L2_CTRL_TYPE_INTEGER,
933 .name = "White Balance", 934 .name = "Hue",
934 .minimum = WHITE_MIN, 935 .minimum = HUE_MIN,
935 .maximum = WHITE_MAX, 936 .maximum = HUE_MAX,
936 .step = 1, 937 .step = 1,
937 .default_value = WHITE_DEF, 938 .default_value = HUE_DEF,
938 }, 939 },
939 .set = sd_setwhite, 940 .set = sd_setwhite,
940 .get = sd_getwhite, 941 .get = sd_getwhite,
@@ -954,19 +955,6 @@ static struct ctrl sd_ctrls_12a[] = {
954 }, 955 },
955 { 956 {
956 { 957 {
957 .id = V4L2_CID_AUTOGAIN,
958 .type = V4L2_CTRL_TYPE_BOOLEAN,
959 .name = "Auto Gain",
960 .minimum = AUTOGAIN_MIN,
961 .maximum = AUTOGAIN_MAX,
962 .step = 1,
963 .default_value = AUTOGAIN_DEF,
964 },
965 .set = sd_setautogain,
966 .get = sd_getautogain,
967 },
968 {
969 {
970 .id = V4L2_CID_GAIN, 958 .id = V4L2_CID_GAIN,
971 .type = V4L2_CTRL_TYPE_INTEGER, 959 .type = V4L2_CTRL_TYPE_INTEGER,
972 .name = "Gain", 960 .name = "Gain",
@@ -983,13 +971,13 @@ static struct ctrl sd_ctrls_12a[] = {
983static struct ctrl sd_ctrls_72a[] = { 971static struct ctrl sd_ctrls_72a[] = {
984 { 972 {
985 { 973 {
986 .id = V4L2_CID_DO_WHITE_BALANCE, 974 .id = V4L2_CID_HUE,
987 .type = V4L2_CTRL_TYPE_INTEGER, 975 .type = V4L2_CTRL_TYPE_INTEGER,
988 .name = "White Balance", 976 .name = "Hue",
989 .minimum = WHITE_MIN, 977 .minimum = HUE_MIN,
990 .maximum = WHITE_MAX, 978 .maximum = HUE_MAX,
991 .step = 1, 979 .step = 1,
992 .default_value = WHITE_DEF, 980 .default_value = HUE_DEF,
993 }, 981 },
994 .set = sd_setwhite, 982 .set = sd_setwhite,
995 .get = sd_getwhite, 983 .get = sd_getwhite,
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = {
1046 .stopN = sd_stopN, 1034 .stopN = sd_stopN,
1047 .stop0 = sd_stop0, 1035 .stop0 = sd_stop0,
1048 .pkt_scan = sd_pkt_scan, 1036 .pkt_scan = sd_pkt_scan,
1049/* .dq_callback = do_autogain, * fixme */
1050}; 1037};
1051static const struct sd_desc sd_desc_72a = { 1038static const struct sd_desc sd_desc_72a = {
1052 .name = MODULE_NAME, 1039 .name = MODULE_NAME,
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 2e1cdf068fda..715a68f0156e 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -309,6 +309,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
309 struct sd *dev = (struct sd *) gspca_dev; 309 struct sd *dev = (struct sd *) gspca_dev;
310 310
311 /* We don't use the buffer gspca allocates so make it small. */ 311 /* We don't use the buffer gspca allocates so make it small. */
312 cam->bulk = 1;
312 cam->bulk_size = 64; 313 cam->bulk_size = 64;
313 314
314 INIT_WORK(&dev->work_struct, sq905_dostream); 315 INIT_WORK(&dev->work_struct, sq905_dostream);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index 0bcb74a1b143..916892505432 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -206,6 +206,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
206 cam->nmodes = 1; 206 cam->nmodes = 1;
207 /* We don't use the buffer gspca allocates so make it small. */ 207 /* We don't use the buffer gspca allocates so make it small. */
208 cam->bulk_size = 32; 208 cam->bulk_size = 32;
209 cam->bulk = 1;
209 INIT_WORK(&dev->work_struct, sq905c_dostream); 210 INIT_WORK(&dev->work_struct, sq905c_dostream);
210 return 0; 211 return 0;
211} 212}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 9dff2e65b116..e573c3406324 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -293,8 +293,6 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev)
293 goto out; 293 goto out;
294 294
295 err = sd->sensor->stop(sd); 295 err = sd->sensor->stop(sd);
296 if (err < 0)
297 goto out;
298 296
299out: 297out:
300 if (err < 0) 298 if (err < 0)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 69c77c932fc0..11a0c002f5dc 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -80,12 +80,26 @@ static const struct ctrl vv6410_ctrl[] = {
80 .minimum = 0, 80 .minimum = 0,
81 .maximum = 15, 81 .maximum = 15,
82 .step = 1, 82 .step = 1,
83 .default_value = 0 83 .default_value = 10
84 }, 84 },
85 .set = vv6410_set_analog_gain, 85 .set = vv6410_set_analog_gain,
86 .get = vv6410_get_analog_gain 86 .get = vv6410_get_analog_gain
87 },
88#define EXPOSURE_IDX 3
89 {
90 {
91 .id = V4L2_CID_EXPOSURE,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "exposure",
94 .minimum = 0,
95 .maximum = 32768,
96 .step = 1,
97 .default_value = 20000
98 },
99 .set = vv6410_set_exposure,
100 .get = vv6410_get_exposure
87 } 101 }
88}; 102 };
89 103
90static int vv6410_probe(struct sd *sd) 104static int vv6410_probe(struct sd *sd)
91{ 105{
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd)
121static int vv6410_init(struct sd *sd) 135static int vv6410_init(struct sd *sd)
122{ 136{
123 int err = 0, i; 137 int err = 0, i;
138 s32 *sensor_settings = sd->sensor_priv;
124 139
125 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { 140 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
126 /* if NULL then len contains single value */ 141 /* if NULL then len contains single value */
@@ -142,6 +157,16 @@ static int vv6410_init(struct sd *sd)
142 157
143 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, 158 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
144 ARRAY_SIZE(vv6410_sensor_init)); 159 ARRAY_SIZE(vv6410_sensor_init));
160 if (err < 0)
161 return err;
162
163 err = vv6410_set_exposure(&sd->gspca_dev,
164 sensor_settings[EXPOSURE_IDX]);
165 if (err < 0)
166 return err;
167
168 err = vv6410_set_analog_gain(&sd->gspca_dev,
169 sensor_settings[GAIN_IDX]);
145 170
146 return (err < 0) ? err : 0; 171 return (err < 0) ? err : 0;
147} 172}
@@ -318,3 +343,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
318 343
319 return (err < 0) ? err : 0; 344 return (err < 0) ? err : 0;
320} 345}
346
347static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
348{
349 struct sd *sd = (struct sd *) gspca_dev;
350 s32 *sensor_settings = sd->sensor_priv;
351
352 *val = sensor_settings[EXPOSURE_IDX];
353
354 PDEBUG(D_V4L2, "Read exposure %d", *val);
355
356 return 0;
357}
358
359static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
360{
361 int err;
362 struct sd *sd = (struct sd *) gspca_dev;
363 s32 *sensor_settings = sd->sensor_priv;
364 unsigned int fine, coarse;
365
366 sensor_settings[EXPOSURE_IDX] = val;
367
368 val = (val * val >> 14) + val / 4;
369
370 fine = val % VV6410_CIF_LINELENGTH;
371 coarse = min(512, val / VV6410_CIF_LINELENGTH);
372
373 PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d",
374 coarse, fine);
375
376 err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
377 if (err < 0)
378 goto out;
379
380 err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff);
381 if (err < 0)
382 goto out;
383
384 err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8);
385 if (err < 0)
386 goto out;
387
388 err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff);
389
390out:
391 return err;
392}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 95ac55891bd4..487d40555343 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -173,6 +173,8 @@
173#define VV6410_SUBSAMPLE 0x01 173#define VV6410_SUBSAMPLE 0x01
174#define VV6410_CROP_TO_QVGA 0x02 174#define VV6410_CROP_TO_QVGA 0x02
175 175
176#define VV6410_CIF_LINELENGTH 415
177
176static int vv6410_probe(struct sd *sd); 178static int vv6410_probe(struct sd *sd);
177static int vv6410_start(struct sd *sd); 179static int vv6410_start(struct sd *sd);
178static int vv6410_init(struct sd *sd); 180static int vv6410_init(struct sd *sd);
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
187static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 189static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
188static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); 190static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
189static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); 191static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
192static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
193static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
190 194
191const struct stv06xx_sensor stv06xx_sensor_vv6410 = { 195const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
192 .name = "ST VV6410", 196 .name = "ST VV6410",
@@ -242,12 +246,6 @@ static const u8 vv6410_sensor_init[][2] = {
242 /* Pre-clock generator divide off */ 246 /* Pre-clock generator divide off */
243 {VV6410_DATAFORMAT, BIT(7) | BIT(0)}, 247 {VV6410_DATAFORMAT, BIT(7) | BIT(0)},
244 248
245 /* Exposure registers */
246 {VV6410_FINEH, VV6410_FINE_EXPOSURE >> 8},
247 {VV6410_FINEL, VV6410_FINE_EXPOSURE & 0xff},
248 {VV6410_COARSEH, VV6410_COARSE_EXPOSURE >> 8},
249 {VV6410_COARSEL, VV6410_COARSE_EXPOSURE & 0xff},
250 {VV6410_ANALOGGAIN, 0xf0 | VV6410_DEFAULT_GAIN},
251 {VV6410_CLKDIV, VV6410_CLK_DIV_2}, 249 {VV6410_CLKDIV, VV6410_CLK_DIV_2},
252 250
253 /* System registers */ 251 /* System registers */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index c2b8c10c075a..9623f294bdac 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,9 +32,6 @@ 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 packet[ISO_MAX_SIZE + 128];
36 /* !! no more than 128 ff in an ISO packet */
37
38 unsigned char brightness; 35 unsigned char brightness;
39 unsigned char contrast; 36 unsigned char contrast;
40 unsigned char colors; 37 unsigned char colors;
@@ -1103,7 +1100,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1103{ 1100{
1104 struct sd *sd = (struct sd *) gspca_dev; 1101 struct sd *sd = (struct sd *) gspca_dev;
1105 int i, sof = 0; 1102 int i, sof = 0;
1106 unsigned char *s, *d;
1107 static unsigned char ffd9[] = {0xff, 0xd9}; 1103 static unsigned char ffd9[] = {0xff, 0xd9};
1108 1104
1109/* frames are jpeg 4.1.1 without 0xff escape */ 1105/* frames are jpeg 4.1.1 without 0xff escape */
@@ -1177,22 +1173,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1177 } 1173 }
1178 1174
1179 /* add 0x00 after 0xff */ 1175 /* add 0x00 after 0xff */
1180 for (i = len; --i >= 0; ) 1176 i = 0;
1181 if (data[i] == 0xff) 1177 do {
1182 break; 1178 if (data[i] == 0xff) {
1183 if (i < 0) { /* no 0xff */ 1179 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1184 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1180 data, i + 1);
1185 return; 1181 len -= i;
1186 } 1182 data += i;
1187 s = data; 1183 *data = 0x00;
1188 d = sd->packet; 1184 i = 0;
1189 for (i = 0; i < len; i++) { 1185 }
1190 *d++ = *s++; 1186 i++;
1191 if (s[-1] == 0xff) 1187 } while (i < len);
1192 *d++ = 0x00; 1188 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1193 }
1194 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1195 sd->packet, d - sd->packet);
1196} 1189}
1197 1190
1198static void setbrightness(struct gspca_dev *gspca_dev) 1191static void setbrightness(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index f63e37e2e4fd..404214b8cd2b 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -697,7 +697,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
697 return -EINVAL; 697 return -EINVAL;
698 } 698 }
699 699
700 if (sd->sensor != SENSOR_OTHER) { 700 if (sd->sensor == SENSOR_OM6802) {
701 reg_w_buf(gspca_dev, n1, sizeof n1); 701 reg_w_buf(gspca_dev, n1, sizeof n1);
702 i = 5; 702 i = 5;
703 while (--i >= 0) { 703 while (--i >= 0) {
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index e4e933c400bc..26dd155efcc3 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -42,7 +42,7 @@ struct sd {
42 char bridge; 42 char bridge;
43#define BRIDGE_VC0321 0 43#define BRIDGE_VC0321 0
44#define BRIDGE_VC0323 1 44#define BRIDGE_VC0323 1
45 char sensor; 45 u8 sensor;
46#define SENSOR_HV7131R 0 46#define SENSOR_HV7131R 0
47#define SENSOR_MI0360 1 47#define SENSOR_MI0360 1
48#define SENSOR_MI1310_SOC 2 48#define SENSOR_MI1310_SOC 2
@@ -159,17 +159,17 @@ static const struct v4l2_pix_format vc0323_mode[] = {
159 .priv = 2}, 159 .priv = 2},
160}; 160};
161static const struct v4l2_pix_format bi_mode[] = { 161static const struct v4l2_pix_format bi_mode[] = {
162 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 162 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
163 .bytesperline = 320, 163 .bytesperline = 320,
164 .sizeimage = 320 * 240 * 2, 164 .sizeimage = 320 * 240 * 2,
165 .colorspace = V4L2_COLORSPACE_SRGB, 165 .colorspace = V4L2_COLORSPACE_SRGB,
166 .priv = 2}, 166 .priv = 2},
167 {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 167 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
168 .bytesperline = 640, 168 .bytesperline = 640,
169 .sizeimage = 640 * 480 * 2, 169 .sizeimage = 640 * 480 * 2,
170 .colorspace = V4L2_COLORSPACE_SRGB, 170 .colorspace = V4L2_COLORSPACE_SRGB,
171 .priv = 1}, 171 .priv = 1},
172 {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 172 {1280, 1024, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
173 .bytesperline = 1280, 173 .bytesperline = 1280,
174 .sizeimage = 1280 * 1024 * 2, 174 .sizeimage = 1280 * 1024 * 2,
175 .colorspace = V4L2_COLORSPACE_SRGB, 175 .colorspace = V4L2_COLORSPACE_SRGB,
@@ -2453,6 +2453,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
2453 struct usb_device *dev = gspca_dev->dev; 2453 struct usb_device *dev = gspca_dev->dev;
2454 struct cam *cam; 2454 struct cam *cam;
2455 int sensor; 2455 int sensor;
2456 static u8 npkt[] = { /* number of packets per ISOC message */
2457 64, /* HV7131R 0 */
2458 32, /* MI0360 1 */
2459 32, /* MI1310_SOC 2 */
2460 64, /* MI1320 3 */
2461 128, /* MI1320_SOC 4 */
2462 32, /* OV7660 5 */
2463 64, /* OV7670 6 */
2464 128, /* PO1200 7 */
2465 128, /* PO3130NC 8 */
2466 };
2456 2467
2457 cam = &gspca_dev->cam; 2468 cam = &gspca_dev->cam;
2458 sd->bridge = id->driver_info; 2469 sd->bridge = id->driver_info;
@@ -2508,6 +2519,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
2508 case SENSOR_MI1320_SOC: 2519 case SENSOR_MI1320_SOC:
2509 cam->cam_mode = bi_mode; 2520 cam->cam_mode = bi_mode;
2510 cam->nmodes = ARRAY_SIZE(bi_mode); 2521 cam->nmodes = ARRAY_SIZE(bi_mode);
2522 cam->input_flags = V4L2_IN_ST_VFLIP |
2523 V4L2_IN_ST_HFLIP;
2511 break; 2524 break;
2512 default: 2525 default:
2513 cam->cam_mode = vc0323_mode; 2526 cam->cam_mode = vc0323_mode;
@@ -2515,6 +2528,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2515 break; 2528 break;
2516 } 2529 }
2517 } 2530 }
2531 cam->npkt = npkt[sd->sensor];
2518 2532
2519 sd->hflip = HFLIP_DEF; 2533 sd->hflip = HFLIP_DEF;
2520 sd->vflip = VFLIP_DEF; 2534 sd->vflip = VFLIP_DEF;
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 4fe01d8b6c87..08422d315e68 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6307,7 +6307,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 6307 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
6308 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 6308 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
6309 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 6309 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */
6310 PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", 6310 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
6311 reg, retval, retbyte); 6311 reg, retval, retbyte);
6312 return retval; 6312 return retval;
6313} 6313}
@@ -6868,7 +6868,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
6868 {0x8001, 0x13}, 6868 {0x8001, 0x13},
6869 {0x8000, 0x14}, /* CS2102K */ 6869 {0x8000, 0x14}, /* CS2102K */
6870 {0x8400, 0x15}, /* TAS5130K */ 6870 {0x8400, 0x15}, /* TAS5130K */
6871 {0x4001, 0x16}, /* ADCM2700 */
6872}; 6871};
6873 6872
6874static int vga_3wr_probe(struct gspca_dev *gspca_dev) 6873static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6904,12 +6903,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6904 retword |= reg_r(gspca_dev, 0x000a); 6903 retword |= reg_r(gspca_dev, 0x000a);
6905 PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); 6904 PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
6906 reg_r(gspca_dev, 0x0010); 6905 reg_r(gspca_dev, 0x0010);
6907 /* this is tested only once anyway */ 6906 /* value 0x4001 is meaningless */
6908 for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { 6907 if (retword != 0x4001) {
6909 if (chipset_revision_sensor[i].revision == retword) { 6908 for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
6910 sd->chip_revision = retword; 6909 if (chipset_revision_sensor[i].revision == retword) {
6911 send_unknown(dev, SENSOR_PB0330); 6910 sd->chip_revision = retword;
6912 return chipset_revision_sensor[i].internal_sensor_id; 6911 send_unknown(dev, SENSOR_PB0330);
6912 return chipset_revision_sensor[i]
6913 .internal_sensor_id;
6914 }
6913 } 6915 }
6914 } 6916 }
6915 6917
@@ -6980,12 +6982,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6980 reg_w(dev, 0x01, 0x0001); 6982 reg_w(dev, 0x01, 0x0001);
6981 reg_w(dev, 0x03, 0x0012); 6983 reg_w(dev, 0x03, 0x0012);
6982 reg_w(dev, 0x01, 0x0012); 6984 reg_w(dev, 0x01, 0x0012);
6983 reg_w(dev, 0x05, 0x0001); 6985 reg_w(dev, 0x05, 0x0012);
6984 reg_w(dev, 0xd3, 0x008b); 6986 reg_w(dev, 0xd3, 0x008b);
6985 retword = i2c_read(gspca_dev, 0x01); 6987 retword = i2c_read(gspca_dev, 0x01);
6986 if (retword != 0) { 6988 if (retword != 0) {
6987 PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); 6989 PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
6988 return retword; 6990 return 0x16; /* adcm2700 (6100/6200) */
6989 } 6991 }
6990 return -1; 6992 return -1;
6991} 6993}
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 8e1463ee1b64..71c211402eb5 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -224,7 +224,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
224{ 224{
225 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); 225 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
226 226
227 if (i->index < 0 || i->index >= HEXIUM_INPUTS) 227 if (i->index >= HEXIUM_INPUTS)
228 return -EINVAL; 228 return -EINVAL;
229 229
230 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); 230 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 2bc39f628455..39d65ca41c62 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -325,7 +325,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
325{ 325{
326 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); 326 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
327 327
328 if (i->index < 0 || i->index >= HEXIUM_INPUTS) 328 if (i->index >= HEXIUM_INPUTS)
329 return -EINVAL; 329 return -EINVAL;
330 330
331 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); 331 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 092c7da0f37a..86f2fefe1edf 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -74,7 +74,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
74 int start, range, toggle, dev, code, ircode; 74 int start, range, toggle, dev, code, ircode;
75 75
76 /* poll IR chip */ 76 /* poll IR chip */
77 if (size != i2c_master_recv(&ir->c,buf,size)) 77 if (size != i2c_master_recv(ir->c, buf, size))
78 return -EIO; 78 return -EIO;
79 79
80 /* split rc5 data block ... */ 80 /* split rc5 data block ... */
@@ -137,7 +137,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
137 unsigned char b; 137 unsigned char b;
138 138
139 /* poll IR chip */ 139 /* poll IR chip */
140 if (1 != i2c_master_recv(&ir->c,&b,1)) { 140 if (1 != i2c_master_recv(ir->c, &b, 1)) {
141 dprintk(1,"read error\n"); 141 dprintk(1,"read error\n");
142 return -EIO; 142 return -EIO;
143 } 143 }
@@ -151,7 +151,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
151 unsigned char b; 151 unsigned char b;
152 152
153 /* poll IR chip */ 153 /* poll IR chip */
154 if (1 != i2c_master_recv(&ir->c,&b,1)) { 154 if (1 != i2c_master_recv(ir->c, &b, 1)) {
155 dprintk(1,"read error\n"); 155 dprintk(1,"read error\n");
156 return -EIO; 156 return -EIO;
157 } 157 }
@@ -171,7 +171,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
171 unsigned char buf[4]; 171 unsigned char buf[4];
172 172
173 /* poll IR chip */ 173 /* poll IR chip */
174 if (4 != i2c_master_recv(&ir->c,buf,4)) { 174 if (4 != i2c_master_recv(ir->c, buf, 4)) {
175 dprintk(1,"read error\n"); 175 dprintk(1,"read error\n");
176 return -EIO; 176 return -EIO;
177 } 177 }
@@ -195,7 +195,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
195 unsigned char b; 195 unsigned char b;
196 196
197 /* poll IR chip */ 197 /* poll IR chip */
198 if (1 != i2c_master_recv(&ir->c,&b,1)) { 198 if (1 != i2c_master_recv(ir->c, &b, 1)) {
199 dprintk(1,"read error\n"); 199 dprintk(1,"read error\n");
200 return -EIO; 200 return -EIO;
201 } 201 }
@@ -222,12 +222,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
222 u32 *ir_key, u32 *ir_raw) 222 u32 *ir_key, u32 *ir_raw)
223{ 223{
224 unsigned char subaddr, key, keygroup; 224 unsigned char subaddr, key, keygroup;
225 struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, 225 struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
226 .buf = &subaddr, .len = 1}, 226 .buf = &subaddr, .len = 1},
227 { .addr = ir->c.addr, .flags = I2C_M_RD, 227 { .addr = ir->c->addr, .flags = I2C_M_RD,
228 .buf = &key, .len = 1} }; 228 .buf = &key, .len = 1} };
229 subaddr = 0x0d; 229 subaddr = 0x0d;
230 if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { 230 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
231 dprintk(1, "read error\n"); 231 dprintk(1, "read error\n");
232 return -EIO; 232 return -EIO;
233 } 233 }
@@ -237,7 +237,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
237 237
238 subaddr = 0x0b; 238 subaddr = 0x0b;
239 msg[1].buf = &keygroup; 239 msg[1].buf = &keygroup;
240 if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { 240 if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
241 dprintk(1, "read error\n"); 241 dprintk(1, "read error\n");
242 return -EIO; 242 return -EIO;
243 } 243 }
@@ -286,7 +286,7 @@ static void ir_work(struct work_struct *work)
286 286
287 /* MSI TV@nywhere Plus requires more frequent polling 287 /* MSI TV@nywhere Plus requires more frequent polling
288 otherwise it will miss some keypresses */ 288 otherwise it will miss some keypresses */
289 if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30) 289 if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30)
290 polling_interval = 50; 290 polling_interval = 50;
291 291
292 ir_key_poll(ir); 292 ir_key_poll(ir);
@@ -295,34 +295,15 @@ static void ir_work(struct work_struct *work)
295 295
296/* ----------------------------------------------------------------------- */ 296/* ----------------------------------------------------------------------- */
297 297
298static int ir_attach(struct i2c_adapter *adap, int addr, 298static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
299 unsigned short flags, int kind);
300static int ir_detach(struct i2c_client *client);
301static int ir_probe(struct i2c_adapter *adap);
302
303static struct i2c_driver driver = {
304 .driver = {
305 .name = "ir-kbd-i2c",
306 },
307 .id = I2C_DRIVERID_INFRARED,
308 .attach_adapter = ir_probe,
309 .detach_client = ir_detach,
310};
311
312static struct i2c_client client_template =
313{
314 .name = "unset",
315 .driver = &driver
316};
317
318static int ir_attach(struct i2c_adapter *adap, int addr,
319 unsigned short flags, int kind)
320{ 299{
321 IR_KEYTAB_TYPE *ir_codes = NULL; 300 IR_KEYTAB_TYPE *ir_codes = NULL;
322 char *name; 301 const char *name = NULL;
323 int ir_type; 302 int ir_type;
324 struct IR_i2c *ir; 303 struct IR_i2c *ir;
325 struct input_dev *input_dev; 304 struct input_dev *input_dev;
305 struct i2c_adapter *adap = client->adapter;
306 unsigned short addr = client->addr;
326 int err; 307 int err;
327 308
328 ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); 309 ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
@@ -332,13 +313,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
332 goto err_out_free; 313 goto err_out_free;
333 } 314 }
334 315
335 ir->c = client_template; 316 ir->c = client;
336 ir->input = input_dev; 317 ir->input = input_dev;
337 318 i2c_set_clientdata(client, ir);
338 ir->c.adapter = adap;
339 ir->c.addr = addr;
340
341 i2c_set_clientdata(&ir->c, ir);
342 319
343 switch(addr) { 320 switch(addr) {
344 case 0x64: 321 case 0x64:
@@ -403,44 +380,46 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
403 ir_codes = ir_codes_avermedia_cardbus; 380 ir_codes = ir_codes_avermedia_cardbus;
404 break; 381 break;
405 default: 382 default:
406 /* shouldn't happen */ 383 dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
407 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
408 err = -ENODEV; 384 err = -ENODEV;
409 goto err_out_free; 385 goto err_out_free;
410 } 386 }
411 387
412 /* Sets name */ 388 /* Let the caller override settings */
413 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 389 if (client->dev.platform_data) {
414 ir->ir_codes = ir_codes; 390 const struct IR_i2c_init_data *init_data =
391 client->dev.platform_data;
415 392
416 /* register i2c device 393 ir_codes = init_data->ir_codes;
417 * At device register, IR codes may be changed to be 394 name = init_data->name;
418 * board dependent. 395 ir->get_key = init_data->get_key;
419 */ 396 }
420 err = i2c_attach_client(&ir->c);
421 if (err)
422 goto err_out_free;
423 397
424 /* If IR not supported or disabled, unregisters driver */ 398 /* Make sure we are all setup before going on */
425 if (ir->get_key == NULL) { 399 if (!name || !ir->get_key || !ir_codes) {
400 dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
401 addr);
426 err = -ENODEV; 402 err = -ENODEV;
427 goto err_out_detach; 403 goto err_out_free;
428 } 404 }
429 405
430 /* Phys addr can only be set after attaching (for ir->c.dev) */ 406 /* Sets name */
407 snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
408 ir->ir_codes = ir_codes;
409
431 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 410 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
432 dev_name(&ir->c.adapter->dev), 411 dev_name(&adap->dev),
433 dev_name(&ir->c.dev)); 412 dev_name(&client->dev));
434 413
435 /* init + register input device */ 414 /* init + register input device */
436 ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); 415 ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
437 input_dev->id.bustype = BUS_I2C; 416 input_dev->id.bustype = BUS_I2C;
438 input_dev->name = ir->c.name; 417 input_dev->name = ir->name;
439 input_dev->phys = ir->phys; 418 input_dev->phys = ir->phys;
440 419
441 err = input_register_device(ir->input); 420 err = input_register_device(ir->input);
442 if (err) 421 if (err)
443 goto err_out_detach; 422 goto err_out_free;
444 423
445 printk(DEVNAME ": %s detected at %s [%s]\n", 424 printk(DEVNAME ": %s detected at %s [%s]\n",
446 ir->input->name, ir->input->phys, adap->name); 425 ir->input->name, ir->input->phys, adap->name);
@@ -451,135 +430,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
451 430
452 return 0; 431 return 0;
453 432
454 err_out_detach:
455 i2c_detach_client(&ir->c);
456 err_out_free: 433 err_out_free:
457 input_free_device(input_dev); 434 input_free_device(input_dev);
458 kfree(ir); 435 kfree(ir);
459 return err; 436 return err;
460} 437}
461 438
462static int ir_detach(struct i2c_client *client) 439static int ir_remove(struct i2c_client *client)
463{ 440{
464 struct IR_i2c *ir = i2c_get_clientdata(client); 441 struct IR_i2c *ir = i2c_get_clientdata(client);
465 442
466 /* kill outstanding polls */ 443 /* kill outstanding polls */
467 cancel_delayed_work_sync(&ir->work); 444 cancel_delayed_work_sync(&ir->work);
468 445
469 /* unregister devices */ 446 /* unregister device */
470 input_unregister_device(ir->input); 447 input_unregister_device(ir->input);
471 i2c_detach_client(&ir->c);
472 448
473 /* free memory */ 449 /* free memory */
474 kfree(ir); 450 kfree(ir);
475 return 0; 451 return 0;
476} 452}
477 453
478static int ir_probe(struct i2c_adapter *adap) 454static const struct i2c_device_id ir_kbd_id[] = {
479{ 455 /* Generic entry for any IR receiver */
480 456 { "ir_video", 0 },
481 /* The external IR receiver is at i2c address 0x34 (0x35 for 457 /* IR device specific entries could be added here */
482 reads). Future Hauppauge cards will have an internal 458 { }
483 receiver at 0x30 (0x31 for reads). In theory, both can be 459};
484 fitted, and Hauppauge suggest an external overrides an
485 internal.
486
487 That's why we probe 0x1a (~0x34) first. CB
488 */
489
490 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
491 static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
492 static const int probe_em28XX[] = { 0x30, 0x47, -1 };
493 static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
494 static const int probe_cx23885[] = { 0x6b, -1 };
495 const int *probe;
496 struct i2c_msg msg = {
497 .flags = I2C_M_RD,
498 .len = 0,
499 .buf = NULL,
500 };
501 int i, rc;
502
503 switch (adap->id) {
504 case I2C_HW_B_BT848:
505 probe = probe_bttv;
506 break;
507 case I2C_HW_B_CX2341X:
508 probe = probe_bttv;
509 break;
510 case I2C_HW_SAA7134:
511 probe = probe_saa7134;
512 break;
513 case I2C_HW_B_EM28XX:
514 probe = probe_em28XX;
515 break;
516 case I2C_HW_B_CX2388x:
517 probe = probe_cx88;
518 break;
519 case I2C_HW_B_CX23885:
520 probe = probe_cx23885;
521 break;
522 default:
523 return 0;
524 }
525
526 for (i = 0; -1 != probe[i]; i++) {
527 msg.addr = probe[i];
528 rc = i2c_transfer(adap, &msg, 1);
529 dprintk(1,"probe 0x%02x @ %s: %s\n",
530 probe[i], adap->name,
531 (1 == rc) ? "yes" : "no");
532 if (1 == rc) {
533 ir_attach(adap, probe[i], 0, 0);
534 return 0;
535 }
536 }
537
538 /* Special case for MSI TV@nywhere Plus remote */
539 if (adap->id == I2C_HW_SAA7134) {
540 u8 temp;
541
542 /* MSI TV@nywhere Plus controller doesn't seem to
543 respond to probes unless we read something from
544 an existing device. Weird... */
545
546 msg.addr = 0x50;
547 rc = i2c_transfer(adap, &msg, 1);
548 dprintk(1, "probe 0x%02x @ %s: %s\n",
549 msg.addr, adap->name,
550 (1 == rc) ? "yes" : "no");
551
552 /* Now do the probe. The controller does not respond
553 to 0-byte reads, so we use a 1-byte read instead. */
554 msg.addr = 0x30;
555 msg.len = 1;
556 msg.buf = &temp;
557 rc = i2c_transfer(adap, &msg, 1);
558 dprintk(1, "probe 0x%02x @ %s: %s\n",
559 msg.addr, adap->name,
560 (1 == rc) ? "yes" : "no");
561 if (1 == rc)
562 ir_attach(adap, msg.addr, 0, 0);
563 }
564
565 /* Special case for AVerMedia Cardbus remote */
566 if (adap->id == I2C_HW_SAA7134) {
567 unsigned char subaddr, data;
568 struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
569 .buf = &subaddr, .len = 1},
570 { .addr = 0x40, .flags = I2C_M_RD,
571 .buf = &data, .len = 1} };
572 subaddr = 0x0d;
573 rc = i2c_transfer(adap, msg, 2);
574 dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
575 msg[0].addr, subaddr, adap->name,
576 (2 == rc) ? "yes" : "no");
577 if (2 == rc)
578 ir_attach(adap, msg[0].addr, 0, 0);
579 }
580 460
581 return 0; 461static struct i2c_driver driver = {
582} 462 .driver = {
463 .name = "ir-kbd-i2c",
464 },
465 .probe = ir_probe,
466 .remove = ir_remove,
467 .id_table = ir_kbd_id,
468};
583 469
584/* ----------------------------------------------------------------------- */ 470/* ----------------------------------------------------------------------- */
585 471
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index db2ac9a99acd..558f8a837ff4 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -455,7 +455,7 @@ static void ivtv_process_eeprom(struct ivtv *itv)
455 break; 455 break;
456 } 456 }
457 if (tv.tuner_type == TUNER_ABSENT) 457 if (tv.tuner_type == TUNER_ABSENT)
458 IVTV_ERR("tveeprom cannot autodetect tuner!"); 458 IVTV_ERR("tveeprom cannot autodetect tuner!\n");
459 459
460 if (itv->options.tuner == -1) 460 if (itv->options.tuner == -1)
461 itv->options.tuner = tv.tuner_type; 461 itv->options.tuner = tv.tuner_type;
@@ -946,17 +946,14 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
946 if (itv == NULL) 946 if (itv == NULL)
947 return -ENOMEM; 947 return -ENOMEM;
948 itv->pdev = pdev; 948 itv->pdev = pdev;
949 itv->instance = atomic_inc_return(&ivtv_instance) - 1; 949 itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv",
950 &ivtv_instance);
950 951
951 retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); 952 retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
952 if (retval) { 953 if (retval) {
953 kfree(itv); 954 kfree(itv);
954 return retval; 955 return retval;
955 } 956 }
956 /* "ivtv + PCI ID" is a bit of a mouthful, so use
957 "ivtv + instance" instead. */
958 snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
959 "ivtv%d", itv->instance);
960 IVTV_INFO("Initializing card %d\n", itv->instance); 957 IVTV_INFO("Initializing card %d\n", itv->instance);
961 958
962 ivtv_process_options(itv); 959 ivtv_process_options(itv);
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9e3d32b8004c..e52aa322b134 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -579,9 +579,11 @@ static struct i2c_client ivtv_i2c_client_template = {
579 .name = "ivtv internal", 579 .name = "ivtv internal",
580}; 580};
581 581
582/* init + register i2c algo-bit adapter */ 582/* init + register i2c adapter + instantiate IR receiver */
583int init_ivtv_i2c(struct ivtv *itv) 583int init_ivtv_i2c(struct ivtv *itv)
584{ 584{
585 int retval;
586
585 IVTV_DEBUG_I2C("i2c init\n"); 587 IVTV_DEBUG_I2C("i2c init\n");
586 588
587 /* Sanity checks for the I2C hardware arrays. They must be the 589 /* Sanity checks for the I2C hardware arrays. They must be the
@@ -619,9 +621,37 @@ int init_ivtv_i2c(struct ivtv *itv)
619 ivtv_setsda(itv, 1); 621 ivtv_setsda(itv, 1);
620 622
621 if (itv->options.newi2c > 0) 623 if (itv->options.newi2c > 0)
622 return i2c_add_adapter(&itv->i2c_adap); 624 retval = i2c_add_adapter(&itv->i2c_adap);
623 else 625 else
624 return i2c_bit_add_bus(&itv->i2c_adap); 626 retval = i2c_bit_add_bus(&itv->i2c_adap);
627
628 /* Instantiate the IR receiver device, if present */
629 if (retval == 0) {
630 struct i2c_board_info info;
631 /* The external IR receiver is at i2c address 0x34 (0x35 for
632 reads). Future Hauppauge cards will have an internal
633 receiver at 0x30 (0x31 for reads). In theory, both can be
634 fitted, and Hauppauge suggest an external overrides an
635 internal.
636
637 That's why we probe 0x1a (~0x34) first. CB
638 */
639 const unsigned short addr_list[] = {
640 0x1a, /* Hauppauge IR external */
641 0x18, /* Hauppauge IR internal */
642 0x71, /* Hauppauge IR (PVR150) */
643 0x64, /* Pixelview IR */
644 0x30, /* KNC ONE IR */
645 0x6b, /* Adaptec IR */
646 I2C_CLIENT_END
647 };
648
649 memset(&info, 0, sizeof(struct i2c_board_info));
650 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
651 i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
652 }
653
654 return retval;
625} 655}
626 656
627void exit_ivtv_i2c(struct ivtv *itv) 657void exit_ivtv_i2c(struct ivtv *itv)
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index c342a9fe983e..99f3c39a118b 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -709,7 +709,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
709 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && 709 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
710 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) 710 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
711 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; 711 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
712 else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) 712 else if (regs->reg < IVTV_ENCODER_SIZE)
713 reg_start = itv->enc_mem; 713 reg_start = itv->enc_mem;
714 else 714 else
715 return -EINVAL; 715 return -EINVAL;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 684f62fa7897..459c04cbf69d 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -75,53 +75,50 @@ struct mt9m001 {
75 unsigned char autoexposure; 75 unsigned char autoexposure;
76}; 76};
77 77
78static int reg_read(struct soc_camera_device *icd, const u8 reg) 78static int reg_read(struct i2c_client *client, const u8 reg)
79{ 79{
80 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
81 struct i2c_client *client = mt9m001->client;
82 s32 data = i2c_smbus_read_word_data(client, reg); 80 s32 data = i2c_smbus_read_word_data(client, reg);
83 return data < 0 ? data : swab16(data); 81 return data < 0 ? data : swab16(data);
84} 82}
85 83
86static int reg_write(struct soc_camera_device *icd, const u8 reg, 84static int reg_write(struct i2c_client *client, const u8 reg,
87 const u16 data) 85 const u16 data)
88{ 86{
89 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 87 return i2c_smbus_write_word_data(client, reg, swab16(data));
90 return i2c_smbus_write_word_data(mt9m001->client, reg, swab16(data));
91} 88}
92 89
93static int reg_set(struct soc_camera_device *icd, const u8 reg, 90static int reg_set(struct i2c_client *client, const u8 reg,
94 const u16 data) 91 const u16 data)
95{ 92{
96 int ret; 93 int ret;
97 94
98 ret = reg_read(icd, reg); 95 ret = reg_read(client, reg);
99 if (ret < 0) 96 if (ret < 0)
100 return ret; 97 return ret;
101 return reg_write(icd, reg, ret | data); 98 return reg_write(client, reg, ret | data);
102} 99}
103 100
104static int reg_clear(struct soc_camera_device *icd, const u8 reg, 101static int reg_clear(struct i2c_client *client, const u8 reg,
105 const u16 data) 102 const u16 data)
106{ 103{
107 int ret; 104 int ret;
108 105
109 ret = reg_read(icd, reg); 106 ret = reg_read(client, reg);
110 if (ret < 0) 107 if (ret < 0)
111 return ret; 108 return ret;
112 return reg_write(icd, reg, ret & ~data); 109 return reg_write(client, reg, ret & ~data);
113} 110}
114 111
115static int mt9m001_init(struct soc_camera_device *icd) 112static int mt9m001_init(struct soc_camera_device *icd)
116{ 113{
117 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 114 struct i2c_client *client = to_i2c_client(icd->control);
118 struct soc_camera_link *icl = mt9m001->client->dev.platform_data; 115 struct soc_camera_link *icl = client->dev.platform_data;
119 int ret; 116 int ret;
120 117
121 dev_dbg(icd->vdev->parent, "%s\n", __func__); 118 dev_dbg(icd->vdev->parent, "%s\n", __func__);
122 119
123 if (icl->power) { 120 if (icl->power) {
124 ret = icl->power(&mt9m001->client->dev, 1); 121 ret = icl->power(&client->dev, 1);
125 if (ret < 0) { 122 if (ret < 0) {
126 dev_err(icd->vdev->parent, 123 dev_err(icd->vdev->parent,
127 "Platform failed to power-on the camera.\n"); 124 "Platform failed to power-on the camera.\n");
@@ -131,49 +128,53 @@ static int mt9m001_init(struct soc_camera_device *icd)
131 128
132 /* The camera could have been already on, we reset it additionally */ 129 /* The camera could have been already on, we reset it additionally */
133 if (icl->reset) 130 if (icl->reset)
134 ret = icl->reset(&mt9m001->client->dev); 131 ret = icl->reset(&client->dev);
135 else 132 else
136 ret = -ENODEV; 133 ret = -ENODEV;
137 134
138 if (ret < 0) { 135 if (ret < 0) {
139 /* Either no platform reset, or platform reset failed */ 136 /* Either no platform reset, or platform reset failed */
140 ret = reg_write(icd, MT9M001_RESET, 1); 137 ret = reg_write(client, MT9M001_RESET, 1);
141 if (!ret) 138 if (!ret)
142 ret = reg_write(icd, MT9M001_RESET, 0); 139 ret = reg_write(client, MT9M001_RESET, 0);
143 } 140 }
144 /* Disable chip, synchronous option update */ 141 /* Disable chip, synchronous option update */
145 if (!ret) 142 if (!ret)
146 ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); 143 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
147 144
148 return ret; 145 return ret;
149} 146}
150 147
151static int mt9m001_release(struct soc_camera_device *icd) 148static int mt9m001_release(struct soc_camera_device *icd)
152{ 149{
153 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 150 struct i2c_client *client = to_i2c_client(icd->control);
154 struct soc_camera_link *icl = mt9m001->client->dev.platform_data; 151 struct soc_camera_link *icl = client->dev.platform_data;
155 152
156 /* Disable the chip */ 153 /* Disable the chip */
157 reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); 154 reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
158 155
159 if (icl->power) 156 if (icl->power)
160 icl->power(&mt9m001->client->dev, 0); 157 icl->power(&client->dev, 0);
161 158
162 return 0; 159 return 0;
163} 160}
164 161
165static int mt9m001_start_capture(struct soc_camera_device *icd) 162static int mt9m001_start_capture(struct soc_camera_device *icd)
166{ 163{
164 struct i2c_client *client = to_i2c_client(icd->control);
165
167 /* Switch to master "normal" mode */ 166 /* Switch to master "normal" mode */
168 if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 2) < 0) 167 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0)
169 return -EIO; 168 return -EIO;
170 return 0; 169 return 0;
171} 170}
172 171
173static int mt9m001_stop_capture(struct soc_camera_device *icd) 172static int mt9m001_stop_capture(struct soc_camera_device *icd)
174{ 173{
174 struct i2c_client *client = to_i2c_client(icd->control);
175
175 /* Stop sensor readout */ 176 /* Stop sensor readout */
176 if (reg_write(icd, MT9M001_OUTPUT_CONTROL, 0) < 0) 177 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
177 return -EIO; 178 return -EIO;
178 return 0; 179 return 0;
179} 180}
@@ -222,28 +223,29 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
222static int mt9m001_set_crop(struct soc_camera_device *icd, 223static int mt9m001_set_crop(struct soc_camera_device *icd,
223 struct v4l2_rect *rect) 224 struct v4l2_rect *rect)
224{ 225{
226 struct i2c_client *client = to_i2c_client(icd->control);
225 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 227 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
226 int ret; 228 int ret;
227 const u16 hblank = 9, vblank = 25; 229 const u16 hblank = 9, vblank = 25;
228 230
229 /* Blanking and start values - default... */ 231 /* Blanking and start values - default... */
230 ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); 232 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
231 if (!ret) 233 if (!ret)
232 ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); 234 ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
233 235
234 /* The caller provides a supported format, as verified per 236 /* The caller provides a supported format, as verified per
235 * call to icd->try_fmt() */ 237 * call to icd->try_fmt() */
236 if (!ret) 238 if (!ret)
237 ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); 239 ret = reg_write(client, MT9M001_COLUMN_START, rect->left);
238 if (!ret) 240 if (!ret)
239 ret = reg_write(icd, MT9M001_ROW_START, rect->top); 241 ret = reg_write(client, MT9M001_ROW_START, rect->top);
240 if (!ret) 242 if (!ret)
241 ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); 243 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1);
242 if (!ret) 244 if (!ret)
243 ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, 245 ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
244 rect->height + icd->y_skip_top - 1); 246 rect->height + icd->y_skip_top - 1);
245 if (!ret && mt9m001->autoexposure) { 247 if (!ret && mt9m001->autoexposure) {
246 ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, 248 ret = reg_write(client, MT9M001_SHUTTER_WIDTH,
247 rect->height + icd->y_skip_top + vblank); 249 rect->height + icd->y_skip_top + vblank);
248 if (!ret) { 250 if (!ret) {
249 const struct v4l2_queryctrl *qctrl = 251 const struct v4l2_queryctrl *qctrl =
@@ -312,16 +314,16 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
312static int mt9m001_get_register(struct soc_camera_device *icd, 314static int mt9m001_get_register(struct soc_camera_device *icd,
313 struct v4l2_dbg_register *reg) 315 struct v4l2_dbg_register *reg)
314{ 316{
315 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 317 struct i2c_client *client = to_i2c_client(icd->control);
316 318
317 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 319 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
318 return -EINVAL; 320 return -EINVAL;
319 321
320 if (reg->match.addr != mt9m001->client->addr) 322 if (reg->match.addr != client->addr)
321 return -ENODEV; 323 return -ENODEV;
322 324
323 reg->size = 2; 325 reg->size = 2;
324 reg->val = reg_read(icd, reg->reg); 326 reg->val = reg_read(client, reg->reg);
325 327
326 if (reg->val > 0xffff) 328 if (reg->val > 0xffff)
327 return -EIO; 329 return -EIO;
@@ -332,15 +334,15 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
332static int mt9m001_set_register(struct soc_camera_device *icd, 334static int mt9m001_set_register(struct soc_camera_device *icd,
333 struct v4l2_dbg_register *reg) 335 struct v4l2_dbg_register *reg)
334{ 336{
335 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 337 struct i2c_client *client = to_i2c_client(icd->control);
336 338
337 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 339 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
338 return -EINVAL; 340 return -EINVAL;
339 341
340 if (reg->match.addr != mt9m001->client->addr) 342 if (reg->match.addr != client->addr)
341 return -ENODEV; 343 return -ENODEV;
342 344
343 if (reg_write(icd, reg->reg, reg->val) < 0) 345 if (reg_write(client, reg->reg, reg->val) < 0)
344 return -EIO; 346 return -EIO;
345 347
346 return 0; 348 return 0;
@@ -416,12 +418,13 @@ static struct soc_camera_ops mt9m001_ops = {
416 418
417static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 419static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
418{ 420{
421 struct i2c_client *client = to_i2c_client(icd->control);
419 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 422 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
420 int data; 423 int data;
421 424
422 switch (ctrl->id) { 425 switch (ctrl->id) {
423 case V4L2_CID_VFLIP: 426 case V4L2_CID_VFLIP:
424 data = reg_read(icd, MT9M001_READ_OPTIONS2); 427 data = reg_read(client, MT9M001_READ_OPTIONS2);
425 if (data < 0) 428 if (data < 0)
426 return -EIO; 429 return -EIO;
427 ctrl->value = !!(data & 0x8000); 430 ctrl->value = !!(data & 0x8000);
@@ -435,6 +438,7 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
435 438
436static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 439static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
437{ 440{
441 struct i2c_client *client = to_i2c_client(icd->control);
438 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 442 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
439 const struct v4l2_queryctrl *qctrl; 443 const struct v4l2_queryctrl *qctrl;
440 int data; 444 int data;
@@ -447,9 +451,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
447 switch (ctrl->id) { 451 switch (ctrl->id) {
448 case V4L2_CID_VFLIP: 452 case V4L2_CID_VFLIP:
449 if (ctrl->value) 453 if (ctrl->value)
450 data = reg_set(icd, MT9M001_READ_OPTIONS2, 0x8000); 454 data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
451 else 455 else
452 data = reg_clear(icd, MT9M001_READ_OPTIONS2, 0x8000); 456 data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
453 if (data < 0) 457 if (data < 0)
454 return -EIO; 458 return -EIO;
455 break; 459 break;
@@ -463,7 +467,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
463 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 467 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
464 468
465 dev_dbg(&icd->dev, "Setting gain %d\n", data); 469 dev_dbg(&icd->dev, "Setting gain %d\n", data);
466 data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); 470 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
467 if (data < 0) 471 if (data < 0)
468 return -EIO; 472 return -EIO;
469 } else { 473 } else {
@@ -481,8 +485,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
481 data = ((gain - 64) * 7 + 28) / 56 + 96; 485 data = ((gain - 64) * 7 + 28) / 56 + 96;
482 486
483 dev_dbg(&icd->dev, "Setting gain from %d to %d\n", 487 dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
484 reg_read(icd, MT9M001_GLOBAL_GAIN), data); 488 reg_read(client, MT9M001_GLOBAL_GAIN), data);
485 data = reg_write(icd, MT9M001_GLOBAL_GAIN, data); 489 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
486 if (data < 0) 490 if (data < 0)
487 return -EIO; 491 return -EIO;
488 } 492 }
@@ -500,8 +504,8 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
500 range / 2) / range + 1; 504 range / 2) / range + 1;
501 505
502 dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", 506 dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n",
503 reg_read(icd, MT9M001_SHUTTER_WIDTH), shutter); 507 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
504 if (reg_write(icd, MT9M001_SHUTTER_WIDTH, shutter) < 0) 508 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
505 return -EIO; 509 return -EIO;
506 icd->exposure = ctrl->value; 510 icd->exposure = ctrl->value;
507 mt9m001->autoexposure = 0; 511 mt9m001->autoexposure = 0;
@@ -510,7 +514,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
510 case V4L2_CID_EXPOSURE_AUTO: 514 case V4L2_CID_EXPOSURE_AUTO:
511 if (ctrl->value) { 515 if (ctrl->value) {
512 const u16 vblank = 25; 516 const u16 vblank = 25;
513 if (reg_write(icd, MT9M001_SHUTTER_WIDTH, icd->height + 517 if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height +
514 icd->y_skip_top + vblank) < 0) 518 icd->y_skip_top + vblank) < 0)
515 return -EIO; 519 return -EIO;
516 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 520 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
@@ -529,8 +533,9 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
529 * this wasn't our capture interface, so, we wait for the right one */ 533 * this wasn't our capture interface, so, we wait for the right one */
530static int mt9m001_video_probe(struct soc_camera_device *icd) 534static int mt9m001_video_probe(struct soc_camera_device *icd)
531{ 535{
536 struct i2c_client *client = to_i2c_client(icd->control);
532 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 537 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
533 struct soc_camera_link *icl = mt9m001->client->dev.platform_data; 538 struct soc_camera_link *icl = client->dev.platform_data;
534 s32 data; 539 s32 data;
535 int ret; 540 int ret;
536 unsigned long flags; 541 unsigned long flags;
@@ -542,11 +547,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
542 return -ENODEV; 547 return -ENODEV;
543 548
544 /* Enable the chip */ 549 /* Enable the chip */
545 data = reg_write(icd, MT9M001_CHIP_ENABLE, 1); 550 data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
546 dev_dbg(&icd->dev, "write: %d\n", data); 551 dev_dbg(&icd->dev, "write: %d\n", data);
547 552
548 /* Read out the chip version register */ 553 /* Read out the chip version register */
549 data = reg_read(icd, MT9M001_CHIP_VERSION); 554 data = reg_read(client, MT9M001_CHIP_VERSION);
550 555
551 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ 556 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
552 switch (data) { 557 switch (data) {
@@ -604,10 +609,13 @@ ei2c:
604static void mt9m001_video_remove(struct soc_camera_device *icd) 609static void mt9m001_video_remove(struct soc_camera_device *icd)
605{ 610{
606 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 611 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
612 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
607 613
608 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, 614 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr,
609 icd->dev.parent, icd->vdev); 615 icd->dev.parent, icd->vdev);
610 soc_camera_video_stop(icd); 616 soc_camera_video_stop(icd);
617 if (icl->free_bus)
618 icl->free_bus(icl);
611} 619}
612 620
613static int mt9m001_probe(struct i2c_client *client, 621static int mt9m001_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index cdd1ddb51388..fc5e2de03766 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -113,10 +113,10 @@
113 * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) 113 * mt9m111: Camera control register addresses (0x200..0x2ff not implemented)
114 */ 114 */
115 115
116#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) 116#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg)
117#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) 117#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val))
118#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) 118#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val))
119#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) 119#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val))
120 120
121#define MT9M111_MIN_DARK_ROWS 8 121#define MT9M111_MIN_DARK_ROWS 8
122#define MT9M111_MIN_DARK_COLS 24 122#define MT9M111_MIN_DARK_COLS 24
@@ -184,58 +184,55 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg)
184 return ret; 184 return ret;
185} 185}
186 186
187static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) 187static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
188{ 188{
189 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
190 struct i2c_client *client = mt9m111->client;
191 int ret; 189 int ret;
192 190
193 ret = reg_page_map_set(client, reg); 191 ret = reg_page_map_set(client, reg);
194 if (!ret) 192 if (!ret)
195 ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); 193 ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff)));
196 194
197 dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); 195 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
198 return ret; 196 return ret;
199} 197}
200 198
201static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, 199static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
202 const u16 data) 200 const u16 data)
203{ 201{
204 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
205 struct i2c_client *client = mt9m111->client;
206 int ret; 202 int ret;
207 203
208 ret = reg_page_map_set(client, reg); 204 ret = reg_page_map_set(client, reg);
209 if (!ret) 205 if (!ret)
210 ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), 206 ret = i2c_smbus_write_word_data(client, (reg & 0xff),
211 swab16(data)); 207 swab16(data));
212 dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); 208 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
213 return ret; 209 return ret;
214} 210}
215 211
216static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, 212static int mt9m111_reg_set(struct i2c_client *client, const u16 reg,
217 const u16 data) 213 const u16 data)
218{ 214{
219 int ret; 215 int ret;
220 216
221 ret = mt9m111_reg_read(icd, reg); 217 ret = mt9m111_reg_read(client, reg);
222 if (ret >= 0) 218 if (ret >= 0)
223 ret = mt9m111_reg_write(icd, reg, ret | data); 219 ret = mt9m111_reg_write(client, reg, ret | data);
224 return ret; 220 return ret;
225} 221}
226 222
227static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, 223static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
228 const u16 data) 224 const u16 data)
229{ 225{
230 int ret; 226 int ret;
231 227
232 ret = mt9m111_reg_read(icd, reg); 228 ret = mt9m111_reg_read(client, reg);
233 return mt9m111_reg_write(icd, reg, ret & ~data); 229 return mt9m111_reg_write(client, reg, ret & ~data);
234} 230}
235 231
236static int mt9m111_set_context(struct soc_camera_device *icd, 232static int mt9m111_set_context(struct soc_camera_device *icd,
237 enum mt9m111_context ctxt) 233 enum mt9m111_context ctxt)
238{ 234{
235 struct i2c_client *client = to_i2c_client(icd->control);
239 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B 236 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
240 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B 237 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
241 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B 238 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -252,6 +249,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
252static int mt9m111_setup_rect(struct soc_camera_device *icd, 249static int mt9m111_setup_rect(struct soc_camera_device *icd,
253 struct v4l2_rect *rect) 250 struct v4l2_rect *rect)
254{ 251{
252 struct i2c_client *client = to_i2c_client(icd->control);
255 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 253 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
256 int ret, is_raw_format; 254 int ret, is_raw_format;
257 int width = rect->width; 255 int width = rect->width;
@@ -296,6 +294,7 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
296 294
297static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) 295static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
298{ 296{
297 struct i2c_client *client = to_i2c_client(icd->control);
299 int ret; 298 int ret;
300 299
301 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 300 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -357,12 +356,13 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
357 356
358static int mt9m111_enable(struct soc_camera_device *icd) 357static int mt9m111_enable(struct soc_camera_device *icd)
359{ 358{
359 struct i2c_client *client = to_i2c_client(icd->control);
360 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 360 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
361 struct soc_camera_link *icl = mt9m111->client->dev.platform_data; 361 struct soc_camera_link *icl = client->dev.platform_data;
362 int ret; 362 int ret;
363 363
364 if (icl->power) { 364 if (icl->power) {
365 ret = icl->power(&mt9m111->client->dev, 1); 365 ret = icl->power(&client->dev, 1);
366 if (ret < 0) { 366 if (ret < 0) {
367 dev_err(icd->vdev->parent, 367 dev_err(icd->vdev->parent,
368 "Platform failed to power-on the camera.\n"); 368 "Platform failed to power-on the camera.\n");
@@ -378,8 +378,9 @@ static int mt9m111_enable(struct soc_camera_device *icd)
378 378
379static int mt9m111_disable(struct soc_camera_device *icd) 379static int mt9m111_disable(struct soc_camera_device *icd)
380{ 380{
381 struct i2c_client *client = to_i2c_client(icd->control);
381 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 382 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
382 struct soc_camera_link *icl = mt9m111->client->dev.platform_data; 383 struct soc_camera_link *icl = client->dev.platform_data;
383 int ret; 384 int ret;
384 385
385 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); 386 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
@@ -387,15 +388,15 @@ static int mt9m111_disable(struct soc_camera_device *icd)
387 mt9m111->powered = 0; 388 mt9m111->powered = 0;
388 389
389 if (icl->power) 390 if (icl->power)
390 icl->power(&mt9m111->client->dev, 0); 391 icl->power(&client->dev, 0);
391 392
392 return ret; 393 return ret;
393} 394}
394 395
395static int mt9m111_reset(struct soc_camera_device *icd) 396static int mt9m111_reset(struct soc_camera_device *icd)
396{ 397{
397 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 398 struct i2c_client *client = to_i2c_client(icd->control);
398 struct soc_camera_link *icl = mt9m111->client->dev.platform_data; 399 struct soc_camera_link *icl = client->dev.platform_data;
399 int ret; 400 int ret;
400 401
401 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); 402 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,7 +407,7 @@ static int mt9m111_reset(struct soc_camera_device *icd)
406 | MT9M111_RESET_RESET_SOC); 407 | MT9M111_RESET_RESET_SOC);
407 408
408 if (icl->reset) 409 if (icl->reset)
409 icl->reset(&mt9m111->client->dev); 410 icl->reset(&client->dev);
410 411
411 return ret; 412 return ret;
412} 413}
@@ -562,15 +563,14 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
562 struct v4l2_dbg_register *reg) 563 struct v4l2_dbg_register *reg)
563{ 564{
564 int val; 565 int val;
565 566 struct i2c_client *client = to_i2c_client(icd->control);
566 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
567 567
568 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 568 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
569 return -EINVAL; 569 return -EINVAL;
570 if (reg->match.addr != mt9m111->client->addr) 570 if (reg->match.addr != client->addr)
571 return -ENODEV; 571 return -ENODEV;
572 572
573 val = mt9m111_reg_read(icd, reg->reg); 573 val = mt9m111_reg_read(client, reg->reg);
574 reg->size = 2; 574 reg->size = 2;
575 reg->val = (u64)val; 575 reg->val = (u64)val;
576 576
@@ -583,15 +583,15 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
583static int mt9m111_set_register(struct soc_camera_device *icd, 583static int mt9m111_set_register(struct soc_camera_device *icd,
584 struct v4l2_dbg_register *reg) 584 struct v4l2_dbg_register *reg)
585{ 585{
586 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 586 struct i2c_client *client = to_i2c_client(icd->control);
587 587
588 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 588 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
589 return -EINVAL; 589 return -EINVAL;
590 590
591 if (reg->match.addr != mt9m111->client->addr) 591 if (reg->match.addr != client->addr)
592 return -ENODEV; 592 return -ENODEV;
593 593
594 if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) 594 if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
595 return -EIO; 595 return -EIO;
596 596
597 return 0; 597 return 0;
@@ -672,6 +672,7 @@ static struct soc_camera_ops mt9m111_ops = {
672 672
673static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) 673static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
674{ 674{
675 struct i2c_client *client = to_i2c_client(icd->control);
675 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 676 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
676 int ret; 677 int ret;
677 678
@@ -692,6 +693,7 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
692 693
693static int mt9m111_get_global_gain(struct soc_camera_device *icd) 694static int mt9m111_get_global_gain(struct soc_camera_device *icd)
694{ 695{
696 struct i2c_client *client = to_i2c_client(icd->control);
695 int data; 697 int data;
696 698
697 data = reg_read(GLOBAL_GAIN); 699 data = reg_read(GLOBAL_GAIN);
@@ -703,6 +705,7 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
703 705
704static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) 706static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
705{ 707{
708 struct i2c_client *client = to_i2c_client(icd->control);
706 u16 val; 709 u16 val;
707 710
708 if (gain > 63 * 2 * 2) 711 if (gain > 63 * 2 * 2)
@@ -721,6 +724,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
721 724
722static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) 725static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
723{ 726{
727 struct i2c_client *client = to_i2c_client(icd->control);
724 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 728 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
725 int ret; 729 int ret;
726 730
@@ -737,6 +741,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
737 741
738static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) 742static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
739{ 743{
744 struct i2c_client *client = to_i2c_client(icd->control);
740 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 745 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
741 int ret; 746 int ret;
742 747
@@ -754,6 +759,7 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
754static int mt9m111_get_control(struct soc_camera_device *icd, 759static int mt9m111_get_control(struct soc_camera_device *icd,
755 struct v4l2_control *ctrl) 760 struct v4l2_control *ctrl)
756{ 761{
762 struct i2c_client *client = to_i2c_client(icd->control);
757 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 763 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
758 int data; 764 int data;
759 765
@@ -898,6 +904,7 @@ static int mt9m111_release(struct soc_camera_device *icd)
898 */ 904 */
899static int mt9m111_video_probe(struct soc_camera_device *icd) 905static int mt9m111_video_probe(struct soc_camera_device *icd)
900{ 906{
907 struct i2c_client *client = to_i2c_client(icd->control);
901 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 908 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
902 s32 data; 909 s32 data;
903 int ret; 910 int ret;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 2b0927bfd217..f72aeb7c4deb 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -76,64 +76,61 @@ struct mt9t031 {
76 u16 yskip; 76 u16 yskip;
77}; 77};
78 78
79static int reg_read(struct soc_camera_device *icd, const u8 reg) 79static int reg_read(struct i2c_client *client, const u8 reg)
80{ 80{
81 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
82 struct i2c_client *client = mt9t031->client;
83 s32 data = i2c_smbus_read_word_data(client, reg); 81 s32 data = i2c_smbus_read_word_data(client, reg);
84 return data < 0 ? data : swab16(data); 82 return data < 0 ? data : swab16(data);
85} 83}
86 84
87static int reg_write(struct soc_camera_device *icd, const u8 reg, 85static int reg_write(struct i2c_client *client, const u8 reg,
88 const u16 data) 86 const u16 data)
89{ 87{
90 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 88 return i2c_smbus_write_word_data(client, reg, swab16(data));
91 return i2c_smbus_write_word_data(mt9t031->client, reg, swab16(data));
92} 89}
93 90
94static int reg_set(struct soc_camera_device *icd, const u8 reg, 91static int reg_set(struct i2c_client *client, const u8 reg,
95 const u16 data) 92 const u16 data)
96{ 93{
97 int ret; 94 int ret;
98 95
99 ret = reg_read(icd, reg); 96 ret = reg_read(client, reg);
100 if (ret < 0) 97 if (ret < 0)
101 return ret; 98 return ret;
102 return reg_write(icd, reg, ret | data); 99 return reg_write(client, reg, ret | data);
103} 100}
104 101
105static int reg_clear(struct soc_camera_device *icd, const u8 reg, 102static int reg_clear(struct i2c_client *client, const u8 reg,
106 const u16 data) 103 const u16 data)
107{ 104{
108 int ret; 105 int ret;
109 106
110 ret = reg_read(icd, reg); 107 ret = reg_read(client, reg);
111 if (ret < 0) 108 if (ret < 0)
112 return ret; 109 return ret;
113 return reg_write(icd, reg, ret & ~data); 110 return reg_write(client, reg, ret & ~data);
114} 111}
115 112
116static int set_shutter(struct soc_camera_device *icd, const u32 data) 113static int set_shutter(struct i2c_client *client, const u32 data)
117{ 114{
118 int ret; 115 int ret;
119 116
120 ret = reg_write(icd, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16); 117 ret = reg_write(client, MT9T031_SHUTTER_WIDTH_UPPER, data >> 16);
121 118
122 if (ret >= 0) 119 if (ret >= 0)
123 ret = reg_write(icd, MT9T031_SHUTTER_WIDTH, data & 0xffff); 120 ret = reg_write(client, MT9T031_SHUTTER_WIDTH, data & 0xffff);
124 121
125 return ret; 122 return ret;
126} 123}
127 124
128static int get_shutter(struct soc_camera_device *icd, u32 *data) 125static int get_shutter(struct i2c_client *client, u32 *data)
129{ 126{
130 int ret; 127 int ret;
131 128
132 ret = reg_read(icd, MT9T031_SHUTTER_WIDTH_UPPER); 129 ret = reg_read(client, MT9T031_SHUTTER_WIDTH_UPPER);
133 *data = ret << 16; 130 *data = ret << 16;
134 131
135 if (ret >= 0) 132 if (ret >= 0)
136 ret = reg_read(icd, MT9T031_SHUTTER_WIDTH); 133 ret = reg_read(client, MT9T031_SHUTTER_WIDTH);
137 *data |= ret & 0xffff; 134 *data |= ret & 0xffff;
138 135
139 return ret < 0 ? ret : 0; 136 return ret < 0 ? ret : 0;
@@ -141,12 +138,12 @@ static int get_shutter(struct soc_camera_device *icd, u32 *data)
141 138
142static int mt9t031_init(struct soc_camera_device *icd) 139static int mt9t031_init(struct soc_camera_device *icd)
143{ 140{
144 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 141 struct i2c_client *client = to_i2c_client(icd->control);
145 struct soc_camera_link *icl = mt9t031->client->dev.platform_data; 142 struct soc_camera_link *icl = client->dev.platform_data;
146 int ret; 143 int ret;
147 144
148 if (icl->power) { 145 if (icl->power) {
149 ret = icl->power(&mt9t031->client->dev, 1); 146 ret = icl->power(&client->dev, 1);
150 if (ret < 0) { 147 if (ret < 0) {
151 dev_err(icd->vdev->parent, 148 dev_err(icd->vdev->parent,
152 "Platform failed to power-on the camera.\n"); 149 "Platform failed to power-on the camera.\n");
@@ -155,44 +152,48 @@ static int mt9t031_init(struct soc_camera_device *icd)
155 } 152 }
156 153
157 /* Disable chip output, synchronous option update */ 154 /* Disable chip output, synchronous option update */
158 ret = reg_write(icd, MT9T031_RESET, 1); 155 ret = reg_write(client, MT9T031_RESET, 1);
159 if (ret >= 0) 156 if (ret >= 0)
160 ret = reg_write(icd, MT9T031_RESET, 0); 157 ret = reg_write(client, MT9T031_RESET, 0);
161 if (ret >= 0) 158 if (ret >= 0)
162 ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); 159 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
163 160
164 if (ret < 0 && icl->power) 161 if (ret < 0 && icl->power)
165 icl->power(&mt9t031->client->dev, 0); 162 icl->power(&client->dev, 0);
166 163
167 return ret >= 0 ? 0 : -EIO; 164 return ret >= 0 ? 0 : -EIO;
168} 165}
169 166
170static int mt9t031_release(struct soc_camera_device *icd) 167static int mt9t031_release(struct soc_camera_device *icd)
171{ 168{
172 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 169 struct i2c_client *client = to_i2c_client(icd->control);
173 struct soc_camera_link *icl = mt9t031->client->dev.platform_data; 170 struct soc_camera_link *icl = client->dev.platform_data;
174 171
175 /* Disable the chip */ 172 /* Disable the chip */
176 reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); 173 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
177 174
178 if (icl->power) 175 if (icl->power)
179 icl->power(&mt9t031->client->dev, 0); 176 icl->power(&client->dev, 0);
180 177
181 return 0; 178 return 0;
182} 179}
183 180
184static int mt9t031_start_capture(struct soc_camera_device *icd) 181static int mt9t031_start_capture(struct soc_camera_device *icd)
185{ 182{
183 struct i2c_client *client = to_i2c_client(icd->control);
184
186 /* Switch to master "normal" mode */ 185 /* Switch to master "normal" mode */
187 if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) 186 if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
188 return -EIO; 187 return -EIO;
189 return 0; 188 return 0;
190} 189}
191 190
192static int mt9t031_stop_capture(struct soc_camera_device *icd) 191static int mt9t031_stop_capture(struct soc_camera_device *icd)
193{ 192{
193 struct i2c_client *client = to_i2c_client(icd->control);
194
194 /* Stop sensor readout */ 195 /* Stop sensor readout */
195 if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) 196 if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
196 return -EIO; 197 return -EIO;
197 return 0; 198 return 0;
198} 199}
@@ -200,14 +201,16 @@ static int mt9t031_stop_capture(struct soc_camera_device *icd)
200static int mt9t031_set_bus_param(struct soc_camera_device *icd, 201static int mt9t031_set_bus_param(struct soc_camera_device *icd,
201 unsigned long flags) 202 unsigned long flags)
202{ 203{
204 struct i2c_client *client = to_i2c_client(icd->control);
205
203 /* The caller should have queried our parameters, check anyway */ 206 /* The caller should have queried our parameters, check anyway */
204 if (flags & ~MT9T031_BUS_PARAM) 207 if (flags & ~MT9T031_BUS_PARAM)
205 return -EINVAL; 208 return -EINVAL;
206 209
207 if (flags & SOCAM_PCLK_SAMPLE_FALLING) 210 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
208 reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); 211 reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
209 else 212 else
210 reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); 213 reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
211 214
212 return 0; 215 return 0;
213} 216}
@@ -235,6 +238,7 @@ static void recalculate_limits(struct soc_camera_device *icd,
235static int mt9t031_set_params(struct soc_camera_device *icd, 238static int mt9t031_set_params(struct soc_camera_device *icd,
236 struct v4l2_rect *rect, u16 xskip, u16 yskip) 239 struct v4l2_rect *rect, u16 xskip, u16 yskip)
237{ 240{
241 struct i2c_client *client = to_i2c_client(icd->control);
238 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 242 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
239 int ret; 243 int ret;
240 u16 xbin, ybin, width, height, left, top; 244 u16 xbin, ybin, width, height, left, top;
@@ -277,22 +281,22 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
277 } 281 }
278 282
279 /* Disable register update, reconfigure atomically */ 283 /* Disable register update, reconfigure atomically */
280 ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1); 284 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
281 if (ret < 0) 285 if (ret < 0)
282 return ret; 286 return ret;
283 287
284 /* Blanking and start values - default... */ 288 /* Blanking and start values - default... */
285 ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank); 289 ret = reg_write(client, MT9T031_HORIZONTAL_BLANKING, hblank);
286 if (ret >= 0) 290 if (ret >= 0)
287 ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank); 291 ret = reg_write(client, MT9T031_VERTICAL_BLANKING, vblank);
288 292
289 if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) { 293 if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
290 /* Binning, skipping */ 294 /* Binning, skipping */
291 if (ret >= 0) 295 if (ret >= 0)
292 ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE, 296 ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
293 ((xbin - 1) << 4) | (xskip - 1)); 297 ((xbin - 1) << 4) | (xskip - 1));
294 if (ret >= 0) 298 if (ret >= 0)
295 ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE, 299 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
296 ((ybin - 1) << 4) | (yskip - 1)); 300 ((ybin - 1) << 4) | (yskip - 1));
297 } 301 }
298 dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); 302 dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
@@ -300,16 +304,16 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
300 /* The caller provides a supported format, as guaranteed by 304 /* The caller provides a supported format, as guaranteed by
301 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ 305 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
302 if (ret >= 0) 306 if (ret >= 0)
303 ret = reg_write(icd, MT9T031_COLUMN_START, left); 307 ret = reg_write(client, MT9T031_COLUMN_START, left);
304 if (ret >= 0) 308 if (ret >= 0)
305 ret = reg_write(icd, MT9T031_ROW_START, top); 309 ret = reg_write(client, MT9T031_ROW_START, top);
306 if (ret >= 0) 310 if (ret >= 0)
307 ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1); 311 ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1);
308 if (ret >= 0) 312 if (ret >= 0)
309 ret = reg_write(icd, MT9T031_WINDOW_HEIGHT, 313 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
310 height + icd->y_skip_top - 1); 314 height + icd->y_skip_top - 1);
311 if (ret >= 0 && mt9t031->autoexposure) { 315 if (ret >= 0 && mt9t031->autoexposure) {
312 ret = set_shutter(icd, height + icd->y_skip_top + vblank); 316 ret = set_shutter(client, height + icd->y_skip_top + vblank);
313 if (ret >= 0) { 317 if (ret >= 0) {
314 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 318 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
315 const struct v4l2_queryctrl *qctrl = 319 const struct v4l2_queryctrl *qctrl =
@@ -324,7 +328,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
324 328
325 /* Re-enable register update, commit all changes */ 329 /* Re-enable register update, commit all changes */
326 if (ret >= 0) 330 if (ret >= 0)
327 ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1); 331 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
328 332
329 return ret < 0 ? ret : 0; 333 return ret < 0 ? ret : 0;
330} 334}
@@ -417,15 +421,15 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
417static int mt9t031_get_register(struct soc_camera_device *icd, 421static int mt9t031_get_register(struct soc_camera_device *icd,
418 struct v4l2_dbg_register *reg) 422 struct v4l2_dbg_register *reg)
419{ 423{
420 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 424 struct i2c_client *client = to_i2c_client(icd->control);
421 425
422 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 426 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
423 return -EINVAL; 427 return -EINVAL;
424 428
425 if (reg->match.addr != mt9t031->client->addr) 429 if (reg->match.addr != client->addr)
426 return -ENODEV; 430 return -ENODEV;
427 431
428 reg->val = reg_read(icd, reg->reg); 432 reg->val = reg_read(client, reg->reg);
429 433
430 if (reg->val > 0xffff) 434 if (reg->val > 0xffff)
431 return -EIO; 435 return -EIO;
@@ -436,15 +440,15 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
436static int mt9t031_set_register(struct soc_camera_device *icd, 440static int mt9t031_set_register(struct soc_camera_device *icd,
437 struct v4l2_dbg_register *reg) 441 struct v4l2_dbg_register *reg)
438{ 442{
439 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 443 struct i2c_client *client = to_i2c_client(icd->control);
440 444
441 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 445 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
442 return -EINVAL; 446 return -EINVAL;
443 447
444 if (reg->match.addr != mt9t031->client->addr) 448 if (reg->match.addr != client->addr)
445 return -ENODEV; 449 return -ENODEV;
446 450
447 if (reg_write(icd, reg->reg, reg->val) < 0) 451 if (reg_write(client, reg->reg, reg->val) < 0)
448 return -EIO; 452 return -EIO;
449 453
450 return 0; 454 return 0;
@@ -528,18 +532,19 @@ static struct soc_camera_ops mt9t031_ops = {
528 532
529static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 533static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
530{ 534{
535 struct i2c_client *client = to_i2c_client(icd->control);
531 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 536 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
532 int data; 537 int data;
533 538
534 switch (ctrl->id) { 539 switch (ctrl->id) {
535 case V4L2_CID_VFLIP: 540 case V4L2_CID_VFLIP:
536 data = reg_read(icd, MT9T031_READ_MODE_2); 541 data = reg_read(client, MT9T031_READ_MODE_2);
537 if (data < 0) 542 if (data < 0)
538 return -EIO; 543 return -EIO;
539 ctrl->value = !!(data & 0x8000); 544 ctrl->value = !!(data & 0x8000);
540 break; 545 break;
541 case V4L2_CID_HFLIP: 546 case V4L2_CID_HFLIP:
542 data = reg_read(icd, MT9T031_READ_MODE_2); 547 data = reg_read(client, MT9T031_READ_MODE_2);
543 if (data < 0) 548 if (data < 0)
544 return -EIO; 549 return -EIO;
545 ctrl->value = !!(data & 0x4000); 550 ctrl->value = !!(data & 0x4000);
@@ -553,6 +558,7 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
553 558
554static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 559static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
555{ 560{
561 struct i2c_client *client = to_i2c_client(icd->control);
556 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 562 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
557 const struct v4l2_queryctrl *qctrl; 563 const struct v4l2_queryctrl *qctrl;
558 int data; 564 int data;
@@ -565,17 +571,17 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
565 switch (ctrl->id) { 571 switch (ctrl->id) {
566 case V4L2_CID_VFLIP: 572 case V4L2_CID_VFLIP:
567 if (ctrl->value) 573 if (ctrl->value)
568 data = reg_set(icd, MT9T031_READ_MODE_2, 0x8000); 574 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
569 else 575 else
570 data = reg_clear(icd, MT9T031_READ_MODE_2, 0x8000); 576 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
571 if (data < 0) 577 if (data < 0)
572 return -EIO; 578 return -EIO;
573 break; 579 break;
574 case V4L2_CID_HFLIP: 580 case V4L2_CID_HFLIP:
575 if (ctrl->value) 581 if (ctrl->value)
576 data = reg_set(icd, MT9T031_READ_MODE_2, 0x4000); 582 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
577 else 583 else
578 data = reg_clear(icd, MT9T031_READ_MODE_2, 0x4000); 584 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
579 if (data < 0) 585 if (data < 0)
580 return -EIO; 586 return -EIO;
581 break; 587 break;
@@ -589,7 +595,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
589 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 595 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
590 596
591 dev_dbg(&icd->dev, "Setting gain %d\n", data); 597 dev_dbg(&icd->dev, "Setting gain %d\n", data);
592 data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); 598 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
593 if (data < 0) 599 if (data < 0)
594 return -EIO; 600 return -EIO;
595 } else { 601 } else {
@@ -609,8 +615,8 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
609 data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; 615 data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
610 616
611 dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", 617 dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
612 reg_read(icd, MT9T031_GLOBAL_GAIN), data); 618 reg_read(client, MT9T031_GLOBAL_GAIN), data);
613 data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); 619 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
614 if (data < 0) 620 if (data < 0)
615 return -EIO; 621 return -EIO;
616 } 622 }
@@ -628,10 +634,10 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
628 range / 2) / range + 1; 634 range / 2) / range + 1;
629 u32 old; 635 u32 old;
630 636
631 get_shutter(icd, &old); 637 get_shutter(client, &old);
632 dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", 638 dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n",
633 old, shutter); 639 old, shutter);
634 if (set_shutter(icd, shutter) < 0) 640 if (set_shutter(client, shutter) < 0)
635 return -EIO; 641 return -EIO;
636 icd->exposure = ctrl->value; 642 icd->exposure = ctrl->value;
637 mt9t031->autoexposure = 0; 643 mt9t031->autoexposure = 0;
@@ -641,7 +647,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
641 if (ctrl->value) { 647 if (ctrl->value) {
642 const u16 vblank = MT9T031_VERTICAL_BLANK; 648 const u16 vblank = MT9T031_VERTICAL_BLANK;
643 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 649 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
644 if (set_shutter(icd, icd->height + 650 if (set_shutter(client, icd->height +
645 icd->y_skip_top + vblank) < 0) 651 icd->y_skip_top + vblank) < 0)
646 return -EIO; 652 return -EIO;
647 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 653 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
@@ -661,6 +667,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
661 * this wasn't our capture interface, so, we wait for the right one */ 667 * this wasn't our capture interface, so, we wait for the right one */
662static int mt9t031_video_probe(struct soc_camera_device *icd) 668static int mt9t031_video_probe(struct soc_camera_device *icd)
663{ 669{
670 struct i2c_client *client = to_i2c_client(icd->control);
664 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 671 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
665 s32 data; 672 s32 data;
666 int ret; 673 int ret;
@@ -672,11 +679,11 @@ static int mt9t031_video_probe(struct soc_camera_device *icd)
672 return -ENODEV; 679 return -ENODEV;
673 680
674 /* Enable the chip */ 681 /* Enable the chip */
675 data = reg_write(icd, MT9T031_CHIP_ENABLE, 1); 682 data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
676 dev_dbg(&icd->dev, "write: %d\n", data); 683 dev_dbg(&icd->dev, "write: %d\n", data);
677 684
678 /* Read out the chip version register */ 685 /* Read out the chip version register */
679 data = reg_read(icd, MT9T031_CHIP_VERSION); 686 data = reg_read(client, MT9T031_CHIP_VERSION);
680 687
681 switch (data) { 688 switch (data) {
682 case 0x1621: 689 case 0x1621:
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 4d3b4813c322..be20d312b1dc 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -91,51 +91,49 @@ struct mt9v022 {
91 u16 chip_control; 91 u16 chip_control;
92}; 92};
93 93
94static int reg_read(struct soc_camera_device *icd, const u8 reg) 94static int reg_read(struct i2c_client *client, const u8 reg)
95{ 95{
96 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
97 struct i2c_client *client = mt9v022->client;
98 s32 data = i2c_smbus_read_word_data(client, reg); 96 s32 data = i2c_smbus_read_word_data(client, reg);
99 return data < 0 ? data : swab16(data); 97 return data < 0 ? data : swab16(data);
100} 98}
101 99
102static int reg_write(struct soc_camera_device *icd, const u8 reg, 100static int reg_write(struct i2c_client *client, const u8 reg,
103 const u16 data) 101 const u16 data)
104{ 102{
105 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 103 return i2c_smbus_write_word_data(client, reg, swab16(data));
106 return i2c_smbus_write_word_data(mt9v022->client, reg, swab16(data));
107} 104}
108 105
109static int reg_set(struct soc_camera_device *icd, const u8 reg, 106static int reg_set(struct i2c_client *client, const u8 reg,
110 const u16 data) 107 const u16 data)
111{ 108{
112 int ret; 109 int ret;
113 110
114 ret = reg_read(icd, reg); 111 ret = reg_read(client, reg);
115 if (ret < 0) 112 if (ret < 0)
116 return ret; 113 return ret;
117 return reg_write(icd, reg, ret | data); 114 return reg_write(client, reg, ret | data);
118} 115}
119 116
120static int reg_clear(struct soc_camera_device *icd, const u8 reg, 117static int reg_clear(struct i2c_client *client, const u8 reg,
121 const u16 data) 118 const u16 data)
122{ 119{
123 int ret; 120 int ret;
124 121
125 ret = reg_read(icd, reg); 122 ret = reg_read(client, reg);
126 if (ret < 0) 123 if (ret < 0)
127 return ret; 124 return ret;
128 return reg_write(icd, reg, ret & ~data); 125 return reg_write(client, reg, ret & ~data);
129} 126}
130 127
131static int mt9v022_init(struct soc_camera_device *icd) 128static int mt9v022_init(struct soc_camera_device *icd)
132{ 129{
130 struct i2c_client *client = to_i2c_client(icd->control);
133 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 131 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
134 struct soc_camera_link *icl = mt9v022->client->dev.platform_data; 132 struct soc_camera_link *icl = client->dev.platform_data;
135 int ret; 133 int ret;
136 134
137 if (icl->power) { 135 if (icl->power) {
138 ret = icl->power(&mt9v022->client->dev, 1); 136 ret = icl->power(&client->dev, 1);
139 if (ret < 0) { 137 if (ret < 0) {
140 dev_err(icd->vdev->parent, 138 dev_err(icd->vdev->parent,
141 "Platform failed to power-on the camera.\n"); 139 "Platform failed to power-on the camera.\n");
@@ -148,27 +146,27 @@ static int mt9v022_init(struct soc_camera_device *icd)
148 * if available. Soft reset is done in video_probe(). 146 * if available. Soft reset is done in video_probe().
149 */ 147 */
150 if (icl->reset) 148 if (icl->reset)
151 icl->reset(&mt9v022->client->dev); 149 icl->reset(&client->dev);
152 150
153 /* Almost the default mode: master, parallel, simultaneous, and an 151 /* Almost the default mode: master, parallel, simultaneous, and an
154 * undocumented bit 0x200, which is present in table 7, but not in 8, 152 * undocumented bit 0x200, which is present in table 7, but not in 8,
155 * plus snapshot mode to disable scan for now */ 153 * plus snapshot mode to disable scan for now */
156 mt9v022->chip_control |= 0x10; 154 mt9v022->chip_control |= 0x10;
157 ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); 155 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
158 if (!ret) 156 if (!ret)
159 ret = reg_write(icd, MT9V022_READ_MODE, 0x300); 157 ret = reg_write(client, MT9V022_READ_MODE, 0x300);
160 158
161 /* All defaults */ 159 /* All defaults */
162 if (!ret) 160 if (!ret)
163 /* AEC, AGC on */ 161 /* AEC, AGC on */
164 ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); 162 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
165 if (!ret) 163 if (!ret)
166 ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); 164 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
167 if (!ret) 165 if (!ret)
168 /* default - auto */ 166 /* default - auto */
169 ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); 167 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
170 if (!ret) 168 if (!ret)
171 ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); 169 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
172 170
173 return ret; 171 return ret;
174} 172}
@@ -186,10 +184,11 @@ static int mt9v022_release(struct soc_camera_device *icd)
186 184
187static int mt9v022_start_capture(struct soc_camera_device *icd) 185static int mt9v022_start_capture(struct soc_camera_device *icd)
188{ 186{
187 struct i2c_client *client = to_i2c_client(icd->control);
189 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 188 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
190 /* Switch to master "normal" mode */ 189 /* Switch to master "normal" mode */
191 mt9v022->chip_control &= ~0x10; 190 mt9v022->chip_control &= ~0x10;
192 if (reg_write(icd, MT9V022_CHIP_CONTROL, 191 if (reg_write(client, MT9V022_CHIP_CONTROL,
193 mt9v022->chip_control) < 0) 192 mt9v022->chip_control) < 0)
194 return -EIO; 193 return -EIO;
195 return 0; 194 return 0;
@@ -197,10 +196,11 @@ static int mt9v022_start_capture(struct soc_camera_device *icd)
197 196
198static int mt9v022_stop_capture(struct soc_camera_device *icd) 197static int mt9v022_stop_capture(struct soc_camera_device *icd)
199{ 198{
199 struct i2c_client *client = to_i2c_client(icd->control);
200 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 200 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
201 /* Switch to snapshot mode */ 201 /* Switch to snapshot mode */
202 mt9v022->chip_control |= 0x10; 202 mt9v022->chip_control |= 0x10;
203 if (reg_write(icd, MT9V022_CHIP_CONTROL, 203 if (reg_write(client, MT9V022_CHIP_CONTROL,
204 mt9v022->chip_control) < 0) 204 mt9v022->chip_control) < 0)
205 return -EIO; 205 return -EIO;
206 return 0; 206 return 0;
@@ -209,8 +209,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
209static int mt9v022_set_bus_param(struct soc_camera_device *icd, 209static int mt9v022_set_bus_param(struct soc_camera_device *icd,
210 unsigned long flags) 210 unsigned long flags)
211{ 211{
212 struct i2c_client *client = to_i2c_client(icd->control);
212 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 213 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
213 struct soc_camera_link *icl = mt9v022->client->dev.platform_data; 214 struct soc_camera_link *icl = client->dev.platform_data;
214 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; 215 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
215 int ret; 216 int ret;
216 u16 pixclk = 0; 217 u16 pixclk = 0;
@@ -243,14 +244,14 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
243 if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH)) 244 if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
244 pixclk |= 0x2; 245 pixclk |= 0x2;
245 246
246 ret = reg_write(icd, MT9V022_PIXCLK_FV_LV, pixclk); 247 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
247 if (ret < 0) 248 if (ret < 0)
248 return ret; 249 return ret;
249 250
250 if (!(flags & SOCAM_MASTER)) 251 if (!(flags & SOCAM_MASTER))
251 mt9v022->chip_control &= ~0x8; 252 mt9v022->chip_control &= ~0x8;
252 253
253 ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); 254 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
254 if (ret < 0) 255 if (ret < 0)
255 return ret; 256 return ret;
256 257
@@ -282,35 +283,36 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
282static int mt9v022_set_crop(struct soc_camera_device *icd, 283static int mt9v022_set_crop(struct soc_camera_device *icd,
283 struct v4l2_rect *rect) 284 struct v4l2_rect *rect)
284{ 285{
286 struct i2c_client *client = to_i2c_client(icd->control);
285 int ret; 287 int ret;
286 288
287 /* Like in example app. Contradicts the datasheet though */ 289 /* Like in example app. Contradicts the datasheet though */
288 ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); 290 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
289 if (ret >= 0) { 291 if (ret >= 0) {
290 if (ret & 1) /* Autoexposure */ 292 if (ret & 1) /* Autoexposure */
291 ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 293 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
292 rect->height + icd->y_skip_top + 43); 294 rect->height + icd->y_skip_top + 43);
293 else 295 else
294 ret = reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, 296 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
295 rect->height + icd->y_skip_top + 43); 297 rect->height + icd->y_skip_top + 43);
296 } 298 }
297 /* Setup frame format: defaults apart from width and height */ 299 /* Setup frame format: defaults apart from width and height */
298 if (!ret) 300 if (!ret)
299 ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); 301 ret = reg_write(client, MT9V022_COLUMN_START, rect->left);
300 if (!ret) 302 if (!ret)
301 ret = reg_write(icd, MT9V022_ROW_START, rect->top); 303 ret = reg_write(client, MT9V022_ROW_START, rect->top);
302 if (!ret) 304 if (!ret)
303 /* Default 94, Phytec driver says: 305 /* Default 94, Phytec driver says:
304 * "width + horizontal blank >= 660" */ 306 * "width + horizontal blank >= 660" */
305 ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, 307 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
306 rect->width > 660 - 43 ? 43 : 308 rect->width > 660 - 43 ? 43 :
307 660 - rect->width); 309 660 - rect->width);
308 if (!ret) 310 if (!ret)
309 ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); 311 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
310 if (!ret) 312 if (!ret)
311 ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); 313 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width);
312 if (!ret) 314 if (!ret)
313 ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, 315 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
314 rect->height + icd->y_skip_top); 316 rect->height + icd->y_skip_top);
315 317
316 if (ret < 0) 318 if (ret < 0)
@@ -396,16 +398,16 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
396static int mt9v022_get_register(struct soc_camera_device *icd, 398static int mt9v022_get_register(struct soc_camera_device *icd,
397 struct v4l2_dbg_register *reg) 399 struct v4l2_dbg_register *reg)
398{ 400{
399 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 401 struct i2c_client *client = to_i2c_client(icd->control);
400 402
401 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 403 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
402 return -EINVAL; 404 return -EINVAL;
403 405
404 if (reg->match.addr != mt9v022->client->addr) 406 if (reg->match.addr != client->addr)
405 return -ENODEV; 407 return -ENODEV;
406 408
407 reg->size = 2; 409 reg->size = 2;
408 reg->val = reg_read(icd, reg->reg); 410 reg->val = reg_read(client, reg->reg);
409 411
410 if (reg->val > 0xffff) 412 if (reg->val > 0xffff)
411 return -EIO; 413 return -EIO;
@@ -416,15 +418,15 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
416static int mt9v022_set_register(struct soc_camera_device *icd, 418static int mt9v022_set_register(struct soc_camera_device *icd,
417 struct v4l2_dbg_register *reg) 419 struct v4l2_dbg_register *reg)
418{ 420{
419 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 421 struct i2c_client *client = to_i2c_client(icd->control);
420 422
421 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 423 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
422 return -EINVAL; 424 return -EINVAL;
423 425
424 if (reg->match.addr != mt9v022->client->addr) 426 if (reg->match.addr != client->addr)
425 return -ENODEV; 427 return -ENODEV;
426 428
427 if (reg_write(icd, reg->reg, reg->val) < 0) 429 if (reg_write(client, reg->reg, reg->val) < 0)
428 return -EIO; 430 return -EIO;
429 431
430 return 0; 432 return 0;
@@ -517,29 +519,30 @@ static struct soc_camera_ops mt9v022_ops = {
517static int mt9v022_get_control(struct soc_camera_device *icd, 519static int mt9v022_get_control(struct soc_camera_device *icd,
518 struct v4l2_control *ctrl) 520 struct v4l2_control *ctrl)
519{ 521{
522 struct i2c_client *client = to_i2c_client(icd->control);
520 int data; 523 int data;
521 524
522 switch (ctrl->id) { 525 switch (ctrl->id) {
523 case V4L2_CID_VFLIP: 526 case V4L2_CID_VFLIP:
524 data = reg_read(icd, MT9V022_READ_MODE); 527 data = reg_read(client, MT9V022_READ_MODE);
525 if (data < 0) 528 if (data < 0)
526 return -EIO; 529 return -EIO;
527 ctrl->value = !!(data & 0x10); 530 ctrl->value = !!(data & 0x10);
528 break; 531 break;
529 case V4L2_CID_HFLIP: 532 case V4L2_CID_HFLIP:
530 data = reg_read(icd, MT9V022_READ_MODE); 533 data = reg_read(client, MT9V022_READ_MODE);
531 if (data < 0) 534 if (data < 0)
532 return -EIO; 535 return -EIO;
533 ctrl->value = !!(data & 0x20); 536 ctrl->value = !!(data & 0x20);
534 break; 537 break;
535 case V4L2_CID_EXPOSURE_AUTO: 538 case V4L2_CID_EXPOSURE_AUTO:
536 data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); 539 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
537 if (data < 0) 540 if (data < 0)
538 return -EIO; 541 return -EIO;
539 ctrl->value = !!(data & 0x1); 542 ctrl->value = !!(data & 0x1);
540 break; 543 break;
541 case V4L2_CID_AUTOGAIN: 544 case V4L2_CID_AUTOGAIN:
542 data = reg_read(icd, MT9V022_AEC_AGC_ENABLE); 545 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
543 if (data < 0) 546 if (data < 0)
544 return -EIO; 547 return -EIO;
545 ctrl->value = !!(data & 0x2); 548 ctrl->value = !!(data & 0x2);
@@ -552,6 +555,7 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
552 struct v4l2_control *ctrl) 555 struct v4l2_control *ctrl)
553{ 556{
554 int data; 557 int data;
558 struct i2c_client *client = to_i2c_client(icd->control);
555 const struct v4l2_queryctrl *qctrl; 559 const struct v4l2_queryctrl *qctrl;
556 560
557 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); 561 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
@@ -562,17 +566,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
562 switch (ctrl->id) { 566 switch (ctrl->id) {
563 case V4L2_CID_VFLIP: 567 case V4L2_CID_VFLIP:
564 if (ctrl->value) 568 if (ctrl->value)
565 data = reg_set(icd, MT9V022_READ_MODE, 0x10); 569 data = reg_set(client, MT9V022_READ_MODE, 0x10);
566 else 570 else
567 data = reg_clear(icd, MT9V022_READ_MODE, 0x10); 571 data = reg_clear(client, MT9V022_READ_MODE, 0x10);
568 if (data < 0) 572 if (data < 0)
569 return -EIO; 573 return -EIO;
570 break; 574 break;
571 case V4L2_CID_HFLIP: 575 case V4L2_CID_HFLIP:
572 if (ctrl->value) 576 if (ctrl->value)
573 data = reg_set(icd, MT9V022_READ_MODE, 0x20); 577 data = reg_set(client, MT9V022_READ_MODE, 0x20);
574 else 578 else
575 data = reg_clear(icd, MT9V022_READ_MODE, 0x20); 579 data = reg_clear(client, MT9V022_READ_MODE, 0x20);
576 if (data < 0) 580 if (data < 0)
577 return -EIO; 581 return -EIO;
578 break; 582 break;
@@ -593,12 +597,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
593 /* The user wants to set gain manually, hope, she 597 /* The user wants to set gain manually, hope, she
594 * knows, what she's doing... Switch AGC off. */ 598 * knows, what she's doing... Switch AGC off. */
595 599
596 if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 600 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
597 return -EIO; 601 return -EIO;
598 602
599 dev_info(&icd->dev, "Setting gain from %d to %lu\n", 603 dev_info(&icd->dev, "Setting gain from %d to %lu\n",
600 reg_read(icd, MT9V022_ANALOG_GAIN), gain); 604 reg_read(client, MT9V022_ANALOG_GAIN), gain);
601 if (reg_write(icd, MT9V022_ANALOG_GAIN, gain) < 0) 605 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
602 return -EIO; 606 return -EIO;
603 icd->gain = ctrl->value; 607 icd->gain = ctrl->value;
604 } 608 }
@@ -614,13 +618,13 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
614 /* The user wants to set shutter width manually, hope, 618 /* The user wants to set shutter width manually, hope,
615 * she knows, what she's doing... Switch AEC off. */ 619 * she knows, what she's doing... Switch AEC off. */
616 620
617 if (reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 621 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
618 return -EIO; 622 return -EIO;
619 623
620 dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", 624 dev_dbg(&icd->dev, "Shutter width from %d to %lu\n",
621 reg_read(icd, MT9V022_TOTAL_SHUTTER_WIDTH), 625 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
622 shutter); 626 shutter);
623 if (reg_write(icd, MT9V022_TOTAL_SHUTTER_WIDTH, 627 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
624 shutter) < 0) 628 shutter) < 0)
625 return -EIO; 629 return -EIO;
626 icd->exposure = ctrl->value; 630 icd->exposure = ctrl->value;
@@ -628,17 +632,17 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
628 break; 632 break;
629 case V4L2_CID_AUTOGAIN: 633 case V4L2_CID_AUTOGAIN:
630 if (ctrl->value) 634 if (ctrl->value)
631 data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x2); 635 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
632 else 636 else
633 data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x2); 637 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
634 if (data < 0) 638 if (data < 0)
635 return -EIO; 639 return -EIO;
636 break; 640 break;
637 case V4L2_CID_EXPOSURE_AUTO: 641 case V4L2_CID_EXPOSURE_AUTO:
638 if (ctrl->value) 642 if (ctrl->value)
639 data = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x1); 643 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
640 else 644 else
641 data = reg_clear(icd, MT9V022_AEC_AGC_ENABLE, 0x1); 645 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
642 if (data < 0) 646 if (data < 0)
643 return -EIO; 647 return -EIO;
644 break; 648 break;
@@ -650,8 +654,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
650 * this wasn't our capture interface, so, we wait for the right one */ 654 * this wasn't our capture interface, so, we wait for the right one */
651static int mt9v022_video_probe(struct soc_camera_device *icd) 655static int mt9v022_video_probe(struct soc_camera_device *icd)
652{ 656{
657 struct i2c_client *client = to_i2c_client(icd->control);
653 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 658 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
654 struct soc_camera_link *icl = mt9v022->client->dev.platform_data; 659 struct soc_camera_link *icl = client->dev.platform_data;
655 s32 data; 660 s32 data;
656 int ret; 661 int ret;
657 unsigned long flags; 662 unsigned long flags;
@@ -661,7 +666,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
661 return -ENODEV; 666 return -ENODEV;
662 667
663 /* Read out the chip version register */ 668 /* Read out the chip version register */
664 data = reg_read(icd, MT9V022_CHIP_VERSION); 669 data = reg_read(client, MT9V022_CHIP_VERSION);
665 670
666 /* must be 0x1311 or 0x1313 */ 671 /* must be 0x1311 or 0x1313 */
667 if (data != 0x1311 && data != 0x1313) { 672 if (data != 0x1311 && data != 0x1313) {
@@ -672,12 +677,12 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
672 } 677 }
673 678
674 /* Soft reset */ 679 /* Soft reset */
675 ret = reg_write(icd, MT9V022_RESET, 1); 680 ret = reg_write(client, MT9V022_RESET, 1);
676 if (ret < 0) 681 if (ret < 0)
677 goto ei2c; 682 goto ei2c;
678 /* 15 clock cycles */ 683 /* 15 clock cycles */
679 udelay(200); 684 udelay(200);
680 if (reg_read(icd, MT9V022_RESET)) { 685 if (reg_read(client, MT9V022_RESET)) {
681 dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); 686 dev_err(&icd->dev, "Resetting MT9V022 failed!\n");
682 goto ei2c; 687 goto ei2c;
683 } 688 }
@@ -685,11 +690,11 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
685 /* Set monochrome or colour sensor type */ 690 /* Set monochrome or colour sensor type */
686 if (sensor_type && (!strcmp("colour", sensor_type) || 691 if (sensor_type && (!strcmp("colour", sensor_type) ||
687 !strcmp("color", sensor_type))) { 692 !strcmp("color", sensor_type))) {
688 ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); 693 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
689 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; 694 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
690 icd->formats = mt9v022_colour_formats; 695 icd->formats = mt9v022_colour_formats;
691 } else { 696 } else {
692 ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); 697 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
693 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; 698 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
694 icd->formats = mt9v022_monochrome_formats; 699 icd->formats = mt9v022_monochrome_formats;
695 } 700 }
@@ -735,10 +740,13 @@ ei2c:
735static void mt9v022_video_remove(struct soc_camera_device *icd) 740static void mt9v022_video_remove(struct soc_camera_device *icd)
736{ 741{
737 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 742 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
743 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
738 744
739 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, 745 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr,
740 icd->dev.parent, icd->vdev); 746 icd->dev.parent, icd->vdev);
741 soc_camera_video_stop(icd); 747 soc_camera_video_stop(icd);
748 if (icl->free_bus)
749 icl->free_bus(icl);
742} 750}
743 751
744static int mt9v022_probe(struct i2c_client *client, 752static int mt9v022_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 86fab56c5a20..2d075205bdfe 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -102,10 +102,10 @@ struct mx1_buffer {
102 * Interface. If anyone ever builds hardware to enable more than 102 * Interface. If anyone ever builds hardware to enable more than
103 * one camera, they will have to modify this driver too */ 103 * one camera, they will have to modify this driver too */
104struct mx1_camera_dev { 104struct mx1_camera_dev {
105 struct soc_camera_host soc_host;
105 struct soc_camera_device *icd; 106 struct soc_camera_device *icd;
106 struct mx1_camera_pdata *pdata; 107 struct mx1_camera_pdata *pdata;
107 struct mx1_buffer *active; 108 struct mx1_buffer *active;
108 struct device *dev;
109 struct resource *res; 109 struct resource *res;
110 struct clk *clk; 110 struct clk *clk;
111 struct list_head capture; 111 struct list_head capture;
@@ -219,7 +219,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
219 int ret; 219 int ret;
220 220
221 if (unlikely(!pcdev->active)) { 221 if (unlikely(!pcdev->active)) {
222 dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n"); 222 dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
223 return -EFAULT; 223 return -EFAULT;
224 } 224 }
225 225
@@ -229,7 +229,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
229 vbuf->size, pcdev->res->start + 229 vbuf->size, pcdev->res->start +
230 CSIRXR, DMA_MODE_READ); 230 CSIRXR, DMA_MODE_READ);
231 if (unlikely(ret)) 231 if (unlikely(ret))
232 dev_err(pcdev->dev, "Failed to setup DMA sg list\n"); 232 dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n");
233 233
234 return ret; 234 return ret;
235} 235}
@@ -338,14 +338,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
338 imx_dma_disable(channel); 338 imx_dma_disable(channel);
339 339
340 if (unlikely(!pcdev->active)) { 340 if (unlikely(!pcdev->active)) {
341 dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n"); 341 dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
342 goto out; 342 goto out;
343 } 343 }
344 344
345 vb = &pcdev->active->vb; 345 vb = &pcdev->active->vb;
346 buf = container_of(vb, struct mx1_buffer, vb); 346 buf = container_of(vb, struct mx1_buffer, vb);
347 WARN_ON(buf->inwork || list_empty(&vb->queue)); 347 WARN_ON(buf->inwork || list_empty(&vb->queue));
348 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 348 dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
349 vb, vb->baddr, vb->bsize); 349 vb, vb->baddr, vb->bsize);
350 350
351 mx1_camera_wakeup(pcdev, vb, buf); 351 mx1_camera_wakeup(pcdev, vb, buf);
@@ -366,7 +366,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
366 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 366 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
367 struct mx1_camera_dev *pcdev = ici->priv; 367 struct mx1_camera_dev *pcdev = ici->priv;
368 368
369 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev, 369 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev,
370 &pcdev->lock, 370 &pcdev->lock,
371 V4L2_BUF_TYPE_VIDEO_CAPTURE, 371 V4L2_BUF_TYPE_VIDEO_CAPTURE,
372 V4L2_FIELD_NONE, 372 V4L2_FIELD_NONE,
@@ -385,7 +385,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
385 * they get a nice Oops */ 385 * they get a nice Oops */
386 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; 386 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
387 387
388 dev_dbg(pcdev->dev, "System clock %lukHz, target freq %dkHz, " 388 dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, "
389 "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); 389 "divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
390 390
391 return div; 391 return div;
@@ -395,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
395{ 395{
396 unsigned int csicr1 = CSICR1_EN; 396 unsigned int csicr1 = CSICR1_EN;
397 397
398 dev_dbg(pcdev->dev, "Activate device\n"); 398 dev_dbg(pcdev->soc_host.dev, "Activate device\n");
399 399
400 clk_enable(pcdev->clk); 400 clk_enable(pcdev->clk);
401 401
@@ -411,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
411 411
412static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) 412static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
413{ 413{
414 dev_dbg(pcdev->dev, "Deactivate device\n"); 414 dev_dbg(pcdev->soc_host.dev, "Deactivate device\n");
415 415
416 /* Disable all CSI interface */ 416 /* Disable all CSI interface */
417 __raw_writel(0x00, pcdev->base + CSICR1); 417 __raw_writel(0x00, pcdev->base + CSICR1);
@@ -550,7 +550,7 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
550 550
551 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 551 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
552 if (!xlate) { 552 if (!xlate) {
553 dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); 553 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
554 return -EINVAL; 554 return -EINVAL;
555 } 555 }
556 556
@@ -633,12 +633,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
633 .querycap = mx1_camera_querycap, 633 .querycap = mx1_camera_querycap,
634}; 634};
635 635
636/* Should be allocated dynamically too, but we have only one. */
637static struct soc_camera_host mx1_soc_camera_host = {
638 .drv_name = DRIVER_NAME,
639 .ops = &mx1_soc_camera_host_ops,
640};
641
642static struct fiq_handler fh = { 636static struct fiq_handler fh = {
643 .name = "csi_sof" 637 .name = "csi_sof"
644}; 638};
@@ -673,7 +667,6 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
673 goto exit_put_clk; 667 goto exit_put_clk;
674 } 668 }
675 669
676 dev_set_drvdata(&pdev->dev, pcdev);
677 pcdev->res = res; 670 pcdev->res = res;
678 pcdev->clk = clk; 671 pcdev->clk = clk;
679 672
@@ -707,16 +700,15 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
707 } 700 }
708 pcdev->irq = irq; 701 pcdev->irq = irq;
709 pcdev->base = base; 702 pcdev->base = base;
710 pcdev->dev = &pdev->dev;
711 703
712 /* request dma */ 704 /* request dma */
713 pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); 705 pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
714 if (pcdev->dma_chan < 0) { 706 if (pcdev->dma_chan < 0) {
715 dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n"); 707 dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
716 err = -EBUSY; 708 err = -EBUSY;
717 goto exit_iounmap; 709 goto exit_iounmap;
718 } 710 }
719 dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan); 711 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
720 712
721 imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, 713 imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
722 pcdev); 714 pcdev);
@@ -729,7 +721,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
729 /* request irq */ 721 /* request irq */
730 err = claim_fiq(&fh); 722 err = claim_fiq(&fh);
731 if (err) { 723 if (err) {
732 dev_err(pcdev->dev, "Camera interrupt register failed \n"); 724 dev_err(&pdev->dev, "Camera interrupt register failed \n");
733 goto exit_free_dma; 725 goto exit_free_dma;
734 } 726 }
735 727
@@ -746,10 +738,12 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
746 mxc_set_irq_fiq(irq, 1); 738 mxc_set_irq_fiq(irq, 1);
747 enable_fiq(irq); 739 enable_fiq(irq);
748 740
749 mx1_soc_camera_host.priv = pcdev; 741 pcdev->soc_host.drv_name = DRIVER_NAME;
750 mx1_soc_camera_host.dev.parent = &pdev->dev; 742 pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
751 mx1_soc_camera_host.nr = pdev->id; 743 pcdev->soc_host.priv = pcdev;
752 err = soc_camera_host_register(&mx1_soc_camera_host); 744 pcdev->soc_host.dev = &pdev->dev;
745 pcdev->soc_host.nr = pdev->id;
746 err = soc_camera_host_register(&pcdev->soc_host);
753 if (err) 747 if (err)
754 goto exit_free_irq; 748 goto exit_free_irq;
755 749
@@ -777,7 +771,9 @@ exit:
777 771
778static int __exit mx1_camera_remove(struct platform_device *pdev) 772static int __exit mx1_camera_remove(struct platform_device *pdev)
779{ 773{
780 struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev); 774 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
775 struct mx1_camera_dev *pcdev = container_of(soc_host,
776 struct mx1_camera_dev, soc_host);
781 struct resource *res; 777 struct resource *res;
782 778
783 imx_dma_free(pcdev->dma_chan); 779 imx_dma_free(pcdev->dma_chan);
@@ -787,7 +783,7 @@ static int __exit mx1_camera_remove(struct platform_device *pdev)
787 783
788 clk_put(pcdev->clk); 784 clk_put(pcdev->clk);
789 785
790 soc_camera_host_unregister(&mx1_soc_camera_host); 786 soc_camera_host_unregister(soc_host);
791 787
792 iounmap(pcdev->base); 788 iounmap(pcdev->base);
793 789
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 2d0781118eb0..e605c076ed89 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -87,7 +87,6 @@ struct mx3_camera_buffer {
87 * @soc_host: embedded soc_host object 87 * @soc_host: embedded soc_host object
88 */ 88 */
89struct mx3_camera_dev { 89struct mx3_camera_dev {
90 struct device *dev;
91 /* 90 /*
92 * i.MX3x is only supposed to handle one camera on its Camera Sensor 91 * i.MX3x is only supposed to handle one camera on its Camera Sensor
93 * Interface. If anyone ever builds hardware to enable more than one 92 * Interface. If anyone ever builds hardware to enable more than one
@@ -431,7 +430,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
431 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 430 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
432 struct mx3_camera_dev *mx3_cam = ici->priv; 431 struct mx3_camera_dev *mx3_cam = ici->priv;
433 432
434 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev, 433 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev,
435 &mx3_cam->lock, 434 &mx3_cam->lock,
436 V4L2_BUF_TYPE_VIDEO_CAPTURE, 435 V4L2_BUF_TYPE_VIDEO_CAPTURE,
437 V4L2_FIELD_NONE, 436 V4L2_FIELD_NONE,
@@ -599,7 +598,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
599 *flags |= SOCAM_DATAWIDTH_4; 598 *flags |= SOCAM_DATAWIDTH_4;
600 break; 599 break;
601 default: 600 default:
602 dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth); 601 dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n",
602 buswidth);
603 return -EINVAL; 603 return -EINVAL;
604 } 604 }
605 605
@@ -614,7 +614,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
614 unsigned long bus_flags, camera_flags; 614 unsigned long bus_flags, camera_flags;
615 int ret = test_platform_param(mx3_cam, depth, &bus_flags); 615 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
616 616
617 dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret); 617 dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret);
618 618
619 if (ret < 0) 619 if (ret < 0)
620 return ret; 620 return ret;
@@ -637,7 +637,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
637 if (!rq) 637 if (!rq)
638 return false; 638 return false;
639 639
640 pdata = rq->mx3_cam->dev->platform_data; 640 pdata = rq->mx3_cam->soc_host.dev->platform_data;
641 641
642 return rq->id == chan->chan_id && 642 return rq->id == chan->chan_id &&
643 pdata->dma_dev == chan->device->dev; 643 pdata->dma_dev == chan->device->dev;
@@ -697,7 +697,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
697 xlate->cam_fmt = icd->formats + idx; 697 xlate->cam_fmt = icd->formats + idx;
698 xlate->buswidth = buswidth; 698 xlate->buswidth = buswidth;
699 xlate++; 699 xlate++;
700 dev_dbg(&ici->dev, "Providing format %s using %s\n", 700 dev_dbg(ici->dev, "Providing format %s using %s\n",
701 mx3_camera_formats[0].name, 701 mx3_camera_formats[0].name,
702 icd->formats[idx].name); 702 icd->formats[idx].name);
703 } 703 }
@@ -709,7 +709,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
709 xlate->cam_fmt = icd->formats + idx; 709 xlate->cam_fmt = icd->formats + idx;
710 xlate->buswidth = buswidth; 710 xlate->buswidth = buswidth;
711 xlate++; 711 xlate++;
712 dev_dbg(&ici->dev, "Providing format %s using %s\n", 712 dev_dbg(ici->dev, "Providing format %s using %s\n",
713 mx3_camera_formats[0].name, 713 mx3_camera_formats[0].name,
714 icd->formats[idx].name); 714 icd->formats[idx].name);
715 } 715 }
@@ -722,7 +722,7 @@ passthrough:
722 xlate->cam_fmt = icd->formats + idx; 722 xlate->cam_fmt = icd->formats + idx;
723 xlate->buswidth = buswidth; 723 xlate->buswidth = buswidth;
724 xlate++; 724 xlate++;
725 dev_dbg(&ici->dev, 725 dev_dbg(ici->dev,
726 "Providing format %s in pass-through mode\n", 726 "Providing format %s in pass-through mode\n",
727 icd->formats[idx].name); 727 icd->formats[idx].name);
728 } 728 }
@@ -829,7 +829,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
829 829
830 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 830 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
831 if (!xlate) { 831 if (!xlate) {
832 dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); 832 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
833 return -EINVAL; 833 return -EINVAL;
834 } 834 }
835 835
@@ -866,7 +866,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
866 866
867 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 867 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
868 if (pixfmt && !xlate) { 868 if (pixfmt && !xlate) {
869 dev_warn(&ici->dev, "Format %x not found\n", pixfmt); 869 dev_warn(ici->dev, "Format %x not found\n", pixfmt);
870 return -EINVAL; 870 return -EINVAL;
871 } 871 }
872 872
@@ -933,11 +933,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
933 933
934 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 934 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
935 if (!xlate) { 935 if (!xlate) {
936 dev_warn(&ici->dev, "Format %x not found\n", pixfmt); 936 dev_warn(ici->dev, "Format %x not found\n", pixfmt);
937 return -EINVAL; 937 return -EINVAL;
938 } 938 }
939 939
940 dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", 940 dev_dbg(ici->dev, "requested bus width %d bit: %d\n",
941 icd->buswidth, ret); 941 icd->buswidth, ret);
942 942
943 if (ret < 0) 943 if (ret < 0)
@@ -947,7 +947,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
947 947
948 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 948 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
949 if (!common_flags) { 949 if (!common_flags) {
950 dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n", 950 dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n",
951 camera_flags, bus_flags); 951 camera_flags, bus_flags);
952 return -EINVAL; 952 return -EINVAL;
953 } 953 }
@@ -1054,7 +1054,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1054 1054
1055 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); 1055 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
1056 1056
1057 dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); 1057 dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
1058 1058
1059 return 0; 1059 return 0;
1060} 1060}
@@ -1074,7 +1074,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
1074 .set_bus_param = mx3_camera_set_bus_param, 1074 .set_bus_param = mx3_camera_set_bus_param,
1075}; 1075};
1076 1076
1077static int mx3_camera_probe(struct platform_device *pdev) 1077static int __devinit mx3_camera_probe(struct platform_device *pdev)
1078{ 1078{
1079 struct mx3_camera_dev *mx3_cam; 1079 struct mx3_camera_dev *mx3_cam;
1080 struct resource *res; 1080 struct resource *res;
@@ -1102,8 +1102,6 @@ static int mx3_camera_probe(struct platform_device *pdev)
1102 goto eclkget; 1102 goto eclkget;
1103 } 1103 }
1104 1104
1105 dev_set_drvdata(&pdev->dev, mx3_cam);
1106
1107 mx3_cam->pdata = pdev->dev.platform_data; 1105 mx3_cam->pdata = pdev->dev.platform_data;
1108 mx3_cam->platform_flags = mx3_cam->pdata->flags; 1106 mx3_cam->platform_flags = mx3_cam->pdata->flags;
1109 if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | 1107 if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
@@ -1135,14 +1133,14 @@ static int mx3_camera_probe(struct platform_device *pdev)
1135 } 1133 }
1136 1134
1137 mx3_cam->base = base; 1135 mx3_cam->base = base;
1138 mx3_cam->dev = &pdev->dev;
1139 1136
1140 soc_host = &mx3_cam->soc_host; 1137 soc_host = &mx3_cam->soc_host;
1141 soc_host->drv_name = MX3_CAM_DRV_NAME; 1138 soc_host->drv_name = MX3_CAM_DRV_NAME;
1142 soc_host->ops = &mx3_soc_camera_host_ops; 1139 soc_host->ops = &mx3_soc_camera_host_ops;
1143 soc_host->priv = mx3_cam; 1140 soc_host->priv = mx3_cam;
1144 soc_host->dev.parent = &pdev->dev; 1141 soc_host->dev = &pdev->dev;
1145 soc_host->nr = pdev->id; 1142 soc_host->nr = pdev->id;
1143
1146 err = soc_camera_host_register(soc_host); 1144 err = soc_camera_host_register(soc_host);
1147 if (err) 1145 if (err)
1148 goto ecamhostreg; 1146 goto ecamhostreg;
@@ -1165,11 +1163,13 @@ egetres:
1165 1163
1166static int __devexit mx3_camera_remove(struct platform_device *pdev) 1164static int __devexit mx3_camera_remove(struct platform_device *pdev)
1167{ 1165{
1168 struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev); 1166 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1167 struct mx3_camera_dev *mx3_cam = container_of(soc_host,
1168 struct mx3_camera_dev, soc_host);
1169 1169
1170 clk_put(mx3_cam->clk); 1170 clk_put(mx3_cam->clk);
1171 1171
1172 soc_camera_host_unregister(&mx3_cam->soc_host); 1172 soc_camera_host_unregister(soc_host);
1173 1173
1174 iounmap(mx3_cam->base); 1174 iounmap(mx3_cam->base);
1175 1175
@@ -1194,11 +1194,11 @@ static struct platform_driver mx3_camera_driver = {
1194 .name = MX3_CAM_DRV_NAME, 1194 .name = MX3_CAM_DRV_NAME,
1195 }, 1195 },
1196 .probe = mx3_camera_probe, 1196 .probe = mx3_camera_probe,
1197 .remove = __exit_p(mx3_camera_remove), 1197 .remove = __devexit_p(mx3_camera_remove),
1198}; 1198};
1199 1199
1200 1200
1201static int __devinit mx3_camera_init(void) 1201static int __init mx3_camera_init(void)
1202{ 1202{
1203 return platform_driver_register(&mx3_camera_driver); 1203 return platform_driver_register(&mx3_camera_driver);
1204} 1204}
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 3be5a71bdac2..35890e8b2431 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -453,7 +453,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
453static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) 453static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
454{ 454{
455 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); 455 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
456 if (i->index < 0 || i->index >= MXB_INPUTS) 456 if (i->index >= MXB_INPUTS)
457 return -EINVAL; 457 return -EINVAL;
458 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); 458 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
459 return 0; 459 return 0;
@@ -616,7 +616,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
616 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 616 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
617 struct mxb *mxb = (struct mxb *)dev->ext_priv; 617 struct mxb *mxb = (struct mxb *)dev->ext_priv;
618 618
619 if (a->index < 0 || a->index > MXB_INPUTS) { 619 if (a->index > MXB_INPUTS) {
620 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); 620 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
621 return -EINVAL; 621 return -EINVAL;
622 } 622 }
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 9af5532db142..08cfd3e4ae8a 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -112,6 +112,8 @@ static int framedrop = -1;
112static int fastset; 112static int fastset;
113static int force_palette; 113static int force_palette;
114static int backlight; 114static int backlight;
115/* Bitmask marking allocated devices from 0 to OV511_MAX_UNIT_VIDEO */
116static unsigned long ov511_devused;
115static int unit_video[OV511_MAX_UNIT_VIDEO]; 117static int unit_video[OV511_MAX_UNIT_VIDEO];
116static int remove_zeros; 118static int remove_zeros;
117static int mirror; 119static int mirror;
@@ -5720,7 +5722,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
5720 struct usb_device *dev = interface_to_usbdev(intf); 5722 struct usb_device *dev = interface_to_usbdev(intf);
5721 struct usb_interface_descriptor *idesc; 5723 struct usb_interface_descriptor *idesc;
5722 struct usb_ov511 *ov; 5724 struct usb_ov511 *ov;
5723 int i; 5725 int i, rc, nr;
5724 5726
5725 PDEBUG(1, "probing for device..."); 5727 PDEBUG(1, "probing for device...");
5726 5728
@@ -5845,33 +5847,41 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
5845 ov->vdev->parent = &intf->dev; 5847 ov->vdev->parent = &intf->dev;
5846 video_set_drvdata(ov->vdev, ov); 5848 video_set_drvdata(ov->vdev, ov);
5847 5849
5848 for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { 5850 mutex_lock(&ov->lock);
5849 /* Minor 0 cannot be specified; assume user wants autodetect */
5850 if (unit_video[i] == 0)
5851 break;
5852 5851
5853 if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, 5852 /* Check to see next free device and mark as used */
5854 unit_video[i]) >= 0) { 5853 nr = find_first_zero_bit(&ov511_devused, OV511_MAX_UNIT_VIDEO);
5855 break; 5854
5856 } 5855 /* Registers device */
5857 } 5856 if (unit_video[nr] != 0)
5857 rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER,
5858 unit_video[nr]);
5859 else
5860 rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1);
5858 5861
5859 /* Use the next available one */ 5862 if (rc < 0) {
5860 if ((ov->vdev->minor == -1) &&
5861 video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
5862 err("video_register_device failed"); 5863 err("video_register_device failed");
5864 mutex_unlock(&ov->lock);
5863 goto error; 5865 goto error;
5864 } 5866 }
5865 5867
5868 /* Mark device as used */
5869 ov511_devused |= 1 << nr;
5870 ov->nr = nr;
5871
5866 dev_info(&intf->dev, "Device at %s registered to minor %d\n", 5872 dev_info(&intf->dev, "Device at %s registered to minor %d\n",
5867 ov->usb_path, ov->vdev->minor); 5873 ov->usb_path, ov->vdev->minor);
5868 5874
5869 usb_set_intfdata(intf, ov); 5875 usb_set_intfdata(intf, ov);
5870 if (ov_create_sysfs(ov->vdev)) { 5876 if (ov_create_sysfs(ov->vdev)) {
5871 err("ov_create_sysfs failed"); 5877 err("ov_create_sysfs failed");
5878 ov511_devused &= ~(1 << nr);
5879 mutex_unlock(&ov->lock);
5872 goto error; 5880 goto error;
5873 } 5881 }
5874 5882
5883 mutex_lock(&ov->lock);
5884
5875 return 0; 5885 return 0;
5876 5886
5877error: 5887error:
@@ -5906,10 +5916,16 @@ ov51x_disconnect(struct usb_interface *intf)
5906 5916
5907 PDEBUG(3, ""); 5917 PDEBUG(3, "");
5908 5918
5919 mutex_lock(&ov->lock);
5909 usb_set_intfdata (intf, NULL); 5920 usb_set_intfdata (intf, NULL);
5910 5921
5911 if (!ov) 5922 if (!ov) {
5923 mutex_unlock(&ov->lock);
5912 return; 5924 return;
5925 }
5926
5927 /* Free device number */
5928 ov511_devused &= ~(1 << ov->nr);
5913 5929
5914 if (ov->vdev) 5930 if (ov->vdev)
5915 video_unregister_device(ov->vdev); 5931 video_unregister_device(ov->vdev);
@@ -5927,6 +5943,7 @@ ov51x_disconnect(struct usb_interface *intf)
5927 5943
5928 ov->streaming = 0; 5944 ov->streaming = 0;
5929 ov51x_unlink_isoc(ov); 5945 ov51x_unlink_isoc(ov);
5946 mutex_unlock(&ov->lock);
5930 5947
5931 ov->dev = NULL; 5948 ov->dev = NULL;
5932 5949
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 70d99e52329d..c450c92468da 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -494,6 +494,9 @@ struct usb_ov511 {
494 int has_decoder; /* Device has a video decoder */ 494 int has_decoder; /* Device has a video decoder */
495 int pal; /* Device is designed for PAL resolution */ 495 int pal; /* Device is designed for PAL resolution */
496 496
497 /* ov511 device number ID */
498 int nr; /* Stores a device number */
499
497 /* I2C interface */ 500 /* I2C interface */
498 struct mutex i2c_lock; /* Protect I2C controller regs */ 501 struct mutex i2c_lock; /* Protect I2C controller regs */
499 unsigned char primary_i2c_slave; /* I2C write id of sensor */ 502 unsigned char primary_i2c_slave; /* I2C write id of sensor */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 1cb6a260e8b0..336a20eded0f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -71,6 +71,7 @@ static const struct pvr2_device_desc pvr2_device_29xxx = {
71 .flag_has_svideo = !0, 71 .flag_has_svideo = !0,
72 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 72 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
73 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, 73 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
74 .ir_scheme = PVR2_IR_SCHEME_29XXX,
74}; 75};
75 76
76 77
@@ -284,6 +285,11 @@ static struct tda10048_config hauppauge_tda10048_config = {
284 .output_mode = TDA10048_PARALLEL_OUTPUT, 285 .output_mode = TDA10048_PARALLEL_OUTPUT,
285 .fwbulkwritelen = TDA10048_BULKWRITE_50, 286 .fwbulkwritelen = TDA10048_BULKWRITE_50,
286 .inversion = TDA10048_INVERSION_ON, 287 .inversion = TDA10048_INVERSION_ON,
288 .dtv6_if_freq_khz = TDA10048_IF_3300,
289 .dtv7_if_freq_khz = TDA10048_IF_3800,
290 .dtv8_if_freq_khz = TDA10048_IF_4300,
291 .clk_freq_khz = TDA10048_CLK_16000,
292 .disable_gate_access = 1,
287}; 293};
288 294
289static struct tda829x_config tda829x_no_probe = { 295static struct tda829x_config tda829x_no_probe = {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index 3e553389cbc3..ea04ecf8aa39 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -69,6 +69,7 @@ struct pvr2_string_table {
69#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 69#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
70#define PVR2_ROUTING_SCHEME_GOTVIEW 1 70#define PVR2_ROUTING_SCHEME_GOTVIEW 1
71#define PVR2_ROUTING_SCHEME_ONAIR 2 71#define PVR2_ROUTING_SCHEME_ONAIR 2
72#define PVR2_ROUTING_SCHEME_AV400 3
72 73
73#define PVR2_DIGITAL_SCHEME_NONE 0 74#define PVR2_DIGITAL_SCHEME_NONE 0
74#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 75#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
@@ -78,8 +79,10 @@ struct pvr2_string_table {
78#define PVR2_LED_SCHEME_HAUPPAUGE 1 79#define PVR2_LED_SCHEME_HAUPPAUGE 1
79 80
80#define PVR2_IR_SCHEME_NONE 0 81#define PVR2_IR_SCHEME_NONE 0
81#define PVR2_IR_SCHEME_24XXX 1 82#define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */
82#define PVR2_IR_SCHEME_ZILOG 2 83#define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */
84#define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */
85#define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */
83 86
84/* This describes a particular hardware type (except for the USB device ID 87/* This describes a particular hardware type (except for the USB device ID
85 which must live in a separate structure due to environmental 88 which must live in a separate structure due to environmental
@@ -162,19 +165,9 @@ struct pvr2_device_desc {
162 ensure that it is found. */ 165 ensure that it is found. */
163 unsigned int flag_has_wm8775:1; 166 unsigned int flag_has_wm8775:1;
164 167
165 /* Indicate any specialized IR scheme that might need to be 168 /* Indicate IR scheme of hardware. If not set, then it is assumed
166 supported by this driver. If not set, then it is assumed that 169 that IR can work without any help from the driver. */
167 IR can work without help from the driver (which is frequently 170 unsigned int ir_scheme:3;
168 the case). This is otherwise set to one of
169 PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a
170 Hauppauge 24xxx class device which has an FPGA-hosted IR
171 receiver that can only be reached via FX2 command codes. In
172 that case the pvrusb2 driver will emulate the behavior of the
173 older 29xxx device's IR receiver (a "virtual" I2C chip) in terms
174 of those command codes. For the value "ZILOG", we're dealing
175 with an IR chip that must be taken out of reset via another FX2
176 command code (which is the case for HVR-1950 devices). */
177 unsigned int ir_scheme:2;
178 171
179 /* These bits define which kinds of sources the device can handle. 172 /* These bits define which kinds of sources the device can handle.
180 Note: Digital tuner presence is inferred by the 173 Note: Digital tuner presence is inferred by the
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 5d75eb5211b1..5b152ff20bd0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -200,6 +200,9 @@ struct pvr2_hdw {
200 int i2c_cx25840_hack_state; 200 int i2c_cx25840_hack_state;
201 int i2c_linked; 201 int i2c_linked;
202 202
203 /* IR related */
204 unsigned int ir_scheme_active; /* IR scheme as seen from the outside */
205
203 /* Frequency table */ 206 /* Frequency table */
204 unsigned int freqTable[FREQTABLE_SIZE]; 207 unsigned int freqTable[FREQTABLE_SIZE];
205 unsigned int freqProgSlot; 208 unsigned int freqProgSlot;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index add3395d3248..0c745b142fb7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -142,6 +142,15 @@ static const unsigned char *module_i2c_addresses[] = {
142}; 142};
143 143
144 144
145static const char *ir_scheme_names[] = {
146 [PVR2_IR_SCHEME_NONE] = "none",
147 [PVR2_IR_SCHEME_29XXX] = "29xxx",
148 [PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)",
149 [PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)",
150 [PVR2_IR_SCHEME_ZILOG] = "Zilog",
151};
152
153
145/* Define the list of additional controls we'll dynamically construct based 154/* Define the list of additional controls we'll dynamically construct based
146 on query of the cx2341x module. */ 155 on query of the cx2341x module. */
147struct pvr2_mpeg_ids { 156struct pvr2_mpeg_ids {
@@ -2170,7 +2179,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
2170 } 2179 }
2171 2180
2172 /* Take the IR chip out of reset, if appropriate */ 2181 /* Take the IR chip out of reset, if appropriate */
2173 if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) { 2182 if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) {
2174 pvr2_issue_simple_cmd(hdw, 2183 pvr2_issue_simple_cmd(hdw,
2175 FX2CMD_HCW_ZILOG_RESET | 2184 FX2CMD_HCW_ZILOG_RESET |
2176 (1 << 8) | 2185 (1 << 8) |
@@ -2451,6 +2460,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2451 GFP_KERNEL); 2460 GFP_KERNEL);
2452 if (!hdw->controls) goto fail; 2461 if (!hdw->controls) goto fail;
2453 hdw->hdw_desc = hdw_desc; 2462 hdw->hdw_desc = hdw_desc;
2463 hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme;
2454 for (idx = 0; idx < hdw->control_cnt; idx++) { 2464 for (idx = 0; idx < hdw->control_cnt; idx++) {
2455 cptr = hdw->controls + idx; 2465 cptr = hdw->controls + idx;
2456 cptr->hdw = hdw; 2466 cptr->hdw = hdw;
@@ -4809,6 +4819,12 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
4809 stats.buffers_processed, 4819 stats.buffers_processed,
4810 stats.buffers_failed); 4820 stats.buffers_failed);
4811 } 4821 }
4822 case 6: {
4823 unsigned int id = hdw->ir_scheme_active;
4824 return scnprintf(buf, acnt, "ir scheme: id=%d %s", id,
4825 (id >= ARRAY_SIZE(ir_scheme_names) ?
4826 "?" : ir_scheme_names[id]));
4827 }
4812 default: break; 4828 default: break;
4813 } 4829 }
4814 return 0; 4830 return 0;
@@ -4825,65 +4841,35 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
4825 unsigned int tcnt = 0; 4841 unsigned int tcnt = 0;
4826 unsigned int ccnt; 4842 unsigned int ccnt;
4827 struct i2c_client *client; 4843 struct i2c_client *client;
4828 struct list_head *item;
4829 void *cd;
4830 const char *p; 4844 const char *p;
4831 unsigned int id; 4845 unsigned int id;
4832 4846
4833 ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:"); 4847 ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n");
4834 tcnt += ccnt; 4848 tcnt += ccnt;
4835 v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { 4849 v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
4836 id = sd->grp_id; 4850 id = sd->grp_id;
4837 p = NULL; 4851 p = NULL;
4838 if (id < ARRAY_SIZE(module_names)) p = module_names[id]; 4852 if (id < ARRAY_SIZE(module_names)) p = module_names[id];
4839 if (p) { 4853 if (p) {
4840 ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p); 4854 ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s:", p);
4841 tcnt += ccnt; 4855 tcnt += ccnt;
4842 } else { 4856 } else {
4843 ccnt = scnprintf(buf + tcnt, acnt - tcnt, 4857 ccnt = scnprintf(buf + tcnt, acnt - tcnt,
4844 " (unknown id=%u)", id); 4858 " (unknown id=%u):", id);
4845 tcnt += ccnt; 4859 tcnt += ccnt;
4846 } 4860 }
4847 } 4861 client = v4l2_get_subdevdata(sd);
4848 ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); 4862 if (client) {
4849 tcnt += ccnt; 4863 ccnt = scnprintf(buf + tcnt, acnt - tcnt,
4850 4864 " %s @ %02x\n", client->name,
4851 ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n"); 4865 client->addr);
4852 tcnt += ccnt; 4866 tcnt += ccnt;
4853 4867 } else {
4854 mutex_lock(&hdw->i2c_adap.clist_lock); 4868 ccnt = scnprintf(buf + tcnt, acnt - tcnt,
4855 list_for_each(item, &hdw->i2c_adap.clients) { 4869 " no i2c client\n");
4856 client = list_entry(item, struct i2c_client, list); 4870 tcnt += ccnt;
4857 ccnt = scnprintf(buf + tcnt, acnt - tcnt,
4858 " %s: i2c=%02x", client->name, client->addr);
4859 tcnt += ccnt;
4860 cd = i2c_get_clientdata(client);
4861 v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
4862 if (cd == sd) {
4863 id = sd->grp_id;
4864 p = NULL;
4865 if (id < ARRAY_SIZE(module_names)) {
4866 p = module_names[id];
4867 }
4868 if (p) {
4869 ccnt = scnprintf(buf + tcnt,
4870 acnt - tcnt,
4871 " subdev=%s", p);
4872 tcnt += ccnt;
4873 } else {
4874 ccnt = scnprintf(buf + tcnt,
4875 acnt - tcnt,
4876 " subdev= id %u)",
4877 id);
4878 tcnt += ccnt;
4879 }
4880 break;
4881 }
4882 } 4871 }
4883 ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
4884 tcnt += ccnt;
4885 } 4872 }
4886 mutex_unlock(&hdw->i2c_adap.clist_lock);
4887 return tcnt; 4873 return tcnt;
4888} 4874}
4889 4875
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 9af282f9e765..610bd848df24 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -42,6 +42,18 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
42module_param_array(ir_mode, int, NULL, 0444); 42module_param_array(ir_mode, int, NULL, 0444);
43MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); 43MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
44 44
45static int pvr2_disable_ir_video;
46module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
47 int, S_IRUGO|S_IWUSR);
48MODULE_PARM_DESC(disable_autoload_ir_video,
49 "1=do not try to autoload ir_video IR receiver");
50
51/* Mapping of IR schemes to known I2C addresses - if any */
52static const unsigned char ir_video_addresses[] = {
53 [PVR2_IR_SCHEME_29XXX] = 0x18,
54 [PVR2_IR_SCHEME_24XXX] = 0x18,
55};
56
45static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ 57static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
46 u8 i2c_addr, /* I2C address we're talking to */ 58 u8 i2c_addr, /* I2C address we're talking to */
47 u8 *data, /* Data to write */ 59 u8 *data, /* Data to write */
@@ -559,6 +571,31 @@ static void do_i2c_scan(struct pvr2_hdw *hdw)
559 printk(KERN_INFO "%s: i2c scan done.\n", hdw->name); 571 printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
560} 572}
561 573
574static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
575{
576 struct i2c_board_info info;
577 unsigned char addr = 0;
578 if (pvr2_disable_ir_video) {
579 pvr2_trace(PVR2_TRACE_INFO,
580 "Automatic binding of ir_video has been disabled.");
581 return;
582 }
583 if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) {
584 addr = ir_video_addresses[hdw->ir_scheme_active];
585 }
586 if (!addr) {
587 /* The device either doesn't support I2C-based IR or we
588 don't know (yet) how to operate IR on the device. */
589 return;
590 }
591 pvr2_trace(PVR2_TRACE_INFO,
592 "Binding ir_video to i2c address 0x%02x.", addr);
593 memset(&info, 0, sizeof(struct i2c_board_info));
594 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
595 info.addr = addr;
596 i2c_new_device(&hdw->i2c_adap, &info);
597}
598
562void pvr2_i2c_core_init(struct pvr2_hdw *hdw) 599void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
563{ 600{
564 unsigned int idx; 601 unsigned int idx;
@@ -574,7 +611,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
574 printk(KERN_INFO "%s: IR disabled\n",hdw->name); 611 printk(KERN_INFO "%s: IR disabled\n",hdw->name);
575 hdw->i2c_func[0x18] = i2c_black_hole; 612 hdw->i2c_func[0x18] = i2c_black_hole;
576 } else if (ir_mode[hdw->unit_number] == 1) { 613 } else if (ir_mode[hdw->unit_number] == 1) {
577 if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { 614 if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
615 /* Set up translation so that our IR looks like a
616 29xxx device */
578 hdw->i2c_func[0x18] = i2c_24xxx_ir; 617 hdw->i2c_func[0x18] = i2c_24xxx_ir;
579 } 618 }
580 } 619 }
@@ -597,15 +636,23 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
597 i2c_add_adapter(&hdw->i2c_adap); 636 i2c_add_adapter(&hdw->i2c_adap);
598 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { 637 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
599 /* Probe for a different type of IR receiver on this 638 /* Probe for a different type of IR receiver on this
600 device. If present, disable the emulated IR receiver. */ 639 device. This is really the only way to differentiate
640 older 24xxx devices from 24xxx variants that include an
641 IR blaster. If the IR blaster is present, the IR
642 receiver is part of that chip and thus we must disable
643 the emulated IR receiver. */
601 if (do_i2c_probe(hdw, 0x71)) { 644 if (do_i2c_probe(hdw, 0x71)) {
602 pvr2_trace(PVR2_TRACE_INFO, 645 pvr2_trace(PVR2_TRACE_INFO,
603 "Device has newer IR hardware;" 646 "Device has newer IR hardware;"
604 " disabling unneeded virtual IR device"); 647 " disabling unneeded virtual IR device");
605 hdw->i2c_func[0x18] = NULL; 648 hdw->i2c_func[0x18] = NULL;
649 /* Remember that this is a different device... */
650 hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE;
606 } 651 }
607 } 652 }
608 if (i2c_scan) do_i2c_scan(hdw); 653 if (i2c_scan) do_i2c_scan(hdw);
654
655 pvr2_i2c_register_ir(hdw);
609} 656}
610 657
611void pvr2_i2c_core_done(struct pvr2_hdw *hdw) 658void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 9e0f2b07b93b..2d8825e5b1be 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -90,7 +90,7 @@ static struct v4l2_capability pvr_capability ={
90 .driver = "pvrusb2", 90 .driver = "pvrusb2",
91 .card = "Hauppauge WinTV pvr-usb2", 91 .card = "Hauppauge WinTV pvr-usb2",
92 .bus_info = "usb", 92 .bus_info = "usb",
93 .version = KERNEL_VERSION(0,8,0), 93 .version = KERNEL_VERSION(0, 9, 0),
94 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | 94 .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
95 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | 95 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
96 V4L2_CAP_READWRITE), 96 V4L2_CAP_READWRITE),
@@ -267,7 +267,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
267 memset(&tmp,0,sizeof(tmp)); 267 memset(&tmp,0,sizeof(tmp));
268 tmp.index = vi->index; 268 tmp.index = vi->index;
269 ret = 0; 269 ret = 0;
270 if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { 270 if (vi->index >= fh->input_cnt) {
271 ret = -EINVAL; 271 ret = -EINVAL;
272 break; 272 break;
273 } 273 }
@@ -331,7 +331,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
331 case VIDIOC_S_INPUT: 331 case VIDIOC_S_INPUT:
332 { 332 {
333 struct v4l2_input *vi = (struct v4l2_input *)arg; 333 struct v4l2_input *vi = (struct v4l2_input *)arg;
334 if ((vi->index < 0) || (vi->index >= fh->input_cnt)) { 334 if (vi->index >= fh->input_cnt) {
335 ret = -ERANGE; 335 ret = -ERANGE;
336 break; 336 break;
337 } 337 }
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 7c542caf248e..db25c3034c11 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -601,7 +601,7 @@ static void pwc_snapshot_button(struct pwc_device *pdev, int down)
601 601
602#ifdef CONFIG_USB_PWC_INPUT_EVDEV 602#ifdef CONFIG_USB_PWC_INPUT_EVDEV
603 if (pdev->button_dev) { 603 if (pdev->button_dev) {
604 input_report_key(pdev->button_dev, BTN_0, down); 604 input_report_key(pdev->button_dev, KEY_CAMERA, down);
605 input_sync(pdev->button_dev); 605 input_sync(pdev->button_dev);
606 } 606 }
607#endif 607#endif
@@ -1783,7 +1783,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1783 return -ENOMEM; 1783 return -ENOMEM;
1784 } 1784 }
1785 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); 1785 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1786 pdev->vdev->parent = &(udev->dev); 1786 pdev->vdev->parent = &intf->dev;
1787 strcpy(pdev->vdev->name, name); 1787 strcpy(pdev->vdev->name, name);
1788 video_set_drvdata(pdev->vdev, pdev); 1788 video_set_drvdata(pdev->vdev, pdev);
1789 1789
@@ -1847,7 +1847,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1847 usb_to_input_id(pdev->udev, &pdev->button_dev->id); 1847 usb_to_input_id(pdev->udev, &pdev->button_dev->id);
1848 pdev->button_dev->dev.parent = &pdev->udev->dev; 1848 pdev->button_dev->dev.parent = &pdev->udev->dev;
1849 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); 1849 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
1850 pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); 1850 pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
1851 1851
1852 rc = input_register_device(pdev->button_dev); 1852 rc = input_register_device(pdev->button_dev);
1853 if (rc) { 1853 if (rc) {
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index bc0a464295c5..2876ce084510 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1107,7 +1107,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1107 return -EINVAL; 1107 return -EINVAL;
1108 if (buf->memory != V4L2_MEMORY_MMAP) 1108 if (buf->memory != V4L2_MEMORY_MMAP)
1109 return -EINVAL; 1109 return -EINVAL;
1110 if (buf->index < 0 || buf->index >= pwc_mbufs) 1110 if (buf->index >= pwc_mbufs)
1111 return -EINVAL; 1111 return -EINVAL;
1112 1112
1113 buf->flags |= V4L2_BUF_FLAG_QUEUED; 1113 buf->flags |= V4L2_BUF_FLAG_QUEUED;
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c639845460ff..f60de40fd21f 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -202,7 +202,7 @@ struct pxa_buffer {
202}; 202};
203 203
204struct pxa_camera_dev { 204struct pxa_camera_dev {
205 struct device *dev; 205 struct soc_camera_host soc_host;
206 /* PXA27x is only supposed to handle one camera on its Quick Capture 206 /* PXA27x is only supposed to handle one camera on its Quick Capture
207 * interface. If anyone ever builds hardware to enable more than 207 * interface. If anyone ever builds hardware to enable more than
208 * one camera, they will have to modify this driver too */ 208 * one camera, they will have to modify this driver too */
@@ -261,7 +261,6 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
261{ 261{
262 struct soc_camera_device *icd = vq->priv_data; 262 struct soc_camera_device *icd = vq->priv_data;
263 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 263 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
264 struct pxa_camera_dev *pcdev = ici->priv;
265 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 264 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
266 int i; 265 int i;
267 266
@@ -278,7 +277,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
278 277
279 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { 278 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
280 if (buf->dmas[i].sg_cpu) 279 if (buf->dmas[i].sg_cpu)
281 dma_free_coherent(pcdev->dev, buf->dmas[i].sg_size, 280 dma_free_coherent(ici->dev, buf->dmas[i].sg_size,
282 buf->dmas[i].sg_cpu, 281 buf->dmas[i].sg_cpu,
283 buf->dmas[i].sg_dma); 282 buf->dmas[i].sg_dma);
284 buf->dmas[i].sg_cpu = NULL; 283 buf->dmas[i].sg_cpu = NULL;
@@ -338,14 +337,14 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
338 int dma_len = 0, xfer_len = 0; 337 int dma_len = 0, xfer_len = 0;
339 338
340 if (pxa_dma->sg_cpu) 339 if (pxa_dma->sg_cpu)
341 dma_free_coherent(pcdev->dev, pxa_dma->sg_size, 340 dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
342 pxa_dma->sg_cpu, pxa_dma->sg_dma); 341 pxa_dma->sg_cpu, pxa_dma->sg_dma);
343 342
344 sglen = calculate_dma_sglen(*sg_first, dma->sglen, 343 sglen = calculate_dma_sglen(*sg_first, dma->sglen,
345 *sg_first_ofs, size); 344 *sg_first_ofs, size);
346 345
347 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); 346 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
348 pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size, 347 pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
349 &pxa_dma->sg_dma, GFP_KERNEL); 348 &pxa_dma->sg_dma, GFP_KERNEL);
350 if (!pxa_dma->sg_cpu) 349 if (!pxa_dma->sg_cpu)
351 return -ENOMEM; 350 return -ENOMEM;
@@ -353,7 +352,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
353 pxa_dma->sglen = sglen; 352 pxa_dma->sglen = sglen;
354 offset = *sg_first_ofs; 353 offset = *sg_first_ofs;
355 354
356 dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", 355 dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
357 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); 356 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
358 357
359 358
@@ -376,7 +375,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
376 pxa_dma->sg_cpu[i].ddadr = 375 pxa_dma->sg_cpu[i].ddadr =
377 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); 376 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
378 377
379 dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", 378 dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
380 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), 379 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
381 sg_dma_address(sg) + offset, xfer_len); 380 sg_dma_address(sg) + offset, xfer_len);
382 offset = 0; 381 offset = 0;
@@ -488,7 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
488 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, 487 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
489 &sg, &next_ofs); 488 &sg, &next_ofs);
490 if (ret) { 489 if (ret) {
491 dev_err(pcdev->dev, 490 dev_err(pcdev->soc_host.dev,
492 "DMA initialization for Y/RGB failed\n"); 491 "DMA initialization for Y/RGB failed\n");
493 goto fail; 492 goto fail;
494 } 493 }
@@ -498,7 +497,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
498 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, 497 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
499 size_u, &sg, &next_ofs); 498 size_u, &sg, &next_ofs);
500 if (ret) { 499 if (ret) {
501 dev_err(pcdev->dev, 500 dev_err(pcdev->soc_host.dev,
502 "DMA initialization for U failed\n"); 501 "DMA initialization for U failed\n");
503 goto fail_u; 502 goto fail_u;
504 } 503 }
@@ -508,7 +507,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
508 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, 507 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
509 size_v, &sg, &next_ofs); 508 size_v, &sg, &next_ofs);
510 if (ret) { 509 if (ret) {
511 dev_err(pcdev->dev, 510 dev_err(pcdev->soc_host.dev,
512 "DMA initialization for V failed\n"); 511 "DMA initialization for V failed\n");
513 goto fail_v; 512 goto fail_v;
514 } 513 }
@@ -522,10 +521,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
522 return 0; 521 return 0;
523 522
524fail_v: 523fail_v:
525 dma_free_coherent(pcdev->dev, buf->dmas[1].sg_size, 524 dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size,
526 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); 525 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
527fail_u: 526fail_u:
528 dma_free_coherent(pcdev->dev, buf->dmas[0].sg_size, 527 dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size,
529 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); 528 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
530fail: 529fail:
531 free_buffer(vq, buf); 530 free_buffer(vq, buf);
@@ -549,7 +548,7 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
549 active = pcdev->active; 548 active = pcdev->active;
550 549
551 for (i = 0; i < pcdev->channels; i++) { 550 for (i = 0; i < pcdev->channels; i++) {
552 dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__, 551 dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__,
553 i, active->dmas[i].sg_dma); 552 i, active->dmas[i].sg_dma);
554 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; 553 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
555 DCSR(pcdev->dma_chans[i]) = DCSR_RUN; 554 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
@@ -561,7 +560,7 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
561 int i; 560 int i;
562 561
563 for (i = 0; i < pcdev->channels; i++) { 562 for (i = 0; i < pcdev->channels; i++) {
564 dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i); 563 dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i);
565 DCSR(pcdev->dma_chans[i]) = 0; 564 DCSR(pcdev->dma_chans[i]) = 0;
566 } 565 }
567} 566}
@@ -597,7 +596,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
597{ 596{
598 unsigned long cicr0, cifr; 597 unsigned long cicr0, cifr;
599 598
600 dev_dbg(pcdev->dev, "%s\n", __func__); 599 dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
601 /* Reset the FIFOs */ 600 /* Reset the FIFOs */
602 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; 601 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
603 __raw_writel(cifr, pcdev->base + CIFR); 602 __raw_writel(cifr, pcdev->base + CIFR);
@@ -617,7 +616,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
617 __raw_writel(cicr0, pcdev->base + CICR0); 616 __raw_writel(cicr0, pcdev->base + CICR0);
618 617
619 pcdev->active = NULL; 618 pcdev->active = NULL;
620 dev_dbg(pcdev->dev, "%s\n", __func__); 619 dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
621} 620}
622 621
623static void pxa_videobuf_queue(struct videobuf_queue *vq, 622static void pxa_videobuf_queue(struct videobuf_queue *vq,
@@ -686,7 +685,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
686 do_gettimeofday(&vb->ts); 685 do_gettimeofday(&vb->ts);
687 vb->field_count++; 686 vb->field_count++;
688 wake_up(&vb->done); 687 wake_up(&vb->done);
689 dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); 688 dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
690 689
691 if (list_empty(&pcdev->capture)) { 690 if (list_empty(&pcdev->capture)) {
692 pxa_camera_stop_capture(pcdev); 691 pxa_camera_stop_capture(pcdev);
@@ -722,7 +721,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
722 for (i = 0; i < pcdev->channels; i++) 721 for (i = 0; i < pcdev->channels; i++)
723 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) 722 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
724 is_dma_stopped = 0; 723 is_dma_stopped = 0;
725 dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n", 724 dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
726 __func__, pcdev->active, is_dma_stopped); 725 __func__, pcdev->active, is_dma_stopped);
727 if (pcdev->active && is_dma_stopped) 726 if (pcdev->active && is_dma_stopped)
728 pxa_camera_start_capture(pcdev); 727 pxa_camera_start_capture(pcdev);
@@ -747,12 +746,12 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
747 overrun |= CISR_IFO_1 | CISR_IFO_2; 746 overrun |= CISR_IFO_1 | CISR_IFO_2;
748 747
749 if (status & DCSR_BUSERR) { 748 if (status & DCSR_BUSERR) {
750 dev_err(pcdev->dev, "DMA Bus Error IRQ!\n"); 749 dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n");
751 goto out; 750 goto out;
752 } 751 }
753 752
754 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { 753 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
755 dev_err(pcdev->dev, "Unknown DMA IRQ source, " 754 dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, "
756 "status: 0x%08x\n", status); 755 "status: 0x%08x\n", status);
757 goto out; 756 goto out;
758 } 757 }
@@ -776,7 +775,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
776 buf = container_of(vb, struct pxa_buffer, vb); 775 buf = container_of(vb, struct pxa_buffer, vb);
777 WARN_ON(buf->inwork || list_empty(&vb->queue)); 776 WARN_ON(buf->inwork || list_empty(&vb->queue));
778 777
779 dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", 778 dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
780 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", 779 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
781 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); 780 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
782 781
@@ -787,7 +786,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
787 */ 786 */
788 if (camera_status & overrun && 787 if (camera_status & overrun &&
789 !list_is_last(pcdev->capture.next, &pcdev->capture)) { 788 !list_is_last(pcdev->capture.next, &pcdev->capture)) {
790 dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", 789 dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n",
791 camera_status); 790 camera_status);
792 pxa_camera_stop_capture(pcdev); 791 pxa_camera_stop_capture(pcdev);
793 pxa_camera_start_capture(pcdev); 792 pxa_camera_start_capture(pcdev);
@@ -854,7 +853,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
854 /* mclk <= ciclk / 4 (27.4.2) */ 853 /* mclk <= ciclk / 4 (27.4.2) */
855 if (mclk > lcdclk / 4) { 854 if (mclk > lcdclk / 4) {
856 mclk = lcdclk / 4; 855 mclk = lcdclk / 4;
857 dev_warn(pcdev->dev, "Limiting master clock to %lu\n", mclk); 856 dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk);
858 } 857 }
859 858
860 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ 859 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
@@ -864,7 +863,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
864 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 863 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
865 pcdev->mclk = lcdclk / (2 * (div + 1)); 864 pcdev->mclk = lcdclk / (2 * (div + 1));
866 865
867 dev_dbg(pcdev->dev, "LCD clock %luHz, target freq %luHz, " 866 dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, "
868 "divisor %u\n", lcdclk, mclk, div); 867 "divisor %u\n", lcdclk, mclk, div);
869 868
870 return div; 869 return div;
@@ -884,12 +883,12 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
884 struct pxacamera_platform_data *pdata = pcdev->pdata; 883 struct pxacamera_platform_data *pdata = pcdev->pdata;
885 u32 cicr4 = 0; 884 u32 cicr4 = 0;
886 885
887 dev_dbg(pcdev->dev, "Registered platform device at %p data %p\n", 886 dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n",
888 pcdev, pdata); 887 pcdev, pdata);
889 888
890 if (pdata && pdata->init) { 889 if (pdata && pdata->init) {
891 dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__); 890 dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__);
892 pdata->init(pcdev->dev); 891 pdata->init(pcdev->soc_host.dev);
893 } 892 }
894 893
895 /* disable all interrupts */ 894 /* disable all interrupts */
@@ -931,7 +930,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
931 struct videobuf_buffer *vb; 930 struct videobuf_buffer *vb;
932 931
933 status = __raw_readl(pcdev->base + CISR); 932 status = __raw_readl(pcdev->base + CISR);
934 dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status); 933 dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status);
935 934
936 if (!status) 935 if (!status)
937 return IRQ_NONE; 936 return IRQ_NONE;
@@ -1259,7 +1258,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1259 xlate->cam_fmt = icd->formats + idx; 1258 xlate->cam_fmt = icd->formats + idx;
1260 xlate->buswidth = buswidth; 1259 xlate->buswidth = buswidth;
1261 xlate++; 1260 xlate++;
1262 dev_dbg(&ici->dev, "Providing format %s using %s\n", 1261 dev_dbg(ici->dev, "Providing format %s using %s\n",
1263 pxa_camera_formats[0].name, 1262 pxa_camera_formats[0].name,
1264 icd->formats[idx].name); 1263 icd->formats[idx].name);
1265 } 1264 }
@@ -1274,7 +1273,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1274 xlate->cam_fmt = icd->formats + idx; 1273 xlate->cam_fmt = icd->formats + idx;
1275 xlate->buswidth = buswidth; 1274 xlate->buswidth = buswidth;
1276 xlate++; 1275 xlate++;
1277 dev_dbg(&ici->dev, "Providing format %s packed\n", 1276 dev_dbg(ici->dev, "Providing format %s packed\n",
1278 icd->formats[idx].name); 1277 icd->formats[idx].name);
1279 } 1278 }
1280 break; 1279 break;
@@ -1286,7 +1285,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1286 xlate->cam_fmt = icd->formats + idx; 1285 xlate->cam_fmt = icd->formats + idx;
1287 xlate->buswidth = icd->formats[idx].depth; 1286 xlate->buswidth = icd->formats[idx].depth;
1288 xlate++; 1287 xlate++;
1289 dev_dbg(&ici->dev, 1288 dev_dbg(ici->dev,
1290 "Providing format %s in pass-through mode\n", 1289 "Providing format %s in pass-through mode\n",
1291 icd->formats[idx].name); 1290 icd->formats[idx].name);
1292 } 1291 }
@@ -1315,11 +1314,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
1315 icd->sense = NULL; 1314 icd->sense = NULL;
1316 1315
1317 if (ret < 0) { 1316 if (ret < 0) {
1318 dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n", 1317 dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n",
1319 rect->width, rect->height, rect->left, rect->top); 1318 rect->width, rect->height, rect->left, rect->top);
1320 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1319 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1321 if (sense.pixel_clock > sense.pixel_clock_max) { 1320 if (sense.pixel_clock > sense.pixel_clock_max) {
1322 dev_err(&ici->dev, 1321 dev_err(ici->dev,
1323 "pixel clock %lu set by the camera too high!", 1322 "pixel clock %lu set by the camera too high!",
1324 sense.pixel_clock); 1323 sense.pixel_clock);
1325 return -EIO; 1324 return -EIO;
@@ -1347,7 +1346,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1347 1346
1348 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1347 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1349 if (!xlate) { 1348 if (!xlate) {
1350 dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); 1349 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
1351 return -EINVAL; 1350 return -EINVAL;
1352 } 1351 }
1353 1352
@@ -1363,11 +1362,11 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1363 icd->sense = NULL; 1362 icd->sense = NULL;
1364 1363
1365 if (ret < 0) { 1364 if (ret < 0) {
1366 dev_warn(&ici->dev, "Failed to configure for format %x\n", 1365 dev_warn(ici->dev, "Failed to configure for format %x\n",
1367 pix->pixelformat); 1366 pix->pixelformat);
1368 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1367 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1369 if (sense.pixel_clock > sense.pixel_clock_max) { 1368 if (sense.pixel_clock > sense.pixel_clock_max) {
1370 dev_err(&ici->dev, 1369 dev_err(ici->dev,
1371 "pixel clock %lu set by the camera too high!", 1370 "pixel clock %lu set by the camera too high!",
1372 sense.pixel_clock); 1371 sense.pixel_clock);
1373 return -EIO; 1372 return -EIO;
@@ -1395,7 +1394,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1395 1394
1396 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1395 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1397 if (!xlate) { 1396 if (!xlate) {
1398 dev_warn(&ici->dev, "Format %x not found\n", pixfmt); 1397 dev_warn(ici->dev, "Format %x not found\n", pixfmt);
1399 return -EINVAL; 1398 return -EINVAL;
1400 } 1399 }
1401 1400
@@ -1552,13 +1551,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1552 .set_bus_param = pxa_camera_set_bus_param, 1551 .set_bus_param = pxa_camera_set_bus_param,
1553}; 1552};
1554 1553
1555/* Should be allocated dynamically too, but we have only one. */ 1554static int __devinit pxa_camera_probe(struct platform_device *pdev)
1556static struct soc_camera_host pxa_soc_camera_host = {
1557 .drv_name = PXA_CAM_DRV_NAME,
1558 .ops = &pxa_soc_camera_host_ops,
1559};
1560
1561static int pxa_camera_probe(struct platform_device *pdev)
1562{ 1555{
1563 struct pxa_camera_dev *pcdev; 1556 struct pxa_camera_dev *pcdev;
1564 struct resource *res; 1557 struct resource *res;
@@ -1586,7 +1579,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
1586 goto exit_kfree; 1579 goto exit_kfree;
1587 } 1580 }
1588 1581
1589 dev_set_drvdata(&pdev->dev, pcdev);
1590 pcdev->res = res; 1582 pcdev->res = res;
1591 1583
1592 pcdev->pdata = pdev->dev.platform_data; 1584 pcdev->pdata = pdev->dev.platform_data;
@@ -1607,7 +1599,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
1607 pcdev->mclk = 20000000; 1599 pcdev->mclk = 20000000;
1608 } 1600 }
1609 1601
1610 pcdev->dev = &pdev->dev;
1611 pcdev->mclk_divisor = mclk_get_divisor(pcdev); 1602 pcdev->mclk_divisor = mclk_get_divisor(pcdev);
1612 1603
1613 INIT_LIST_HEAD(&pcdev->capture); 1604 INIT_LIST_HEAD(&pcdev->capture);
@@ -1616,13 +1607,13 @@ static int pxa_camera_probe(struct platform_device *pdev)
1616 /* 1607 /*
1617 * Request the regions. 1608 * Request the regions.
1618 */ 1609 */
1619 if (!request_mem_region(res->start, res->end - res->start + 1, 1610 if (!request_mem_region(res->start, resource_size(res),
1620 PXA_CAM_DRV_NAME)) { 1611 PXA_CAM_DRV_NAME)) {
1621 err = -EBUSY; 1612 err = -EBUSY;
1622 goto exit_clk; 1613 goto exit_clk;
1623 } 1614 }
1624 1615
1625 base = ioremap(res->start, res->end - res->start + 1); 1616 base = ioremap(res->start, resource_size(res));
1626 if (!base) { 1617 if (!base) {
1627 err = -ENOMEM; 1618 err = -ENOMEM;
1628 goto exit_release; 1619 goto exit_release;
@@ -1634,29 +1625,29 @@ static int pxa_camera_probe(struct platform_device *pdev)
1634 err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, 1625 err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
1635 pxa_camera_dma_irq_y, pcdev); 1626 pxa_camera_dma_irq_y, pcdev);
1636 if (err < 0) { 1627 if (err < 0) {
1637 dev_err(pcdev->dev, "Can't request DMA for Y\n"); 1628 dev_err(&pdev->dev, "Can't request DMA for Y\n");
1638 goto exit_iounmap; 1629 goto exit_iounmap;
1639 } 1630 }
1640 pcdev->dma_chans[0] = err; 1631 pcdev->dma_chans[0] = err;
1641 dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]); 1632 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
1642 1633
1643 err = pxa_request_dma("CI_U", DMA_PRIO_HIGH, 1634 err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
1644 pxa_camera_dma_irq_u, pcdev); 1635 pxa_camera_dma_irq_u, pcdev);
1645 if (err < 0) { 1636 if (err < 0) {
1646 dev_err(pcdev->dev, "Can't request DMA for U\n"); 1637 dev_err(&pdev->dev, "Can't request DMA for U\n");
1647 goto exit_free_dma_y; 1638 goto exit_free_dma_y;
1648 } 1639 }
1649 pcdev->dma_chans[1] = err; 1640 pcdev->dma_chans[1] = err;
1650 dev_dbg(pcdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]); 1641 dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
1651 1642
1652 err = pxa_request_dma("CI_V", DMA_PRIO_HIGH, 1643 err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
1653 pxa_camera_dma_irq_v, pcdev); 1644 pxa_camera_dma_irq_v, pcdev);
1654 if (err < 0) { 1645 if (err < 0) {
1655 dev_err(pcdev->dev, "Can't request DMA for V\n"); 1646 dev_err(&pdev->dev, "Can't request DMA for V\n");
1656 goto exit_free_dma_u; 1647 goto exit_free_dma_u;
1657 } 1648 }
1658 pcdev->dma_chans[2] = err; 1649 pcdev->dma_chans[2] = err;
1659 dev_dbg(pcdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]); 1650 dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
1660 1651
1661 DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD; 1652 DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
1662 DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD; 1653 DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
@@ -1666,14 +1657,17 @@ static int pxa_camera_probe(struct platform_device *pdev)
1666 err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME, 1657 err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
1667 pcdev); 1658 pcdev);
1668 if (err) { 1659 if (err) {
1669 dev_err(pcdev->dev, "Camera interrupt register failed \n"); 1660 dev_err(&pdev->dev, "Camera interrupt register failed \n");
1670 goto exit_free_dma; 1661 goto exit_free_dma;
1671 } 1662 }
1672 1663
1673 pxa_soc_camera_host.priv = pcdev; 1664 pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
1674 pxa_soc_camera_host.dev.parent = &pdev->dev; 1665 pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
1675 pxa_soc_camera_host.nr = pdev->id; 1666 pcdev->soc_host.priv = pcdev;
1676 err = soc_camera_host_register(&pxa_soc_camera_host); 1667 pcdev->soc_host.dev = &pdev->dev;
1668 pcdev->soc_host.nr = pdev->id;
1669
1670 err = soc_camera_host_register(&pcdev->soc_host);
1677 if (err) 1671 if (err)
1678 goto exit_free_irq; 1672 goto exit_free_irq;
1679 1673
@@ -1690,7 +1684,7 @@ exit_free_dma_y:
1690exit_iounmap: 1684exit_iounmap:
1691 iounmap(base); 1685 iounmap(base);
1692exit_release: 1686exit_release:
1693 release_mem_region(res->start, res->end - res->start + 1); 1687 release_mem_region(res->start, resource_size(res));
1694exit_clk: 1688exit_clk:
1695 clk_put(pcdev->clk); 1689 clk_put(pcdev->clk);
1696exit_kfree: 1690exit_kfree:
@@ -1701,7 +1695,9 @@ exit:
1701 1695
1702static int __devexit pxa_camera_remove(struct platform_device *pdev) 1696static int __devexit pxa_camera_remove(struct platform_device *pdev)
1703{ 1697{
1704 struct pxa_camera_dev *pcdev = platform_get_drvdata(pdev); 1698 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1699 struct pxa_camera_dev *pcdev = container_of(soc_host,
1700 struct pxa_camera_dev, soc_host);
1705 struct resource *res; 1701 struct resource *res;
1706 1702
1707 clk_put(pcdev->clk); 1703 clk_put(pcdev->clk);
@@ -1711,12 +1707,12 @@ static int __devexit pxa_camera_remove(struct platform_device *pdev)
1711 pxa_free_dma(pcdev->dma_chans[2]); 1707 pxa_free_dma(pcdev->dma_chans[2]);
1712 free_irq(pcdev->irq, pcdev); 1708 free_irq(pcdev->irq, pcdev);
1713 1709
1714 soc_camera_host_unregister(&pxa_soc_camera_host); 1710 soc_camera_host_unregister(soc_host);
1715 1711
1716 iounmap(pcdev->base); 1712 iounmap(pcdev->base);
1717 1713
1718 res = pcdev->res; 1714 res = pcdev->res;
1719 release_mem_region(res->start, res->end - res->start + 1); 1715 release_mem_region(res->start, resource_size(res));
1720 1716
1721 kfree(pcdev); 1717 kfree(pcdev);
1722 1718
@@ -1730,11 +1726,11 @@ static struct platform_driver pxa_camera_driver = {
1730 .name = PXA_CAM_DRV_NAME, 1726 .name = PXA_CAM_DRV_NAME,
1731 }, 1727 },
1732 .probe = pxa_camera_probe, 1728 .probe = pxa_camera_probe,
1733 .remove = __exit_p(pxa_camera_remove), 1729 .remove = __devexit_p(pxa_camera_remove),
1734}; 1730};
1735 1731
1736 1732
1737static int __devinit pxa_camera_init(void) 1733static int __init pxa_camera_init(void)
1738{ 1734{
1739 return platform_driver_register(&pxa_camera_driver); 1735 return platform_driver_register(&pxa_camera_driver);
1740} 1736}
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 30f4698be90a..6be845ccc7d7 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -77,6 +77,8 @@
77#define MAX_CHANNELS 4 77#define MAX_CHANNELS 4
78#define S2255_MARKER_FRAME 0x2255DA4AL 78#define S2255_MARKER_FRAME 0x2255DA4AL
79#define S2255_MARKER_RESPONSE 0x2255ACACL 79#define S2255_MARKER_RESPONSE 0x2255ACACL
80#define S2255_RESPONSE_SETMODE 0x01
81#define S2255_RESPONSE_FW 0x10
80#define S2255_USB_XFER_SIZE (16 * 1024) 82#define S2255_USB_XFER_SIZE (16 * 1024)
81#define MAX_CHANNELS 4 83#define MAX_CHANNELS 4
82#define MAX_PIPE_BUFFERS 1 84#define MAX_PIPE_BUFFERS 1
@@ -107,6 +109,8 @@
107#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ 109#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
108#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ 110#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
109#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ 111#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
112/* SCALE_4CIFSI is the 2 fields interpolated into one */
113#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
110 114
111#define COLOR_YUVPL 1 /* YUV planar */ 115#define COLOR_YUVPL 1 /* YUV planar */
112#define COLOR_YUVPK 2 /* YUV packed */ 116#define COLOR_YUVPK 2 /* YUV packed */
@@ -178,9 +182,6 @@ struct s2255_bufferi {
178 182
179struct s2255_dmaqueue { 183struct s2255_dmaqueue {
180 struct list_head active; 184 struct list_head active;
181 /* thread for acquisition */
182 struct task_struct *kthread;
183 int frame;
184 struct s2255_dev *dev; 185 struct s2255_dev *dev;
185 int channel; 186 int channel;
186}; 187};
@@ -210,16 +211,11 @@ struct s2255_pipeinfo {
210 u32 max_transfer_size; 211 u32 max_transfer_size;
211 u32 cur_transfer_size; 212 u32 cur_transfer_size;
212 u8 *transfer_buffer; 213 u8 *transfer_buffer;
213 u32 transfer_flags;;
214 u32 state; 214 u32 state;
215 u32 prev_state;
216 u32 urb_size;
217 void *stream_urb; 215 void *stream_urb;
218 void *dev; /* back pointer to s2255_dev struct*/ 216 void *dev; /* back pointer to s2255_dev struct*/
219 u32 err_count; 217 u32 err_count;
220 u32 buf_index;
221 u32 idx; 218 u32 idx;
222 u32 priority_set;
223}; 219};
224 220
225struct s2255_fmt; /*forward declaration */ 221struct s2255_fmt; /*forward declaration */
@@ -239,13 +235,13 @@ struct s2255_dev {
239 struct list_head s2255_devlist; 235 struct list_head s2255_devlist;
240 struct timer_list timer; 236 struct timer_list timer;
241 struct s2255_fw *fw_data; 237 struct s2255_fw *fw_data;
242 int board_num;
243 int is_open;
244 struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; 238 struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS];
245 struct s2255_bufferi buffer[MAX_CHANNELS]; 239 struct s2255_bufferi buffer[MAX_CHANNELS];
246 struct s2255_mode mode[MAX_CHANNELS]; 240 struct s2255_mode mode[MAX_CHANNELS];
247 /* jpeg compression */ 241 /* jpeg compression */
248 struct v4l2_jpegcompression jc[MAX_CHANNELS]; 242 struct v4l2_jpegcompression jc[MAX_CHANNELS];
243 /* capture parameters (for high quality mode full size) */
244 struct v4l2_captureparm cap_parm[MAX_CHANNELS];
249 const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; 245 const struct s2255_fmt *cur_fmt[MAX_CHANNELS];
250 int cur_frame[MAX_CHANNELS]; 246 int cur_frame[MAX_CHANNELS];
251 int last_frame[MAX_CHANNELS]; 247 int last_frame[MAX_CHANNELS];
@@ -297,9 +293,10 @@ struct s2255_fh {
297 int resources[MAX_CHANNELS]; 293 int resources[MAX_CHANNELS];
298}; 294};
299 295
300#define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ 296/* current cypress EEPROM firmware version */
297#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
301#define S2255_MAJOR_VERSION 1 298#define S2255_MAJOR_VERSION 1
302#define S2255_MINOR_VERSION 13 299#define S2255_MINOR_VERSION 14
303#define S2255_RELEASE 0 300#define S2255_RELEASE 0
304#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ 301#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
305 S2255_MINOR_VERSION, \ 302 S2255_MINOR_VERSION, \
@@ -1027,9 +1024,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1027 fh->type = f->type; 1024 fh->type = f->type;
1028 norm = norm_minw(fh->dev->vdev[fh->channel]); 1025 norm = norm_minw(fh->dev->vdev[fh->channel]);
1029 if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { 1026 if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) {
1030 if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) 1027 if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) {
1031 fh->mode.scale = SCALE_4CIFS; 1028 if (fh->dev->cap_parm[fh->channel].capturemode &
1032 else 1029 V4L2_MODE_HIGHQUALITY) {
1030 fh->mode.scale = SCALE_4CIFSI;
1031 dprintk(2, "scale 4CIFSI\n");
1032 } else {
1033 fh->mode.scale = SCALE_4CIFS;
1034 dprintk(2, "scale 4CIFS\n");
1035 }
1036 } else
1033 fh->mode.scale = SCALE_2CIFS; 1037 fh->mode.scale = SCALE_2CIFS;
1034 1038
1035 } else { 1039 } else {
@@ -1130,6 +1134,7 @@ static u32 get_transfer_size(struct s2255_mode *mode)
1130 if (mode->format == FORMAT_NTSC) { 1134 if (mode->format == FORMAT_NTSC) {
1131 switch (mode->scale) { 1135 switch (mode->scale) {
1132 case SCALE_4CIFS: 1136 case SCALE_4CIFS:
1137 case SCALE_4CIFSI:
1133 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; 1138 linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
1134 pixelsPerLine = LINE_SZ_4CIFS_NTSC; 1139 pixelsPerLine = LINE_SZ_4CIFS_NTSC;
1135 break; 1140 break;
@@ -1147,6 +1152,7 @@ static u32 get_transfer_size(struct s2255_mode *mode)
1147 } else if (mode->format == FORMAT_PAL) { 1152 } else if (mode->format == FORMAT_PAL) {
1148 switch (mode->scale) { 1153 switch (mode->scale) {
1149 case SCALE_4CIFS: 1154 case SCALE_4CIFS:
1155 case SCALE_4CIFSI:
1150 linesPerFrame = NUM_LINES_4CIFS_PAL * 2; 1156 linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
1151 pixelsPerLine = LINE_SZ_4CIFS_PAL; 1157 pixelsPerLine = LINE_SZ_4CIFS_PAL;
1152 break; 1158 break;
@@ -1502,6 +1508,33 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
1502 dprintk(2, "setting jpeg quality %d\n", jc->quality); 1508 dprintk(2, "setting jpeg quality %d\n", jc->quality);
1503 return 0; 1509 return 0;
1504} 1510}
1511
1512static int vidioc_g_parm(struct file *file, void *priv,
1513 struct v4l2_streamparm *sp)
1514{
1515 struct s2255_fh *fh = priv;
1516 struct s2255_dev *dev = fh->dev;
1517 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1518 return -EINVAL;
1519 sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
1520 dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode);
1521 return 0;
1522}
1523
1524static int vidioc_s_parm(struct file *file, void *priv,
1525 struct v4l2_streamparm *sp)
1526{
1527 struct s2255_fh *fh = priv;
1528 struct s2255_dev *dev = fh->dev;
1529
1530 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1531 return -EINVAL;
1532
1533 dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode;
1534 dprintk(2, "setting param capture mode %d\n",
1535 sp->parm.capture.capturemode);
1536 return 0;
1537}
1505static int s2255_open(struct file *file) 1538static int s2255_open(struct file *file)
1506{ 1539{
1507 int minor = video_devdata(file)->minor; 1540 int minor = video_devdata(file)->minor;
@@ -1793,6 +1826,8 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
1793#endif 1826#endif
1794 .vidioc_s_jpegcomp = vidioc_s_jpegcomp, 1827 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1795 .vidioc_g_jpegcomp = vidioc_g_jpegcomp, 1828 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1829 .vidioc_s_parm = vidioc_s_parm,
1830 .vidioc_g_parm = vidioc_g_parm,
1796}; 1831};
1797 1832
1798static struct video_device template = { 1833static struct video_device template = {
@@ -1818,7 +1853,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
1818 INIT_LIST_HEAD(&dev->vidq[i].active); 1853 INIT_LIST_HEAD(&dev->vidq[i].active);
1819 dev->vidq[i].dev = dev; 1854 dev->vidq[i].dev = dev;
1820 dev->vidq[i].channel = i; 1855 dev->vidq[i].channel = i;
1821 dev->vidq[i].kthread = NULL;
1822 /* register 4 video devices */ 1856 /* register 4 video devices */
1823 dev->vdev[i] = video_device_alloc(); 1857 dev->vdev[i] = video_device_alloc();
1824 memcpy(dev->vdev[i], &template, sizeof(struct video_device)); 1858 memcpy(dev->vdev[i], &template, sizeof(struct video_device));
@@ -1839,7 +1873,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
1839 return ret; 1873 return ret;
1840 } 1874 }
1841 } 1875 }
1842 printk(KERN_INFO "Sensoray 2255 V4L driver\n"); 1876 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1877 S2255_MAJOR_VERSION,
1878 S2255_MINOR_VERSION);
1843 return ret; 1879 return ret;
1844} 1880}
1845 1881
@@ -1929,14 +1965,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1929 if (!(cc >= 0 && cc < MAX_CHANNELS)) 1965 if (!(cc >= 0 && cc < MAX_CHANNELS))
1930 break; 1966 break;
1931 switch (pdword[2]) { 1967 switch (pdword[2]) {
1932 case 0x01: 1968 case S2255_RESPONSE_SETMODE:
1933 /* check if channel valid */ 1969 /* check if channel valid */
1934 /* set mode ready */ 1970 /* set mode ready */
1935 dev->setmode_ready[cc] = 1; 1971 dev->setmode_ready[cc] = 1;
1936 wake_up(&dev->wait_setmode[cc]); 1972 wake_up(&dev->wait_setmode[cc]);
1937 dprintk(5, "setmode ready %d\n", cc); 1973 dprintk(5, "setmode ready %d\n", cc);
1938 break; 1974 break;
1939 case 0x10: 1975 case S2255_RESPONSE_FW:
1940 1976
1941 dev->chn_ready |= (1 << cc); 1977 dev->chn_ready |= (1 << cc);
1942 if ((dev->chn_ready & 0x0f) != 0x0f) 1978 if ((dev->chn_ready & 0x0f) != 0x0f)
@@ -2172,10 +2208,15 @@ static int s2255_board_init(struct s2255_dev *dev)
2172 /* query the firmware */ 2208 /* query the firmware */
2173 fw_ver = s2255_get_fx2fw(dev); 2209 fw_ver = s2255_get_fx2fw(dev);
2174 2210
2175 printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver); 2211 printk(KERN_INFO "2255 usb firmware version %d.%d\n",
2176 if (fw_ver < CUR_USB_FWVER) 2212 (fw_ver >> 8) & 0xff,
2213 fw_ver & 0xff);
2214
2215 if (fw_ver < S2255_CUR_USB_FWVER)
2177 dev_err(&dev->udev->dev, 2216 dev_err(&dev->udev->dev,
2178 "usb firmware not up to date %d\n", fw_ver); 2217 "usb firmware not up to date %d.%d\n",
2218 (fw_ver >> 8) & 0xff,
2219 fw_ver & 0xff);
2179 2220
2180 for (j = 0; j < MAX_CHANNELS; j++) { 2221 for (j = 0; j < MAX_CHANNELS; j++) {
2181 dev->b_acquire[j] = 0; 2222 dev->b_acquire[j] = 0;
@@ -2240,8 +2281,10 @@ static void read_pipe_completion(struct urb *purb)
2240 return; 2281 return;
2241 } 2282 }
2242 status = purb->status; 2283 status = purb->status;
2243 if (status != 0) { 2284 /* if shutting down, do not resubmit, exit immediately */
2244 dprintk(2, "read_pipe_completion: err\n"); 2285 if (status == -ESHUTDOWN) {
2286 dprintk(2, "read_pipe_completion: err shutdown\n");
2287 pipe_info->err_count++;
2245 return; 2288 return;
2246 } 2289 }
2247 2290
@@ -2250,9 +2293,13 @@ static void read_pipe_completion(struct urb *purb)
2250 return; 2293 return;
2251 } 2294 }
2252 2295
2253 s2255_read_video_callback(dev, pipe_info); 2296 if (status == 0)
2297 s2255_read_video_callback(dev, pipe_info);
2298 else {
2299 pipe_info->err_count++;
2300 dprintk(1, "s2255drv: failed URB %d\n", status);
2301 }
2254 2302
2255 pipe_info->err_count = 0;
2256 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); 2303 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2257 /* reuse urb */ 2304 /* reuse urb */
2258 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, 2305 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
@@ -2264,7 +2311,6 @@ static void read_pipe_completion(struct urb *purb)
2264 if (pipe_info->state != 0) { 2311 if (pipe_info->state != 0) {
2265 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { 2312 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
2266 dev_err(&dev->udev->dev, "error submitting urb\n"); 2313 dev_err(&dev->udev->dev, "error submitting urb\n");
2267 usb_free_urb(pipe_info->stream_urb);
2268 } 2314 }
2269 } else { 2315 } else {
2270 dprintk(2, "read pipe complete state 0\n"); 2316 dprintk(2, "read pipe complete state 0\n");
@@ -2283,8 +2329,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
2283 2329
2284 for (i = 0; i < MAX_PIPE_BUFFERS; i++) { 2330 for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
2285 pipe_info->state = 1; 2331 pipe_info->state = 1;
2286 pipe_info->buf_index = (u32) i; 2332 pipe_info->err_count = 0;
2287 pipe_info->priority_set = 0;
2288 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); 2333 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2289 if (!pipe_info->stream_urb) { 2334 if (!pipe_info->stream_urb) {
2290 dev_err(&dev->udev->dev, 2335 dev_err(&dev->udev->dev,
@@ -2298,7 +2343,6 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
2298 pipe_info->cur_transfer_size, 2343 pipe_info->cur_transfer_size,
2299 read_pipe_completion, pipe_info); 2344 read_pipe_completion, pipe_info);
2300 2345
2301 pipe_info->urb_size = sizeof(pipe_info->stream_urb);
2302 dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); 2346 dprintk(4, "submitting URB %p\n", pipe_info->stream_urb);
2303 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); 2347 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2304 if (retval) { 2348 if (retval) {
@@ -2403,8 +2447,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
2403 if (pipe_info->state == 0) 2447 if (pipe_info->state == 0)
2404 continue; 2448 continue;
2405 pipe_info->state = 0; 2449 pipe_info->state = 0;
2406 pipe_info->prev_state = 1;
2407
2408 } 2450 }
2409 } 2451 }
2410 2452
@@ -2542,7 +2584,9 @@ static int s2255_probe(struct usb_interface *interface,
2542 s2255_probe_v4l(dev); 2584 s2255_probe_v4l(dev);
2543 usb_reset_device(dev->udev); 2585 usb_reset_device(dev->udev);
2544 /* load 2255 board specific */ 2586 /* load 2255 board specific */
2545 s2255_board_init(dev); 2587 retval = s2255_board_init(dev);
2588 if (retval)
2589 goto error;
2546 2590
2547 dprintk(4, "before probe done %p\n", dev); 2591 dprintk(4, "before probe done %p\n", dev);
2548 spin_lock_init(&dev->slock); 2592 spin_lock_init(&dev->slock);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 0ba68987bfce..5bcce092e804 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -44,6 +44,7 @@ config VIDEO_SAA7134_DVB
44 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 44 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
45 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 45 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
46 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE 46 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
47 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
47 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE 48 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
48 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE 49 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
49 ---help--- 50 ---help---
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index 3dbaa19a6d00..604158a8c235 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,8 +3,7 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \ 3 saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \
4 saa7134-video.o saa7134-input.o 4 saa7134-video.o saa7134-input.o
5 5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ 6obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o
7 saa6752hs.o
8 7
9obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o 8obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
10 9
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index fdb19449d269..06861b782b95 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1669,6 +1669,39 @@ struct saa7134_board saa7134_boards[] = {
1669 .amux = LINE1, 1669 .amux = LINE1,
1670 }, 1670 },
1671 }, 1671 },
1672 [SAA7134_BOARD_AVERMEDIA_CARDBUS_501] = {
1673 /* Oldrich Jedlicka <oldium.pro@seznam.cz> */
1674 .name = "AVerMedia Cardbus TV/Radio (E501R)",
1675 .audio_clock = 0x187de7,
1676 .tuner_type = TUNER_ALPS_TSBE5_PAL,
1677 .radio_type = TUNER_TEA5767,
1678 .tuner_addr = 0x61,
1679 .radio_addr = 0x60,
1680 .tda9887_conf = TDA9887_PRESENT,
1681 .gpiomask = 0x08000000,
1682 .inputs = { {
1683 .name = name_tv,
1684 .vmux = 1,
1685 .amux = TV,
1686 .tv = 1,
1687 .gpio = 0x08000000,
1688 }, {
1689 .name = name_comp1,
1690 .vmux = 3,
1691 .amux = LINE1,
1692 .gpio = 0x08000000,
1693 }, {
1694 .name = name_svideo,
1695 .vmux = 8,
1696 .amux = LINE1,
1697 .gpio = 0x08000000,
1698 } },
1699 .radio = {
1700 .name = name_radio,
1701 .amux = LINE2,
1702 .gpio = 0x00000000,
1703 },
1704 },
1672 [SAA7134_BOARD_CINERGY400_CARDBUS] = { 1705 [SAA7134_BOARD_CINERGY400_CARDBUS] = {
1673 .name = "Terratec Cinergy 400 mobile", 1706 .name = "Terratec Cinergy 400 mobile",
1674 .audio_clock = 0x187de7, 1707 .audio_clock = 0x187de7,
@@ -3331,13 +3364,15 @@ struct saa7134_board saa7134_boards[] = {
3331 }, 3364 },
3332 }, 3365 },
3333 [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = { 3366 [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
3334 .name = "Hauppauge WinTV-HVR1110r3", 3367 .name = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid",
3335 .audio_clock = 0x00187de7, 3368 .audio_clock = 0x00187de7,
3336 .tuner_type = TUNER_PHILIPS_TDA8290, 3369 .tuner_type = TUNER_PHILIPS_TDA8290,
3337 .radio_type = UNSET, 3370 .radio_type = UNSET,
3338 .tuner_addr = ADDR_UNSET, 3371 .tuner_addr = ADDR_UNSET,
3339 .radio_addr = ADDR_UNSET, 3372 .radio_addr = ADDR_UNSET,
3340 .tuner_config = 3, 3373 .tuner_config = 3,
3374 .mpeg = SAA7134_MPEG_DVB,
3375 .ts_type = SAA7134_MPEG_TS_SERIAL,
3341 .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ 3376 .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
3342 .inputs = {{ 3377 .inputs = {{
3343 .name = name_tv, 3378 .name = name_tv,
@@ -4006,7 +4041,7 @@ struct saa7134_board saa7134_boards[] = {
4006 [SAA7134_BOARD_BEHOLD_505FM] = { 4041 [SAA7134_BOARD_BEHOLD_505FM] = {
4007 /* Beholder Intl. Ltd. 2008 */ 4042 /* Beholder Intl. Ltd. 2008 */
4008 /*Dmitry Belimov <d.belimov@gmail.com> */ 4043 /*Dmitry Belimov <d.belimov@gmail.com> */
4009 .name = "Beholder BeholdTV 505 FM/RDS", 4044 .name = "Beholder BeholdTV 505 FM",
4010 .audio_clock = 0x00200000, 4045 .audio_clock = 0x00200000,
4011 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 4046 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4012 .radio_type = UNSET, 4047 .radio_type = UNSET,
@@ -4019,6 +4054,40 @@ struct saa7134_board saa7134_boards[] = {
4019 .vmux = 3, 4054 .vmux = 3,
4020 .amux = LINE2, 4055 .amux = LINE2,
4021 .tv = 1, 4056 .tv = 1,
4057 }, {
4058 .name = name_comp1,
4059 .vmux = 1,
4060 .amux = LINE1,
4061 }, {
4062 .name = name_svideo,
4063 .vmux = 8,
4064 .amux = LINE1,
4065 } },
4066 .mute = {
4067 .name = name_mute,
4068 .amux = LINE1,
4069 },
4070 .radio = {
4071 .name = name_radio,
4072 .amux = LINE2,
4073 },
4074 },
4075 [SAA7134_BOARD_BEHOLD_505RDS] = {
4076 /* Beholder Intl. Ltd. 2008 */
4077 /*Dmitry Belimov <d.belimov@gmail.com> */
4078 .name = "Beholder BeholdTV 505 RDS",
4079 .audio_clock = 0x00200000,
4080 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4081 .radio_type = UNSET,
4082 .tuner_addr = ADDR_UNSET,
4083 .radio_addr = ADDR_UNSET,
4084 .tda9887_conf = TDA9887_PRESENT,
4085 .gpiomask = 0x00008000,
4086 .inputs = {{
4087 .name = name_tv,
4088 .vmux = 3,
4089 .amux = LINE2,
4090 .tv = 1,
4022 },{ 4091 },{
4023 .name = name_comp1, 4092 .name = name_comp1,
4024 .vmux = 1, 4093 .vmux = 1,
@@ -4040,7 +4109,7 @@ struct saa7134_board saa7134_boards[] = {
4040 [SAA7134_BOARD_BEHOLD_507_9FM] = { 4109 [SAA7134_BOARD_BEHOLD_507_9FM] = {
4041 /* Beholder Intl. Ltd. 2008 */ 4110 /* Beholder Intl. Ltd. 2008 */
4042 /*Dmitry Belimov <d.belimov@gmail.com> */ 4111 /*Dmitry Belimov <d.belimov@gmail.com> */
4043 .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", 4112 .name = "Beholder BeholdTV 507 FM / BeholdTV 509 FM",
4044 .audio_clock = 0x00187de7, 4113 .audio_clock = 0x00187de7,
4045 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 4114 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4046 .radio_type = UNSET, 4115 .radio_type = UNSET,
@@ -4067,6 +4136,66 @@ struct saa7134_board saa7134_boards[] = {
4067 .amux = LINE2, 4136 .amux = LINE2,
4068 }, 4137 },
4069 }, 4138 },
4139 [SAA7134_BOARD_BEHOLD_507RDS_MK5] = {
4140 /* Beholder Intl. Ltd. 2008 */
4141 /*Dmitry Belimov <d.belimov@gmail.com> */
4142 .name = "Beholder BeholdTV 507 RDS",
4143 .audio_clock = 0x00187de7,
4144 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4145 .radio_type = UNSET,
4146 .tuner_addr = ADDR_UNSET,
4147 .radio_addr = ADDR_UNSET,
4148 .tda9887_conf = TDA9887_PRESENT,
4149 .gpiomask = 0x00008000,
4150 .inputs = {{
4151 .name = name_tv,
4152 .vmux = 3,
4153 .amux = TV,
4154 .tv = 1,
4155 }, {
4156 .name = name_comp1,
4157 .vmux = 1,
4158 .amux = LINE1,
4159 }, {
4160 .name = name_svideo,
4161 .vmux = 8,
4162 .amux = LINE1,
4163 } },
4164 .radio = {
4165 .name = name_radio,
4166 .amux = LINE2,
4167 },
4168 },
4169 [SAA7134_BOARD_BEHOLD_507RDS_MK3] = {
4170 /* Beholder Intl. Ltd. 2008 */
4171 /*Dmitry Belimov <d.belimov@gmail.com> */
4172 .name = "Beholder BeholdTV 507 RDS",
4173 .audio_clock = 0x00187de7,
4174 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4175 .radio_type = UNSET,
4176 .tuner_addr = ADDR_UNSET,
4177 .radio_addr = ADDR_UNSET,
4178 .tda9887_conf = TDA9887_PRESENT,
4179 .gpiomask = 0x00008000,
4180 .inputs = {{
4181 .name = name_tv,
4182 .vmux = 3,
4183 .amux = TV,
4184 .tv = 1,
4185 }, {
4186 .name = name_comp1,
4187 .vmux = 1,
4188 .amux = LINE1,
4189 }, {
4190 .name = name_svideo,
4191 .vmux = 8,
4192 .amux = LINE1,
4193 } },
4194 .radio = {
4195 .name = name_radio,
4196 .amux = LINE2,
4197 },
4198 },
4070 [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { 4199 [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
4071 /* Beholder Intl. Ltd. 2008 */ 4200 /* Beholder Intl. Ltd. 2008 */
4072 /*Dmitry Belimov <d.belimov@gmail.com> */ 4201 /*Dmitry Belimov <d.belimov@gmail.com> */
@@ -4101,9 +4230,121 @@ struct saa7134_board saa7134_boards[] = {
4101 .gpio = 0x000A8000, 4230 .gpio = 0x000A8000,
4102 }, 4231 },
4103 }, 4232 },
4104 [SAA7134_BOARD_BEHOLD_607_9FM] = { 4233 [SAA7134_BOARD_BEHOLD_607FM_MK3] = {
4234 /* Andrey Melnikoff <temnota@kmv.ru> */
4235 .name = "Beholder BeholdTV 607 FM",
4236 .audio_clock = 0x00187de7,
4237 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4238 .radio_type = UNSET,
4239 .tuner_addr = ADDR_UNSET,
4240 .radio_addr = ADDR_UNSET,
4241 .tda9887_conf = TDA9887_PRESENT,
4242 .inputs = {{
4243 .name = name_tv,
4244 .vmux = 3,
4245 .amux = TV,
4246 .tv = 1,
4247 }, {
4248 .name = name_comp1,
4249 .vmux = 1,
4250 .amux = LINE1,
4251 }, {
4252 .name = name_svideo,
4253 .vmux = 8,
4254 .amux = LINE1,
4255 } },
4256 .radio = {
4257 .name = name_radio,
4258 .amux = LINE2,
4259 },
4260 },
4261 [SAA7134_BOARD_BEHOLD_609FM_MK3] = {
4262 /* Andrey Melnikoff <temnota@kmv.ru> */
4263 .name = "Beholder BeholdTV 609 FM",
4264 .audio_clock = 0x00187de7,
4265 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4266 .radio_type = UNSET,
4267 .tuner_addr = ADDR_UNSET,
4268 .radio_addr = ADDR_UNSET,
4269 .tda9887_conf = TDA9887_PRESENT,
4270 .inputs = {{
4271 .name = name_tv,
4272 .vmux = 3,
4273 .amux = TV,
4274 .tv = 1,
4275 }, {
4276 .name = name_comp1,
4277 .vmux = 1,
4278 .amux = LINE1,
4279 }, {
4280 .name = name_svideo,
4281 .vmux = 8,
4282 .amux = LINE1,
4283 } },
4284 .radio = {
4285 .name = name_radio,
4286 .amux = LINE2,
4287 },
4288 },
4289 [SAA7134_BOARD_BEHOLD_607FM_MK5] = {
4290 /* Andrey Melnikoff <temnota@kmv.ru> */
4291 .name = "Beholder BeholdTV 607 FM",
4292 .audio_clock = 0x00187de7,
4293 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4294 .radio_type = UNSET,
4295 .tuner_addr = ADDR_UNSET,
4296 .radio_addr = ADDR_UNSET,
4297 .tda9887_conf = TDA9887_PRESENT,
4298 .inputs = {{
4299 .name = name_tv,
4300 .vmux = 3,
4301 .amux = TV,
4302 .tv = 1,
4303 }, {
4304 .name = name_comp1,
4305 .vmux = 1,
4306 .amux = LINE1,
4307 }, {
4308 .name = name_svideo,
4309 .vmux = 8,
4310 .amux = LINE1,
4311 } },
4312 .radio = {
4313 .name = name_radio,
4314 .amux = LINE2,
4315 },
4316 },
4317 [SAA7134_BOARD_BEHOLD_609FM_MK5] = {
4105 /* Andrey Melnikoff <temnota@kmv.ru> */ 4318 /* Andrey Melnikoff <temnota@kmv.ru> */
4106 .name = "Beholder BeholdTV 607 / BeholdTV 609", 4319 .name = "Beholder BeholdTV 609 FM",
4320 .audio_clock = 0x00187de7,
4321 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4322 .radio_type = UNSET,
4323 .tuner_addr = ADDR_UNSET,
4324 .radio_addr = ADDR_UNSET,
4325 .tda9887_conf = TDA9887_PRESENT,
4326 .inputs = {{
4327 .name = name_tv,
4328 .vmux = 3,
4329 .amux = TV,
4330 .tv = 1,
4331 }, {
4332 .name = name_comp1,
4333 .vmux = 1,
4334 .amux = LINE1,
4335 }, {
4336 .name = name_svideo,
4337 .vmux = 8,
4338 .amux = LINE1,
4339 } },
4340 .radio = {
4341 .name = name_radio,
4342 .amux = LINE2,
4343 },
4344 },
4345 [SAA7134_BOARD_BEHOLD_607RDS_MK3] = {
4346 /* Andrey Melnikoff <temnota@kmv.ru> */
4347 .name = "Beholder BeholdTV 607 RDS",
4107 .audio_clock = 0x00187de7, 4348 .audio_clock = 0x00187de7,
4108 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 4349 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4109 .radio_type = UNSET, 4350 .radio_type = UNSET,
@@ -4115,6 +4356,90 @@ struct saa7134_board saa7134_boards[] = {
4115 .vmux = 3, 4356 .vmux = 3,
4116 .amux = TV, 4357 .amux = TV,
4117 .tv = 1, 4358 .tv = 1,
4359 }, {
4360 .name = name_comp1,
4361 .vmux = 1,
4362 .amux = LINE1,
4363 }, {
4364 .name = name_svideo,
4365 .vmux = 8,
4366 .amux = LINE1,
4367 } },
4368 .radio = {
4369 .name = name_radio,
4370 .amux = LINE2,
4371 },
4372 },
4373 [SAA7134_BOARD_BEHOLD_609RDS_MK3] = {
4374 /* Andrey Melnikoff <temnota@kmv.ru> */
4375 .name = "Beholder BeholdTV 609 RDS",
4376 .audio_clock = 0x00187de7,
4377 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4378 .radio_type = UNSET,
4379 .tuner_addr = ADDR_UNSET,
4380 .radio_addr = ADDR_UNSET,
4381 .tda9887_conf = TDA9887_PRESENT,
4382 .inputs = {{
4383 .name = name_tv,
4384 .vmux = 3,
4385 .amux = TV,
4386 .tv = 1,
4387 }, {
4388 .name = name_comp1,
4389 .vmux = 1,
4390 .amux = LINE1,
4391 }, {
4392 .name = name_svideo,
4393 .vmux = 8,
4394 .amux = LINE1,
4395 } },
4396 .radio = {
4397 .name = name_radio,
4398 .amux = LINE2,
4399 },
4400 },
4401 [SAA7134_BOARD_BEHOLD_607RDS_MK5] = {
4402 /* Andrey Melnikoff <temnota@kmv.ru> */
4403 .name = "Beholder BeholdTV 607 RDS",
4404 .audio_clock = 0x00187de7,
4405 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4406 .radio_type = UNSET,
4407 .tuner_addr = ADDR_UNSET,
4408 .radio_addr = ADDR_UNSET,
4409 .tda9887_conf = TDA9887_PRESENT,
4410 .inputs = {{
4411 .name = name_tv,
4412 .vmux = 3,
4413 .amux = TV,
4414 .tv = 1,
4415 }, {
4416 .name = name_comp1,
4417 .vmux = 1,
4418 .amux = LINE1,
4419 }, {
4420 .name = name_svideo,
4421 .vmux = 8,
4422 .amux = LINE1,
4423 } },
4424 .radio = {
4425 .name = name_radio,
4426 .amux = LINE2,
4427 },
4428 },
4429 [SAA7134_BOARD_BEHOLD_609RDS_MK5] = {
4430 /* Andrey Melnikoff <temnota@kmv.ru> */
4431 .name = "Beholder BeholdTV 609 RDS",
4432 .audio_clock = 0x00187de7,
4433 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4434 .radio_type = UNSET,
4435 .tuner_addr = ADDR_UNSET,
4436 .radio_addr = ADDR_UNSET,
4437 .tda9887_conf = TDA9887_PRESENT,
4438 .inputs = {{
4439 .name = name_tv,
4440 .vmux = 3,
4441 .amux = TV,
4442 .tv = 1,
4118 },{ 4443 },{
4119 .name = name_comp1, 4444 .name = name_comp1,
4120 .vmux = 1, 4445 .vmux = 1,
@@ -4133,6 +4458,7 @@ struct saa7134_board saa7134_boards[] = {
4133 /* Igor Kuznetsov <igk@igk.ru> */ 4458 /* Igor Kuznetsov <igk@igk.ru> */
4134 /* Andrey Melnikoff <temnota@kmv.ru> */ 4459 /* Andrey Melnikoff <temnota@kmv.ru> */
4135 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ 4460 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
4461 /* Alexey Osipov <lion-simba@pridelands.ru> */
4136 .name = "Beholder BeholdTV M6", 4462 .name = "Beholder BeholdTV M6",
4137 .audio_clock = 0x00187de7, 4463 .audio_clock = 0x00187de7,
4138 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 4464 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
@@ -4207,10 +4533,10 @@ struct saa7134_board saa7134_boards[] = {
4207 /* Igor Kuznetsov <igk@igk.ru> */ 4533 /* Igor Kuznetsov <igk@igk.ru> */
4208 /* Andrey Melnikoff <temnota@kmv.ru> */ 4534 /* Andrey Melnikoff <temnota@kmv.ru> */
4209 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */ 4535 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
4536 /* Alexey Osipov <lion-simba@pridelands.ru> */
4210 .name = "Beholder BeholdTV M6 Extra", 4537 .name = "Beholder BeholdTV M6 Extra",
4211 .audio_clock = 0x00187de7, 4538 .audio_clock = 0x00187de7,
4212 /* FIXME: Must be PHILIPS_FM1216ME_MK5*/ 4539 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
4213 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
4214 .radio_type = UNSET, 4540 .radio_type = UNSET,
4215 .tuner_addr = ADDR_UNSET, 4541 .tuner_addr = ADDR_UNSET,
4216 .radio_addr = ADDR_UNSET, 4542 .radio_addr = ADDR_UNSET,
@@ -4465,7 +4791,6 @@ struct saa7134_board saa7134_boards[] = {
4465 .radio_type = UNSET, 4791 .radio_type = UNSET,
4466 .tuner_addr = ADDR_UNSET, 4792 .tuner_addr = ADDR_UNSET,
4467 .radio_addr = ADDR_UNSET, 4793 .radio_addr = ADDR_UNSET,
4468 .mpeg = SAA7134_MPEG_DVB,
4469 .inputs = {{ 4794 .inputs = {{
4470 .name = name_tv, 4795 .name = name_tv,
4471 .vmux = 3, 4796 .vmux = 3,
@@ -4753,6 +5078,44 @@ struct saa7134_board saa7134_boards[] = {
4753 .gpio = 0x01, 5078 .gpio = 0x01,
4754 }, 5079 },
4755 }, 5080 },
5081 [SAA7134_BOARD_AVERMEDIA_STUDIO_507UA] = {
5082 /* Andy Shevchenko <andy@smile.org.ua> */
5083 .name = "Avermedia AVerTV Studio 507UA",
5084 .audio_clock = 0x00187de7,
5085 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* Should be MK5 */
5086 .radio_type = UNSET,
5087 .tuner_addr = ADDR_UNSET,
5088 .radio_addr = ADDR_UNSET,
5089 .tda9887_conf = TDA9887_PRESENT,
5090 .gpiomask = 0x03,
5091 .inputs = { {
5092 .name = name_tv,
5093 .vmux = 1,
5094 .amux = TV,
5095 .tv = 1,
5096 .gpio = 0x00,
5097 }, {
5098 .name = name_comp1,
5099 .vmux = 3,
5100 .amux = LINE1,
5101 .gpio = 0x00,
5102 }, {
5103 .name = name_svideo,
5104 .vmux = 8,
5105 .amux = LINE1,
5106 .gpio = 0x00,
5107 } },
5108 .radio = {
5109 .name = name_radio,
5110 .amux = LINE2,
5111 .gpio = 0x01,
5112 },
5113 .mute = {
5114 .name = name_mute,
5115 .amux = LINE1,
5116 .gpio = 0x00,
5117 },
5118 },
4756}; 5119};
4757 5120
4758const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 5121const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5027,6 +5390,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
5027 .subdevice = 0xd6ee, 5390 .subdevice = 0xd6ee,
5028 .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS, 5391 .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
5029 },{ 5392 },{
5393 /* AVerMedia CardBus */
5394 .vendor = PCI_VENDOR_ID_PHILIPS,
5395 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5396 .subvendor = 0x1461, /* Avermedia Technologies Inc */
5397 .subdevice = 0xb7e9,
5398 .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501,
5399 }, {
5030 /* TransGear 3000TV */ 5400 /* TransGear 3000TV */
5031 .vendor = PCI_VENDOR_ID_PHILIPS, 5401 .vendor = PCI_VENDOR_ID_PHILIPS,
5032 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 5402 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -5441,6 +5811,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5441 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507, 5811 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507,
5442 },{ 5812 },{
5443 .vendor = PCI_VENDOR_ID_PHILIPS, 5813 .vendor = PCI_VENDOR_ID_PHILIPS,
5814 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5815 .subvendor = 0x1461, /* Avermedia Technologies Inc */
5816 .subdevice = 0xa11b,
5817 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA,
5818 }, {
5819 .vendor = PCI_VENDOR_ID_PHILIPS,
5444 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 5820 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5445 .subvendor = 0x1043, 5821 .subvendor = 0x1043,
5446 .subdevice = 0x4876, 5822 .subdevice = 0x4876,
@@ -5647,14 +6023,8 @@ struct pci_device_id saa7134_pci_tbl[] = {
5647 .vendor = PCI_VENDOR_ID_PHILIPS, 6023 .vendor = PCI_VENDOR_ID_PHILIPS,
5648 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 6024 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
5649 .subvendor = 0x0000, 6025 .subvendor = 0x0000,
5650 .subdevice = 0x5051,
5651 .driver_data = SAA7134_BOARD_BEHOLD_505FM,
5652 },{
5653 .vendor = PCI_VENDOR_ID_PHILIPS,
5654 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
5655 .subvendor = 0x0000,
5656 .subdevice = 0x505B, 6026 .subdevice = 0x505B,
5657 .driver_data = SAA7134_BOARD_BEHOLD_505FM, 6027 .driver_data = SAA7134_BOARD_BEHOLD_505RDS,
5658 },{ 6028 },{
5659 .vendor = PCI_VENDOR_ID_PHILIPS, 6029 .vendor = PCI_VENDOR_ID_PHILIPS,
5660 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 6030 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
@@ -5666,13 +6036,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
5666 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6036 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5667 .subvendor = 0x0000, 6037 .subvendor = 0x0000,
5668 .subdevice = 0x5071, 6038 .subdevice = 0x5071,
5669 .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, 6039 .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3,
5670 },{ 6040 },{
5671 .vendor = PCI_VENDOR_ID_PHILIPS, 6041 .vendor = PCI_VENDOR_ID_PHILIPS,
5672 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6042 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5673 .subvendor = 0x0000, 6043 .subvendor = 0x0000,
5674 .subdevice = 0x507B, 6044 .subdevice = 0x507B,
5675 .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, 6045 .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5,
5676 },{ 6046 },{
5677 .vendor = PCI_VENDOR_ID_PHILIPS, 6047 .vendor = PCI_VENDOR_ID_PHILIPS,
5678 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6048 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5696,49 +6066,49 @@ struct pci_device_id saa7134_pci_tbl[] = {
5696 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6066 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5697 .subvendor = 0x5ace, 6067 .subvendor = 0x5ace,
5698 .subdevice = 0x6070, 6068 .subdevice = 0x6070,
5699 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6069 .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3,
5700 },{ 6070 },{
5701 .vendor = PCI_VENDOR_ID_PHILIPS, 6071 .vendor = PCI_VENDOR_ID_PHILIPS,
5702 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6072 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5703 .subvendor = 0x5ace, 6073 .subvendor = 0x5ace,
5704 .subdevice = 0x6071, 6074 .subdevice = 0x6071,
5705 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6075 .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5,
5706 },{ 6076 },{
5707 .vendor = PCI_VENDOR_ID_PHILIPS, 6077 .vendor = PCI_VENDOR_ID_PHILIPS,
5708 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6078 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5709 .subvendor = 0x5ace, 6079 .subvendor = 0x5ace,
5710 .subdevice = 0x6072, 6080 .subdevice = 0x6072,
5711 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6081 .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3,
5712 },{ 6082 },{
5713 .vendor = PCI_VENDOR_ID_PHILIPS, 6083 .vendor = PCI_VENDOR_ID_PHILIPS,
5714 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6084 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
5715 .subvendor = 0x5ace, 6085 .subvendor = 0x5ace,
5716 .subdevice = 0x6073, 6086 .subdevice = 0x6073,
5717 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6087 .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5,
5718 },{ 6088 },{
5719 .vendor = PCI_VENDOR_ID_PHILIPS, 6089 .vendor = PCI_VENDOR_ID_PHILIPS,
5720 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6090 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5721 .subvendor = 0x5ace, 6091 .subvendor = 0x5ace,
5722 .subdevice = 0x6090, 6092 .subdevice = 0x6090,
5723 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6093 .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3,
5724 },{ 6094 },{
5725 .vendor = PCI_VENDOR_ID_PHILIPS, 6095 .vendor = PCI_VENDOR_ID_PHILIPS,
5726 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6096 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5727 .subvendor = 0x5ace, 6097 .subvendor = 0x5ace,
5728 .subdevice = 0x6091, 6098 .subdevice = 0x6091,
5729 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6099 .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5,
5730 },{ 6100 },{
5731 .vendor = PCI_VENDOR_ID_PHILIPS, 6101 .vendor = PCI_VENDOR_ID_PHILIPS,
5732 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6102 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5733 .subvendor = 0x5ace, 6103 .subvendor = 0x5ace,
5734 .subdevice = 0x6092, 6104 .subdevice = 0x6092,
5735 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6105 .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3,
5736 },{ 6106 },{
5737 .vendor = PCI_VENDOR_ID_PHILIPS, 6107 .vendor = PCI_VENDOR_ID_PHILIPS,
5738 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6108 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5739 .subvendor = 0x5ace, 6109 .subvendor = 0x5ace,
5740 .subdevice = 0x6093, 6110 .subdevice = 0x6093,
5741 .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, 6111 .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5,
5742 },{ 6112 },{
5743 .vendor = PCI_VENDOR_ID_PHILIPS, 6113 .vendor = PCI_VENDOR_ID_PHILIPS,
5744 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6114 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -5832,6 +6202,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5832 }, { 6202 }, {
5833 .vendor = PCI_VENDOR_ID_PHILIPS, 6203 .vendor = PCI_VENDOR_ID_PHILIPS,
5834 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6204 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6205 .subvendor = 0x1461, /* Avermedia Technologies Inc */
6206 .subdevice = 0xf736,
6207 .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
6208 }, {
6209 .vendor = PCI_VENDOR_ID_PHILIPS,
6210 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5835 .subvendor = 0x1043, 6211 .subvendor = 0x1043,
5836 .subdevice = 0x4878, /* REV:1.02G */ 6212 .subdevice = 0x4878, /* REV:1.02G */
5837 .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, 6213 .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1,
@@ -6114,7 +6490,6 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6114 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 6490 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
6115 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 6491 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
6116 case SAA7134_BOARD_VIDEOMATE_DVBT_200A: 6492 case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
6117 case SAA7134_BOARD_VIDEOMATE_T750:
6118 case SAA7134_BOARD_MANLI_MTV001: 6493 case SAA7134_BOARD_MANLI_MTV001:
6119 case SAA7134_BOARD_MANLI_MTV002: 6494 case SAA7134_BOARD_MANLI_MTV002:
6120 case SAA7134_BOARD_BEHOLD_409FM: 6495 case SAA7134_BOARD_BEHOLD_409FM:
@@ -6142,7 +6517,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6142 case SAA7134_BOARD_BEHOLD_407FM: 6517 case SAA7134_BOARD_BEHOLD_407FM:
6143 case SAA7134_BOARD_BEHOLD_409: 6518 case SAA7134_BOARD_BEHOLD_409:
6144 case SAA7134_BOARD_BEHOLD_505FM: 6519 case SAA7134_BOARD_BEHOLD_505FM:
6520 case SAA7134_BOARD_BEHOLD_505RDS:
6145 case SAA7134_BOARD_BEHOLD_507_9FM: 6521 case SAA7134_BOARD_BEHOLD_507_9FM:
6522 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
6523 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
6146 case SAA7134_BOARD_GENIUS_TVGO_A11MCE: 6524 case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
6147 case SAA7134_BOARD_REAL_ANGEL_220: 6525 case SAA7134_BOARD_REAL_ANGEL_220:
6148 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: 6526 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
@@ -6196,6 +6574,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6196 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); 6574 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
6197 msleep(10); 6575 msleep(10);
6198 break; 6576 break;
6577 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
6578 /* power-down tuner chip */
6579 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000);
6580 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0);
6581 msleep(10);
6582 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x08400000, 0x08400000);
6583 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08400000, 0x08400000);
6584 msleep(10);
6585 dev->has_remote = SAA7134_REMOTE_I2C;
6586 break;
6199 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: 6587 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
6200 saa7134_set_gpio(dev, 23, 0); 6588 saa7134_set_gpio(dev, 23, 0);
6201 msleep(10); 6589 msleep(10);
@@ -6253,7 +6641,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6253 case SAA7134_BOARD_UPMOST_PURPLE_TV: 6641 case SAA7134_BOARD_UPMOST_PURPLE_TV:
6254 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 6642 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
6255 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 6643 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
6256 case SAA7134_BOARD_BEHOLD_607_9FM: 6644 case SAA7134_BOARD_BEHOLD_607FM_MK3:
6645 case SAA7134_BOARD_BEHOLD_607FM_MK5:
6646 case SAA7134_BOARD_BEHOLD_609FM_MK3:
6647 case SAA7134_BOARD_BEHOLD_609FM_MK5:
6648 case SAA7134_BOARD_BEHOLD_607RDS_MK3:
6649 case SAA7134_BOARD_BEHOLD_607RDS_MK5:
6650 case SAA7134_BOARD_BEHOLD_609RDS_MK3:
6651 case SAA7134_BOARD_BEHOLD_609RDS_MK5:
6257 case SAA7134_BOARD_BEHOLD_M6: 6652 case SAA7134_BOARD_BEHOLD_M6:
6258 case SAA7134_BOARD_BEHOLD_M63: 6653 case SAA7134_BOARD_BEHOLD_M63:
6259 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 6654 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
@@ -6635,6 +7030,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
6635 7030
6636 switch (dev->board) { 7031 switch (dev->board) {
6637 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: 7032 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
7033 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
6638 { 7034 {
6639 struct v4l2_priv_tun_config tea5767_cfg; 7035 struct v4l2_priv_tun_config tea5767_cfg;
6640 struct tea5767_ctrl ctl; 7036 struct tea5767_ctrl ctl;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 2def6fec814b..94a023a14bbc 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -331,6 +331,10 @@ void saa7134_buffer_next(struct saa7134_dev *dev,
331 dprintk("buffer_next %p\n",NULL); 331 dprintk("buffer_next %p\n",NULL);
332 saa7134_set_dmabits(dev); 332 saa7134_set_dmabits(dev);
333 del_timer(&q->timeout); 333 del_timer(&q->timeout);
334
335 if (card_has_mpeg(dev))
336 if (dev->ts_started)
337 saa7134_ts_stop(dev);
334 } 338 }
335} 339}
336 340
@@ -416,6 +420,19 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
416 ctrl |= SAA7134_MAIN_CTRL_TE5; 420 ctrl |= SAA7134_MAIN_CTRL_TE5;
417 irq |= SAA7134_IRQ1_INTE_RA2_1 | 421 irq |= SAA7134_IRQ1_INTE_RA2_1 |
418 SAA7134_IRQ1_INTE_RA2_0; 422 SAA7134_IRQ1_INTE_RA2_0;
423
424 /* dma: setup channel 5 (= TS) */
425
426 saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
427 saa_writeb(SAA7134_TS_DMA1,
428 ((dev->ts.nr_packets - 1) >> 8) & 0xff);
429 /* TSNOPIT=0, TSCOLAP=0 */
430 saa_writeb(SAA7134_TS_DMA2,
431 (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
432 saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
433 saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
434 SAA7134_RS_CONTROL_ME |
435 (dev->ts.pt_ts.dma >> 12));
419 } 436 }
420 437
421 /* set task conditions + field handling */ 438 /* set task conditions + field handling */
@@ -775,7 +792,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
775 if (NULL == vfd) 792 if (NULL == vfd)
776 return NULL; 793 return NULL;
777 *vfd = *template; 794 *vfd = *template;
778 vfd->minor = -1;
779 vfd->v4l2_dev = &dev->v4l2_dev; 795 vfd->v4l2_dev = &dev->v4l2_dev;
780 vfd->release = video_device_release; 796 vfd->release = video_device_release;
781 vfd->debug = video_debug; 797 vfd->debug = video_debug;
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 4eff1ca8593c..31930f26ffc7 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -48,6 +48,7 @@
48#include "isl6405.h" 48#include "isl6405.h"
49#include "lnbp21.h" 49#include "lnbp21.h"
50#include "tuner-simple.h" 50#include "tuner-simple.h"
51#include "tda10048.h"
51#include "tda18271.h" 52#include "tda18271.h"
52#include "lgdt3305.h" 53#include "lgdt3305.h"
53#include "tda8290.h" 54#include "tda8290.h"
@@ -978,6 +979,18 @@ static struct lgdt3305_config hcw_lgdt3305_config = {
978 .vsb_if_khz = 3250, 979 .vsb_if_khz = 3250,
979}; 980};
980 981
982static struct tda10048_config hcw_tda10048_config = {
983 .demod_address = 0x10 >> 1,
984 .output_mode = TDA10048_SERIAL_OUTPUT,
985 .fwbulkwritelen = TDA10048_BULKWRITE_200,
986 .inversion = TDA10048_INVERSION_ON,
987 .dtv6_if_freq_khz = TDA10048_IF_3300,
988 .dtv7_if_freq_khz = TDA10048_IF_3500,
989 .dtv8_if_freq_khz = TDA10048_IF_4000,
990 .clk_freq_khz = TDA10048_CLK_16000,
991 .disable_gate_access = 1,
992};
993
981static struct tda18271_std_map hauppauge_tda18271_std_map = { 994static struct tda18271_std_map hauppauge_tda18271_std_map = {
982 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, 995 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
983 .if_lvl = 1, .rfagc_top = 0x58, }, 996 .if_lvl = 1, .rfagc_top = 0x58, },
@@ -1106,6 +1119,19 @@ static int dvb_init(struct saa7134_dev *dev)
1106 &tda827x_cfg_2) < 0) 1119 &tda827x_cfg_2) < 0)
1107 goto dettach_frontend; 1120 goto dettach_frontend;
1108 break; 1121 break;
1122 case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
1123 fe0->dvb.frontend = dvb_attach(tda10048_attach,
1124 &hcw_tda10048_config,
1125 &dev->i2c_adap);
1126 if (fe0->dvb.frontend != NULL) {
1127 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1128 &dev->i2c_adap, 0x4b,
1129 &tda829x_no_probe);
1130 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1131 0x60, &dev->i2c_adap,
1132 &hcw_tda18271_config);
1133 }
1134 break;
1109 case SAA7134_BOARD_PHILIPS_TIGER: 1135 case SAA7134_BOARD_PHILIPS_TIGER:
1110 if (configure_tda827x_fe(dev, &philips_tiger_config, 1136 if (configure_tda827x_fe(dev, &philips_tiger_config,
1111 &tda827x_cfg_0) < 0) 1137 &tda827x_cfg_0) < 0)
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 9db3472667e5..add1757f8930 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -255,6 +255,16 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
255 return 0; 255 return 0;
256} 256}
257 257
258static int empress_try_fmt_vid_cap(struct file *file, void *priv,
259 struct v4l2_format *f)
260{
261 struct saa7134_dev *dev = file->private_data;
262
263 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
264 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
265
266 return 0;
267}
258 268
259static int empress_reqbufs(struct file *file, void *priv, 269static int empress_reqbufs(struct file *file, void *priv,
260 struct v4l2_requestbuffers *p) 270 struct v4l2_requestbuffers *p)
@@ -450,6 +460,7 @@ static const struct v4l2_file_operations ts_fops =
450static const struct v4l2_ioctl_ops ts_ioctl_ops = { 460static const struct v4l2_ioctl_ops ts_ioctl_ops = {
451 .vidioc_querycap = empress_querycap, 461 .vidioc_querycap = empress_querycap,
452 .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, 462 .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap,
463 .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap,
453 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, 464 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
454 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, 465 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
455 .vidioc_reqbufs = empress_reqbufs, 466 .vidioc_reqbufs = empress_reqbufs,
@@ -491,11 +502,8 @@ static void empress_signal_update(struct work_struct *work)
491 502
492 if (dev->nosignal) { 503 if (dev->nosignal) {
493 dprintk("no video signal\n"); 504 dprintk("no video signal\n");
494 ts_reset_encoder(dev);
495 } else { 505 } else {
496 dprintk("video signal acquired\n"); 506 dprintk("video signal acquired\n");
497 if (atomic_read(&dev->empress_users))
498 ts_init_encoder(dev);
499 } 507 }
500} 508}
501 509
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index f3e285aa2fb4..8096dace5f6c 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -259,7 +259,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
259 /* workaround for a saa7134 i2c bug 259 /* workaround for a saa7134 i2c bug
260 * needed to talk to the mt352 demux 260 * needed to talk to the mt352 demux
261 * thanks to pinnacle for the hint */ 261 * thanks to pinnacle for the hint */
262 int quirk = 0xfd; 262 int quirk = 0xfe;
263 d1printk(" [%02x quirk]",quirk); 263 d1printk(" [%02x quirk]",quirk);
264 i2c_send_byte(dev,START,quirk); 264 i2c_send_byte(dev,START,quirk);
265 i2c_recv_byte(dev); 265 i2c_recv_byte(dev);
@@ -321,33 +321,6 @@ static u32 functionality(struct i2c_adapter *adap)
321 return I2C_FUNC_SMBUS_EMUL; 321 return I2C_FUNC_SMBUS_EMUL;
322} 322}
323 323
324static int attach_inform(struct i2c_client *client)
325{
326 struct saa7134_dev *dev = client->adapter->algo_data;
327
328 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
329 client->driver->driver.name, client->addr, client->name);
330
331 /* Am I an i2c remote control? */
332
333 switch (client->addr) {
334 case 0x7a:
335 case 0x47:
336 case 0x71:
337 case 0x2d:
338 case 0x30:
339 {
340 struct IR_i2c *ir = i2c_get_clientdata(client);
341 d1printk("%s i2c IR detected (%s).\n",
342 client->driver->driver.name, ir->phys);
343 saa7134_set_i2c_ir(dev,ir);
344 break;
345 }
346 }
347
348 return 0;
349}
350
351static struct i2c_algorithm saa7134_algo = { 324static struct i2c_algorithm saa7134_algo = {
352 .master_xfer = saa7134_i2c_xfer, 325 .master_xfer = saa7134_i2c_xfer,
353 .functionality = functionality, 326 .functionality = functionality,
@@ -358,7 +331,6 @@ static struct i2c_adapter saa7134_adap_template = {
358 .name = "saa7134", 331 .name = "saa7134",
359 .id = I2C_HW_SAA7134, 332 .id = I2C_HW_SAA7134,
360 .algo = &saa7134_algo, 333 .algo = &saa7134_algo,
361 .client_register = attach_inform,
362}; 334};
363 335
364static struct i2c_client saa7134_client_template = { 336static struct i2c_client saa7134_client_template = {
@@ -433,6 +405,9 @@ int saa7134_i2c_register(struct saa7134_dev *dev)
433 saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata)); 405 saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
434 if (i2c_scan) 406 if (i2c_scan)
435 do_i2c_scan(dev->name,&dev->i2c_client); 407 do_i2c_scan(dev->name,&dev->i2c_client);
408
409 /* Instantiate the IR receiver device, if present */
410 saa7134_probe_i2c_ir(dev);
436 return 0; 411 return 0;
437} 412}
438 413
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 8a106d36e723..6e219c2db841 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
60#define dprintk(fmt, arg...) if (ir_debug) \ 60#define dprintk(fmt, arg...) if (ir_debug) \
61 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) 61 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
62#define i2cdprintk(fmt, arg...) if (ir_debug) \ 62#define i2cdprintk(fmt, arg...) if (ir_debug) \
63 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) 63 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
64 64
65/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ 65/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
66static int saa7134_rc5_irq(struct saa7134_dev *dev); 66static int saa7134_rc5_irq(struct saa7134_dev *dev);
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
134 int gpio; 134 int gpio;
135 135
136 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ 136 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
137 struct saa7134_dev *dev = ir->c.adapter->algo_data; 137 struct saa7134_dev *dev = ir->c->adapter->algo_data;
138 if (dev == NULL) { 138 if (dev == NULL) {
139 dprintk("get_key_msi_tvanywhere_plus: " 139 dprintk("get_key_msi_tvanywhere_plus: "
140 "gir->c.adapter->algo_data is NULL!\n"); 140 "gir->c->adapter->algo_data is NULL!\n");
141 return -EIO; 141 return -EIO;
142 } 142 }
143 143
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
156 156
157 /* GPIO says there is a button press. Get it. */ 157 /* GPIO says there is a button press. Get it. */
158 158
159 if (1 != i2c_master_recv(&ir->c, &b, 1)) { 159 if (1 != i2c_master_recv(ir->c, &b, 1)) {
160 i2cdprintk("read error\n"); 160 i2cdprintk("read error\n");
161 return -EIO; 161 return -EIO;
162 } 162 }
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
179 unsigned char b; 179 unsigned char b;
180 180
181 /* poll IR chip */ 181 /* poll IR chip */
182 if (1 != i2c_master_recv(&ir->c,&b,1)) { 182 if (1 != i2c_master_recv(ir->c, &b, 1)) {
183 i2cdprintk("read error\n"); 183 i2cdprintk("read error\n");
184 return -EIO; 184 return -EIO;
185 } 185 }
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
202 unsigned char buf[5], cod4, code3, code4; 202 unsigned char buf[5], cod4, code3, code4;
203 203
204 /* poll IR chip */ 204 /* poll IR chip */
205 if (5 != i2c_master_recv(&ir->c,buf,5)) 205 if (5 != i2c_master_recv(ir->c, buf, 5))
206 return -EIO; 206 return -EIO;
207 207
208 cod4 = buf[4]; 208 cod4 = buf[4];
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
224 unsigned char data[12]; 224 unsigned char data[12];
225 u32 gpio; 225 u32 gpio;
226 226
227 struct saa7134_dev *dev = ir->c.adapter->algo_data; 227 struct saa7134_dev *dev = ir->c->adapter->algo_data;
228 228
229 /* rising SAA7134_GPIO_GPRESCAN reads the status */ 229 /* rising SAA7134_GPIO_GPRESCAN reads the status */
230 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 230 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
235 if (0x400000 & ~gpio) 235 if (0x400000 & ~gpio)
236 return 0; /* No button press */ 236 return 0; /* No button press */
237 237
238 ir->c.addr = 0x5a >> 1; 238 ir->c->addr = 0x5a >> 1;
239 239
240 if (12 != i2c_master_recv(&ir->c, data, 12)) { 240 if (12 != i2c_master_recv(ir->c, data, 12)) {
241 i2cdprintk("read error\n"); 241 i2cdprintk("read error\n");
242 return -EIO; 242 return -EIO;
243 } 243 }
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
267 unsigned int start = 0,parity = 0,code = 0; 267 unsigned int start = 0,parity = 0,code = 0;
268 268
269 /* poll IR chip */ 269 /* poll IR chip */
270 if (4 != i2c_master_recv(&ir->c, b, 4)) { 270 if (4 != i2c_master_recv(ir->c, b, 4)) {
271 i2cdprintk("read error\n"); 271 i2cdprintk("read error\n");
272 return -EIO; 272 return -EIO;
273 } 273 }
@@ -447,6 +447,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
447 case SAA7134_BOARD_AVERMEDIA_STUDIO_305: 447 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
448 case SAA7134_BOARD_AVERMEDIA_STUDIO_307: 448 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
449 case SAA7134_BOARD_AVERMEDIA_STUDIO_507: 449 case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
450 case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
450 case SAA7134_BOARD_AVERMEDIA_GO_007_FM: 451 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
451 case SAA7134_BOARD_AVERMEDIA_M102: 452 case SAA7134_BOARD_AVERMEDIA_M102:
452 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: 453 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
@@ -506,7 +507,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
506 case SAA7134_BOARD_BEHOLD_407FM: 507 case SAA7134_BOARD_BEHOLD_407FM:
507 case SAA7134_BOARD_BEHOLD_409: 508 case SAA7134_BOARD_BEHOLD_409:
508 case SAA7134_BOARD_BEHOLD_505FM: 509 case SAA7134_BOARD_BEHOLD_505FM:
510 case SAA7134_BOARD_BEHOLD_505RDS:
509 case SAA7134_BOARD_BEHOLD_507_9FM: 511 case SAA7134_BOARD_BEHOLD_507_9FM:
512 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
513 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
510 ir_codes = ir_codes_manli; 514 ir_codes = ir_codes_manli;
511 mask_keycode = 0x003f00; 515 mask_keycode = 0x003f00;
512 mask_keyup = 0x004000; 516 mask_keyup = 0x004000;
@@ -678,55 +682,101 @@ void saa7134_input_fini(struct saa7134_dev *dev)
678 dev->remote = NULL; 682 dev->remote = NULL;
679} 683}
680 684
681void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) 685void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
682{ 686{
687 struct i2c_board_info info;
688 struct IR_i2c_init_data init_data;
689 const unsigned short addr_list[] = {
690 0x7a, 0x47, 0x71, 0x2d,
691 I2C_CLIENT_END
692 };
693
694 struct i2c_msg msg_msi = {
695 .addr = 0x50,
696 .flags = I2C_M_RD,
697 .len = 0,
698 .buf = NULL,
699 };
700
701 int rc;
702
683 if (disable_ir) { 703 if (disable_ir) {
684 dprintk("Found supported i2c remote, but IR has been disabled\n"); 704 dprintk("IR has been disabled, not probing for i2c remote\n");
685 ir->get_key=NULL;
686 return; 705 return;
687 } 706 }
688 707
708 memset(&info, 0, sizeof(struct i2c_board_info));
709 memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
710 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
711
689 switch (dev->board) { 712 switch (dev->board) {
690 case SAA7134_BOARD_PINNACLE_PCTV_110i: 713 case SAA7134_BOARD_PINNACLE_PCTV_110i:
691 case SAA7134_BOARD_PINNACLE_PCTV_310i: 714 case SAA7134_BOARD_PINNACLE_PCTV_310i:
692 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); 715 init_data.name = "Pinnacle PCTV";
693 if (pinnacle_remote == 0) { 716 if (pinnacle_remote == 0) {
694 ir->get_key = get_key_pinnacle_color; 717 init_data.get_key = get_key_pinnacle_color;
695 ir->ir_codes = ir_codes_pinnacle_color; 718 init_data.ir_codes = ir_codes_pinnacle_color;
696 } else { 719 } else {
697 ir->get_key = get_key_pinnacle_grey; 720 init_data.get_key = get_key_pinnacle_grey;
698 ir->ir_codes = ir_codes_pinnacle_grey; 721 init_data.ir_codes = ir_codes_pinnacle_grey;
699 } 722 }
700 break; 723 break;
701 case SAA7134_BOARD_UPMOST_PURPLE_TV: 724 case SAA7134_BOARD_UPMOST_PURPLE_TV:
702 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); 725 init_data.name = "Purple TV";
703 ir->get_key = get_key_purpletv; 726 init_data.get_key = get_key_purpletv;
704 ir->ir_codes = ir_codes_purpletv; 727 init_data.ir_codes = ir_codes_purpletv;
705 break; 728 break;
706 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 729 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
707 snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus"); 730 init_data.name = "MSI TV@nywhere Plus";
708 ir->get_key = get_key_msi_tvanywhere_plus; 731 init_data.get_key = get_key_msi_tvanywhere_plus;
709 ir->ir_codes = ir_codes_msi_tvanywhere_plus; 732 init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
733 info.addr = 0x30;
734 /* MSI TV@nywhere Plus controller doesn't seem to
735 respond to probes unless we read something from
736 an existing device. Weird...
737 REVISIT: might no longer be needed */
738 rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
739 dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
740 msg_msi.addr, dev->i2c_adap.name,
741 (1 == rc) ? "yes" : "no");
710 break; 742 break;
711 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 743 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
712 snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); 744 init_data.name = "HVR 1110";
713 ir->get_key = get_key_hvr1110; 745 init_data.get_key = get_key_hvr1110;
714 ir->ir_codes = ir_codes_hauppauge_new; 746 init_data.ir_codes = ir_codes_hauppauge_new;
715 break; 747 break;
716 case SAA7134_BOARD_BEHOLD_607_9FM: 748 case SAA7134_BOARD_BEHOLD_607FM_MK3:
749 case SAA7134_BOARD_BEHOLD_607FM_MK5:
750 case SAA7134_BOARD_BEHOLD_609FM_MK3:
751 case SAA7134_BOARD_BEHOLD_609FM_MK5:
752 case SAA7134_BOARD_BEHOLD_607RDS_MK3:
753 case SAA7134_BOARD_BEHOLD_607RDS_MK5:
754 case SAA7134_BOARD_BEHOLD_609RDS_MK3:
755 case SAA7134_BOARD_BEHOLD_609RDS_MK5:
717 case SAA7134_BOARD_BEHOLD_M6: 756 case SAA7134_BOARD_BEHOLD_M6:
718 case SAA7134_BOARD_BEHOLD_M63: 757 case SAA7134_BOARD_BEHOLD_M63:
719 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 758 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
720 case SAA7134_BOARD_BEHOLD_H6: 759 case SAA7134_BOARD_BEHOLD_H6:
721 snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); 760 init_data.name = "BeholdTV";
722 ir->get_key = get_key_beholdm6xx; 761 init_data.get_key = get_key_beholdm6xx;
723 ir->ir_codes = ir_codes_behold; 762 init_data.ir_codes = ir_codes_behold;
724 break; 763 break;
725 default: 764 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
726 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); 765 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
766 info.addr = 0x40;
727 break; 767 break;
728 } 768 }
729 769
770 if (init_data.name)
771 info.platform_data = &init_data;
772 /* No need to probe if address is known */
773 if (info.addr) {
774 i2c_new_device(&dev->i2c_adap, &info);
775 return;
776 }
777
778 /* Address not known, fallback to probing */
779 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
730} 780}
731 781
732static int saa7134_rc5_irq(struct saa7134_dev *dev) 782static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index cc8b923afbc0..3fa652279ac0 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -65,35 +65,10 @@ static int buffer_activate(struct saa7134_dev *dev,
65 /* start DMA */ 65 /* start DMA */
66 saa7134_set_dmabits(dev); 66 saa7134_set_dmabits(dev);
67 67
68 mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT); 68 mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
69
70 if (dev->ts_state == SAA7134_TS_BUFF_DONE) {
71 /* Clear TS cache */
72 dev->buff_cnt = 0;
73 saa_writeb(SAA7134_TS_SERIAL1, 0x00);
74 saa_writeb(SAA7134_TS_SERIAL1, 0x03);
75 saa_writeb(SAA7134_TS_SERIAL1, 0x00);
76 saa_writeb(SAA7134_TS_SERIAL1, 0x01);
77
78 /* TS clock non-inverted */
79 saa_writeb(SAA7134_TS_SERIAL1, 0x00);
80
81 /* Start TS stream */
82 switch (saa7134_boards[dev->board].ts_type) {
83 case SAA7134_MPEG_TS_PARALLEL:
84 saa_writeb(SAA7134_TS_SERIAL0, 0x40);
85 saa_writeb(SAA7134_TS_PARALLEL, 0xec);
86 break;
87 case SAA7134_MPEG_TS_SERIAL:
88 saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
89 saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
90 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
91 saa_writeb(SAA7134_TS_SERIAL1, 0x02);
92 break;
93 }
94 69
95 dev->ts_state = SAA7134_TS_STARTED; 70 if (!dev->ts_started)
96 } 71 saa7134_ts_start(dev);
97 72
98 return 0; 73 return 0;
99} 74}
@@ -104,7 +79,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
104 struct saa7134_dev *dev = q->priv_data; 79 struct saa7134_dev *dev = q->priv_data;
105 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 80 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
106 unsigned int lines, llength, size; 81 unsigned int lines, llength, size;
107 u32 control;
108 int err; 82 int err;
109 83
110 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); 84 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -121,8 +95,11 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
121 } 95 }
122 96
123 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 97 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
98
124 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 99 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
125 100
101 dprintk("buffer_prepare: needs_init\n");
102
126 buf->vb.width = llength; 103 buf->vb.width = llength;
127 buf->vb.height = lines; 104 buf->vb.height = lines;
128 buf->vb.size = size; 105 buf->vb.size = size;
@@ -139,23 +116,6 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
139 goto oops; 116 goto oops;
140 } 117 }
141 118
142 dev->buff_cnt++;
143
144 if (dev->buff_cnt == dev->ts.nr_bufs) {
145 dev->ts_state = SAA7134_TS_BUFF_DONE;
146 /* dma: setup channel 5 (= TS) */
147 control = SAA7134_RS_CONTROL_BURST_16 |
148 SAA7134_RS_CONTROL_ME |
149 (buf->pt->dma >> 12);
150
151 saa_writeb(SAA7134_TS_DMA0, (lines - 1) & 0xff);
152 saa_writeb(SAA7134_TS_DMA1, ((lines - 1) >> 8) & 0xff);
153 /* TSNOPIT=0, TSCOLAP=0 */
154 saa_writeb(SAA7134_TS_DMA2, (((lines - 1) >> 16) & 0x3f) | 0x00);
155 saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
156 saa_writel(SAA7134_RS_CONTROL(5), control);
157 }
158
159 buf->vb.state = VIDEOBUF_PREPARED; 119 buf->vb.state = VIDEOBUF_PREPARED;
160 buf->activate = buffer_activate; 120 buf->activate = buffer_activate;
161 buf->vb.field = field; 121 buf->vb.field = field;
@@ -175,8 +135,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
175 if (0 == *count) 135 if (0 == *count)
176 *count = dev->ts.nr_bufs; 136 *count = dev->ts.nr_bufs;
177 *count = saa7134_buffer_count(*size,*count); 137 *count = saa7134_buffer_count(*size,*count);
178 dev->buff_cnt = 0; 138
179 dev->ts_state = SAA7134_TS_STOPPED;
180 return 0; 139 return 0;
181} 140}
182 141
@@ -193,11 +152,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
193 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 152 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
194 struct saa7134_dev *dev = q->priv_data; 153 struct saa7134_dev *dev = q->priv_data;
195 154
196 if (dev->ts_state == SAA7134_TS_STARTED) { 155 if (dev->ts_started)
197 /* Stop TS transport */ 156 saa7134_ts_stop(dev);
198 saa_writeb(SAA7134_TS_PARALLEL, 0x6c); 157
199 dev->ts_state = SAA7134_TS_STOPPED;
200 }
201 saa7134_dma_free(q,buf); 158 saa7134_dma_free(q,buf);
202} 159}
203 160
@@ -214,7 +171,7 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
214 171
215static unsigned int tsbufs = 8; 172static unsigned int tsbufs = 8;
216module_param(tsbufs, int, 0444); 173module_param(tsbufs, int, 0444);
217MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); 174MODULE_PARM_DESC(tsbufs, "number of ts buffers for read/write IO, range 2-32");
218 175
219static unsigned int ts_nr_packets = 64; 176static unsigned int ts_nr_packets = 64;
220module_param(ts_nr_packets, int, 0444); 177module_param(ts_nr_packets, int, 0444);
@@ -256,6 +213,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
256 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); 213 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
257 dev->ts_q.dev = dev; 214 dev->ts_q.dev = dev;
258 dev->ts_q.need_two = 1; 215 dev->ts_q.need_two = 1;
216 dev->ts_started = 0;
259 saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); 217 saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
260 218
261 /* init TS hw */ 219 /* init TS hw */
@@ -264,13 +222,67 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
264 return 0; 222 return 0;
265} 223}
266 224
225/* Function for stop TS */
226int saa7134_ts_stop(struct saa7134_dev *dev)
227{
228 dprintk("TS stop\n");
229
230 BUG_ON(!dev->ts_started);
231
232 /* Stop TS stream */
233 switch (saa7134_boards[dev->board].ts_type) {
234 case SAA7134_MPEG_TS_PARALLEL:
235 saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
236 dev->ts_started = 0;
237 break;
238 case SAA7134_MPEG_TS_SERIAL:
239 saa_writeb(SAA7134_TS_SERIAL0, 0x40);
240 dev->ts_started = 0;
241 break;
242 }
243 return 0;
244}
245
246/* Function for start TS */
247int saa7134_ts_start(struct saa7134_dev *dev)
248{
249 dprintk("TS start\n");
250
251 BUG_ON(dev->ts_started);
252
253 saa_writeb(SAA7134_TS_SERIAL1, 0x00);
254 saa_writeb(SAA7134_TS_SERIAL1, 0x03);
255 saa_writeb(SAA7134_TS_SERIAL1, 0x00);
256 saa_writeb(SAA7134_TS_SERIAL1, 0x01);
257
258 /* TS clock non-inverted */
259 saa_writeb(SAA7134_TS_SERIAL1, 0x00);
260
261 /* Start TS stream */
262 switch (saa7134_boards[dev->board].ts_type) {
263 case SAA7134_MPEG_TS_PARALLEL:
264 saa_writeb(SAA7134_TS_SERIAL0, 0x40);
265 saa_writeb(SAA7134_TS_PARALLEL, 0xec);
266 break;
267 case SAA7134_MPEG_TS_SERIAL:
268 saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
269 saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
270 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
271 saa_writeb(SAA7134_TS_SERIAL1, 0x02);
272 break;
273 }
274
275 dev->ts_started = 1;
276
277 return 0;
278}
279
267int saa7134_ts_fini(struct saa7134_dev *dev) 280int saa7134_ts_fini(struct saa7134_dev *dev)
268{ 281{
269 saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); 282 saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
270 return 0; 283 return 0;
271} 284}
272 285
273
274void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) 286void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
275{ 287{
276 enum v4l2_field field; 288 enum v4l2_field field;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 493cad941460..e305c1674cee 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1057,6 +1057,7 @@ static int buffer_prepare(struct videobuf_queue *q,
1057 buf->vb.field = field; 1057 buf->vb.field = field;
1058 buf->fmt = fh->fmt; 1058 buf->fmt = fh->fmt;
1059 buf->pt = &fh->pt_cap; 1059 buf->pt = &fh->pt_cap;
1060 dev->video_q.curr = NULL;
1060 1061
1061 err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); 1062 err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
1062 if (err) 1063 if (err)
@@ -1423,11 +1424,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1423{ 1424{
1424 struct saa7134_fh *fh = file->private_data; 1425 struct saa7134_fh *fh = file->private_data;
1425 struct videobuf_buffer *buf = NULL; 1426 struct videobuf_buffer *buf = NULL;
1427 unsigned int rc = 0;
1426 1428
1427 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) 1429 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1428 return videobuf_poll_stream(file, &fh->vbi, wait); 1430 return videobuf_poll_stream(file, &fh->vbi, wait);
1429 1431
1430 if (res_check(fh,RESOURCE_VIDEO)) { 1432 if (res_check(fh,RESOURCE_VIDEO)) {
1433 mutex_lock(&fh->cap.vb_lock);
1431 if (!list_empty(&fh->cap.stream)) 1434 if (!list_empty(&fh->cap.stream))
1432 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); 1435 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
1433 } else { 1436 } else {
@@ -1446,13 +1449,14 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1446 } 1449 }
1447 1450
1448 if (!buf) 1451 if (!buf)
1449 return POLLERR; 1452 goto err;
1450 1453
1451 poll_wait(file, &buf->done, wait); 1454 poll_wait(file, &buf->done, wait);
1452 if (buf->state == VIDEOBUF_DONE || 1455 if (buf->state == VIDEOBUF_DONE ||
1453 buf->state == VIDEOBUF_ERROR) 1456 buf->state == VIDEOBUF_ERROR)
1454 return POLLIN|POLLRDNORM; 1457 rc = POLLIN|POLLRDNORM;
1455 return 0; 1458 mutex_unlock(&fh->cap.vb_lock);
1459 return rc;
1456 1460
1457err: 1461err:
1458 mutex_unlock(&fh->cap.vb_lock); 1462 mutex_unlock(&fh->cap.vb_lock);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 0cbaf90d4874..82268848f26a 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -252,7 +252,7 @@ struct saa7134_format {
252#define SAA7134_BOARD_BEHOLD_505FM 126 252#define SAA7134_BOARD_BEHOLD_505FM 126
253#define SAA7134_BOARD_BEHOLD_507_9FM 127 253#define SAA7134_BOARD_BEHOLD_507_9FM 127
254#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 254#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128
255#define SAA7134_BOARD_BEHOLD_607_9FM 129 255#define SAA7134_BOARD_BEHOLD_607FM_MK3 129
256#define SAA7134_BOARD_BEHOLD_M6 130 256#define SAA7134_BOARD_BEHOLD_M6 130
257#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 257#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131
258#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 258#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132
@@ -280,6 +280,18 @@ struct saa7134_format {
280#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 280#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
281#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 281#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155
282#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 282#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156
283#define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
284#define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
285#define SAA7134_BOARD_BEHOLD_505RDS 159
286#define SAA7134_BOARD_BEHOLD_507RDS_MK3 160
287#define SAA7134_BOARD_BEHOLD_507RDS_MK5 161
288#define SAA7134_BOARD_BEHOLD_607FM_MK5 162
289#define SAA7134_BOARD_BEHOLD_609FM_MK3 163
290#define SAA7134_BOARD_BEHOLD_609FM_MK5 164
291#define SAA7134_BOARD_BEHOLD_607RDS_MK3 165
292#define SAA7134_BOARD_BEHOLD_607RDS_MK5 166
293#define SAA7134_BOARD_BEHOLD_609RDS_MK3 167
294#define SAA7134_BOARD_BEHOLD_609RDS_MK5 168
283 295
284#define SAA7134_MAXBOARDS 32 296#define SAA7134_MAXBOARDS 32
285#define SAA7134_INPUT_MAX 8 297#define SAA7134_INPUT_MAX 8
@@ -364,6 +376,7 @@ struct saa7134_board {
364#define INTERLACE_OFF 2 376#define INTERLACE_OFF 2
365 377
366#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ 378#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
379#define TS_BUFFER_TIMEOUT msecs_to_jiffies(1000) /* 1 second */
367 380
368struct saa7134_dev; 381struct saa7134_dev;
369struct saa7134_dma; 382struct saa7134_dma;
@@ -480,12 +493,6 @@ struct saa7134_mpeg_ops {
480 void (*signal_change)(struct saa7134_dev *dev); 493 void (*signal_change)(struct saa7134_dev *dev);
481}; 494};
482 495
483enum saa7134_ts_status {
484 SAA7134_TS_STOPPED,
485 SAA7134_TS_BUFF_DONE,
486 SAA7134_TS_STARTED,
487};
488
489/* global device status */ 496/* global device status */
490struct saa7134_dev { 497struct saa7134_dev {
491 struct list_head devlist; 498 struct list_head devlist;
@@ -580,8 +587,7 @@ struct saa7134_dev {
580 /* SAA7134_MPEG_* */ 587 /* SAA7134_MPEG_* */
581 struct saa7134_ts ts; 588 struct saa7134_ts ts;
582 struct saa7134_dmaqueue ts_q; 589 struct saa7134_dmaqueue ts_q;
583 enum saa7134_ts_status ts_state; 590 int ts_started;
584 unsigned int buff_cnt;
585 struct saa7134_mpeg_ops *mops; 591 struct saa7134_mpeg_ops *mops;
586 592
587 /* SAA7134_MPEG_EMPRESS only */ 593 /* SAA7134_MPEG_EMPRESS only */
@@ -739,6 +745,9 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
739 745
740int saa7134_ts_init_hw(struct saa7134_dev *dev); 746int saa7134_ts_init_hw(struct saa7134_dev *dev);
741 747
748int saa7134_ts_start(struct saa7134_dev *dev);
749int saa7134_ts_stop(struct saa7134_dev *dev);
750
742/* ----------------------------------------------------------- */ 751/* ----------------------------------------------------------- */
743/* saa7134-vbi.c */ 752/* saa7134-vbi.c */
744 753
@@ -786,7 +795,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
786int saa7134_input_init1(struct saa7134_dev *dev); 795int saa7134_input_init1(struct saa7134_dev *dev);
787void saa7134_input_fini(struct saa7134_dev *dev); 796void saa7134_input_fini(struct saa7134_dev *dev);
788void saa7134_input_irq(struct saa7134_dev *dev); 797void saa7134_input_irq(struct saa7134_dev *dev);
789void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); 798void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
790void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); 799void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
791void saa7134_ir_stop(struct saa7134_dev *dev); 800void saa7134_ir_stop(struct saa7134_dev *dev);
792 801
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 5990ab38a124..c8f05297d0f0 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -38,7 +38,7 @@ static const char version[] = "0.24";
38static int flickerless; 38static int flickerless;
39static int video_nr = -1; 39static int video_nr = -1;
40 40
41static struct usb_device_id device_table [] = { 41static struct usb_device_id device_table[] = {
42 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */ 42 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
43 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */ 43 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
44 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */ 44 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
@@ -53,7 +53,8 @@ MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
53MODULE_DESCRIPTION("SE401 USB Camera Driver"); 53MODULE_DESCRIPTION("SE401 USB Camera Driver");
54MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
55module_param(flickerless, int, 0); 55module_param(flickerless, int, 0);
56MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)"); 56MODULE_PARM_DESC(flickerless,
57 "Net frequency to adjust exposure time to (0/50/60)");
57module_param(video_nr, int, 0); 58module_param(video_nr, int, 0);
58 59
59static struct usb_driver se401_driver; 60static struct usb_driver se401_driver;
@@ -78,8 +79,8 @@ static void *rvmalloc(unsigned long size)
78 adr = (unsigned long) mem; 79 adr = (unsigned long) mem;
79 while (size > 0) { 80 while (size > 0) {
80 SetPageReserved(vmalloc_to_page((void *)adr)); 81 SetPageReserved(vmalloc_to_page((void *)adr));
81 adr += PAGE_SIZE; 82 adr += PAGE_SIZE;
82 size -= PAGE_SIZE; 83 size -= PAGE_SIZE;
83 } 84 }
84 85
85 return mem; 86 return mem;
@@ -95,8 +96,8 @@ static void rvfree(void *mem, unsigned long size)
95 adr = (unsigned long) mem; 96 adr = (unsigned long) mem;
96 while ((long) size > 0) { 97 while ((long) size > 0) {
97 ClearPageReserved(vmalloc_to_page((void *)adr)); 98 ClearPageReserved(vmalloc_to_page((void *)adr));
98 adr += PAGE_SIZE; 99 adr += PAGE_SIZE;
99 size -= PAGE_SIZE; 100 size -= PAGE_SIZE;
100 } 101 }
101 vfree(mem); 102 vfree(mem);
102} 103}
@@ -112,7 +113,7 @@ static void rvfree(void *mem, unsigned long size)
112static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req, 113static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
113 unsigned short value, unsigned char *cp, int size) 114 unsigned short value, unsigned char *cp, int size)
114{ 115{
115 return usb_control_msg ( 116 return usb_control_msg(
116 se401->dev, 117 se401->dev,
117 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0), 118 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
118 req, 119 req,
@@ -132,7 +133,7 @@ static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
132 and the param in index, but in the logs of the windows driver they do 133 and the param in index, but in the logs of the windows driver they do
133 this the other way around... 134 this the other way around...
134 */ 135 */
135 return usb_control_msg ( 136 return usb_control_msg(
136 se401->dev, 137 se401->dev,
137 usb_sndctrlpipe(se401->dev, 0), 138 usb_sndctrlpipe(se401->dev, 0),
138 SE401_REQ_SET_EXT_FEATURE, 139 SE401_REQ_SET_EXT_FEATURE,
@@ -152,7 +153,7 @@ static unsigned short se401_get_feature(struct usb_se401 *se401,
152 wrong here to.... 153 wrong here to....
153 */ 154 */
154 unsigned char cp[2]; 155 unsigned char cp[2];
155 usb_control_msg ( 156 usb_control_msg(
156 se401->dev, 157 se401->dev,
157 usb_rcvctrlpipe(se401->dev, 0), 158 usb_rcvctrlpipe(se401->dev, 0),
158 SE401_REQ_GET_EXT_FEATURE, 159 SE401_REQ_GET_EXT_FEATURE,
@@ -175,46 +176,51 @@ static unsigned short se401_get_feature(struct usb_se401 *se401,
175 176
176static int se401_send_pict(struct usb_se401 *se401) 177static int se401_send_pict(struct usb_se401 *se401)
177{ 178{
178 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */ 179 /* integration time low */
179 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */ 180 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);
180 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */ 181 /* integration time mid */
181 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */ 182 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);
182 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */ 183 /* integration time mid */
183 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */ 184 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);
184 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */ 185 /* reset level value */
186 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
187 /* red color gain */
188 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);
189 /* green color gain */
190 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);
191 /* blue color gain */
192 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);
185 193
186 return 0; 194 return 0;
187} 195}
188 196
189static void se401_set_exposure(struct usb_se401 *se401, int brightness) 197static void se401_set_exposure(struct usb_se401 *se401, int brightness)
190{ 198{
191 int integration=brightness<<5; 199 int integration = brightness << 5;
192 200
193 if (flickerless==50) { 201 if (flickerless == 50)
194 integration=integration-integration%106667; 202 integration = integration-integration % 106667;
195 } 203 if (flickerless == 60)
196 if (flickerless==60) { 204 integration = integration-integration % 88889;
197 integration=integration-integration%88889; 205 se401->brightness = integration >> 5;
198 } 206 se401->expose_h = (integration >> 16) & 0xff;
199 se401->brightness=integration>>5; 207 se401->expose_m = (integration >> 8) & 0xff;
200 se401->expose_h=(integration>>16)&0xff; 208 se401->expose_l = integration & 0xff;
201 se401->expose_m=(integration>>8)&0xff;
202 se401->expose_l=integration&0xff;
203} 209}
204 210
205static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p) 211static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
206{ 212{
207 p->brightness=se401->brightness; 213 p->brightness = se401->brightness;
208 if (se401->enhance) { 214 if (se401->enhance)
209 p->whiteness=32768; 215 p->whiteness = 32768;
210 } else { 216 else
211 p->whiteness=0; 217 p->whiteness = 0;
212 } 218
213 p->colour=65535; 219 p->colour = 65535;
214 p->contrast=65535; 220 p->contrast = 65535;
215 p->hue=se401->rgain<<10; 221 p->hue = se401->rgain << 10;
216 p->palette=se401->palette; 222 p->palette = se401->palette;
217 p->depth=3; /* rgb24 */ 223 p->depth = 3; /* rgb24 */
218 return 0; 224 return 0;
219} 225}
220 226
@@ -223,20 +229,19 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
223{ 229{
224 if (p->palette != VIDEO_PALETTE_RGB24) 230 if (p->palette != VIDEO_PALETTE_RGB24)
225 return 1; 231 return 1;
226 se401->palette=p->palette; 232 se401->palette = p->palette;
227 if (p->hue!=se401->hue) { 233 if (p->hue != se401->hue) {
228 se401->rgain= p->hue>>10; 234 se401->rgain = p->hue >> 10;
229 se401->bgain= 0x40-(p->hue>>10); 235 se401->bgain = 0x40-(p->hue >> 10);
230 se401->hue=p->hue; 236 se401->hue = p->hue;
231 } 237 }
232 if (p->brightness!=se401->brightness) { 238 if (p->brightness != se401->brightness)
233 se401_set_exposure(se401, p->brightness); 239 se401_set_exposure(se401, p->brightness);
234 } 240
235 if (p->whiteness>=32768) { 241 if (p->whiteness >= 32768)
236 se401->enhance=1; 242 se401->enhance = 1;
237 } else { 243 else
238 se401->enhance=0; 244 se401->enhance = 0;
239 }
240 se401_send_pict(se401); 245 se401_send_pict(se401);
241 se401_send_pict(se401); 246 se401_send_pict(se401);
242 return 0; 247 return 0;
@@ -249,7 +254,7 @@ static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
249static void se401_auto_resetlevel(struct usb_se401 *se401) 254static void se401_auto_resetlevel(struct usb_se401 *se401)
250{ 255{
251 unsigned int ahrc, alrc; 256 unsigned int ahrc, alrc;
252 int oldreset=se401->resetlevel; 257 int oldreset = se401->resetlevel;
253 258
254 /* For some reason this normally read-only register doesn't get reset 259 /* For some reason this normally read-only register doesn't get reset
255 to zero after reading them just once... 260 to zero after reading them just once...
@@ -258,24 +263,24 @@ static void se401_auto_resetlevel(struct usb_se401 *se401)
258 se401_get_feature(se401, HV7131_REG_HIREFNOL); 263 se401_get_feature(se401, HV7131_REG_HIREFNOL);
259 se401_get_feature(se401, HV7131_REG_LOREFNOH); 264 se401_get_feature(se401, HV7131_REG_LOREFNOH);
260 se401_get_feature(se401, HV7131_REG_LOREFNOL); 265 se401_get_feature(se401, HV7131_REG_LOREFNOL);
261 ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) + 266 ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
262 se401_get_feature(se401, HV7131_REG_HIREFNOL); 267 se401_get_feature(se401, HV7131_REG_HIREFNOL);
263 alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) + 268 alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
264 se401_get_feature(se401, HV7131_REG_LOREFNOL); 269 se401_get_feature(se401, HV7131_REG_LOREFNOL);
265 270
266 /* Not an exact science, but it seems to work pretty well... */ 271 /* Not an exact science, but it seems to work pretty well... */
267 if (alrc > 10) { 272 if (alrc > 10) {
268 while (alrc>=10 && se401->resetlevel < 63) { 273 while (alrc >= 10 && se401->resetlevel < 63) {
269 se401->resetlevel++; 274 se401->resetlevel++;
270 alrc /=2; 275 alrc /= 2;
271 } 276 }
272 } else if (ahrc > 20) { 277 } else if (ahrc > 20) {
273 while (ahrc>=20 && se401->resetlevel > 0) { 278 while (ahrc >= 20 && se401->resetlevel > 0) {
274 se401->resetlevel--; 279 se401->resetlevel--;
275 ahrc /=2; 280 ahrc /= 2;
276 } 281 }
277 } 282 }
278 if (se401->resetlevel!=oldreset) 283 if (se401->resetlevel != oldreset)
279 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel); 284 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
280 285
281 return; 286 return;
@@ -300,21 +305,22 @@ static void se401_button_irq(struct urb *urb)
300 case -ENOENT: 305 case -ENOENT:
301 case -ESHUTDOWN: 306 case -ESHUTDOWN:
302 /* this urb is terminated, clean up */ 307 /* this urb is terminated, clean up */
303 dbg("%s - urb shutting down with status: %d", __func__, urb->status); 308 dbg("%s - urb shutting down with status: %d",
309 __func__, urb->status);
304 return; 310 return;
305 default: 311 default:
306 dbg("%s - nonzero urb status received: %d", __func__, urb->status); 312 dbg("%s - nonzero urb status received: %d",
313 __func__, urb->status);
307 goto exit; 314 goto exit;
308 } 315 }
309 316
310 if (urb->actual_length >=2) { 317 if (urb->actual_length >= 2)
311 if (se401->button) 318 if (se401->button)
312 se401->buttonpressed=1; 319 se401->buttonpressed = 1;
313 }
314exit: 320exit:
315 status = usb_submit_urb (urb, GFP_ATOMIC); 321 status = usb_submit_urb(urb, GFP_ATOMIC);
316 if (status) 322 if (status)
317 err ("%s - usb_submit_urb failed with result %d", 323 err("%s - usb_submit_urb failed with result %d",
318 __func__, status); 324 __func__, status);
319} 325}
320 326
@@ -336,55 +342,52 @@ static void se401_video_irq(struct urb *urb)
336 keeps sending them forever... 342 keeps sending them forever...
337 */ 343 */
338 if (length && !urb->status) { 344 if (length && !urb->status) {
339 se401->nullpackets=0; 345 se401->nullpackets = 0;
340 switch(se401->scratch[se401->scratch_next].state) { 346 switch (se401->scratch[se401->scratch_next].state) {
341 case BUFFER_READY: 347 case BUFFER_READY:
342 case BUFFER_BUSY: { 348 case BUFFER_BUSY:
343 se401->dropped++; 349 se401->dropped++;
344 break; 350 break;
345 } 351 case BUFFER_UNUSED:
346 case BUFFER_UNUSED: { 352 memcpy(se401->scratch[se401->scratch_next].data,
347 memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length); 353 (unsigned char *)urb->transfer_buffer, length);
348 se401->scratch[se401->scratch_next].state=BUFFER_READY; 354 se401->scratch[se401->scratch_next].state
349 se401->scratch[se401->scratch_next].offset=se401->bayeroffset; 355 = BUFFER_READY;
350 se401->scratch[se401->scratch_next].length=length; 356 se401->scratch[se401->scratch_next].offset
351 if (waitqueue_active(&se401->wq)) { 357 = se401->bayeroffset;
352 wake_up_interruptible(&se401->wq); 358 se401->scratch[se401->scratch_next].length = length;
353 } 359 if (waitqueue_active(&se401->wq))
354 se401->scratch_overflow=0; 360 wake_up_interruptible(&se401->wq);
355 se401->scratch_next++; 361 se401->scratch_overflow = 0;
356 if (se401->scratch_next>=SE401_NUMSCRATCH) 362 se401->scratch_next++;
357 se401->scratch_next=0; 363 if (se401->scratch_next >= SE401_NUMSCRATCH)
358 break; 364 se401->scratch_next = 0;
359 } 365 break;
360 }
361 se401->bayeroffset+=length;
362 if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
363 se401->bayeroffset=0;
364 } 366 }
367 se401->bayeroffset += length;
368 if (se401->bayeroffset >= se401->cheight * se401->cwidth)
369 se401->bayeroffset = 0;
365 } else { 370 } else {
366 se401->nullpackets++; 371 se401->nullpackets++;
367 if (se401->nullpackets > SE401_MAX_NULLPACKETS) { 372 if (se401->nullpackets > SE401_MAX_NULLPACKETS)
368 if (waitqueue_active(&se401->wq)) { 373 if (waitqueue_active(&se401->wq))
369 wake_up_interruptible(&se401->wq); 374 wake_up_interruptible(&se401->wq);
370 }
371 }
372 } 375 }
373 376
374 /* Resubmit urb for new data */ 377 /* Resubmit urb for new data */
375 urb->status=0; 378 urb->status = 0;
376 urb->dev=se401->dev; 379 urb->dev = se401->dev;
377 if(usb_submit_urb(urb, GFP_KERNEL)) 380 if (usb_submit_urb(urb, GFP_KERNEL))
378 dev_info(&urb->dev->dev, "urb burned down\n"); 381 dev_info(&urb->dev->dev, "urb burned down\n");
379 return; 382 return;
380} 383}
381 384
382static void se401_send_size(struct usb_se401 *se401, int width, int height) 385static void se401_send_size(struct usb_se401 *se401, int width, int height)
383{ 386{
384 int i=0; 387 int i = 0;
385 int mode=0x03; /* No compression */ 388 int mode = 0x03; /* No compression */
386 int sendheight=height; 389 int sendheight = height;
387 int sendwidth=width; 390 int sendwidth = width;
388 391
389 /* JangGu compression can only be used with the camera supported sizes, 392 /* JangGu compression can only be used with the camera supported sizes,
390 but bayer seems to work with any size that fits on the sensor. 393 but bayer seems to work with any size that fits on the sensor.
@@ -392,18 +395,21 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height)
392 4 or 16 times subcapturing, if not we use uncompressed bayer data 395 4 or 16 times subcapturing, if not we use uncompressed bayer data
393 but this will result in cutouts of the maximum size.... 396 but this will result in cutouts of the maximum size....
394 */ 397 */
395 while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height)) 398 while (i < se401->sizes && !(se401->width[i] == width &&
399 se401->height[i] == height))
396 i++; 400 i++;
397 while (i<se401->sizes) { 401 while (i < se401->sizes) {
398 if (se401->width[i]==width*2 && se401->height[i]==height*2) { 402 if (se401->width[i] == width * 2 &&
399 sendheight=se401->height[i]; 403 se401->height[i] == height * 2) {
400 sendwidth=se401->width[i]; 404 sendheight = se401->height[i];
401 mode=0x40; 405 sendwidth = se401->width[i];
406 mode = 0x40;
402 } 407 }
403 if (se401->width[i]==width*4 && se401->height[i]==height*4) { 408 if (se401->width[i] == width * 4 &&
404 sendheight=se401->height[i]; 409 se401->height[i] == height * 4) {
405 sendwidth=se401->width[i]; 410 sendheight = se401->height[i];
406 mode=0x42; 411 sendwidth = se401->width[i];
412 mode = 0x42;
407 } 413 }
408 i++; 414 i++;
409 } 415 }
@@ -412,13 +418,10 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height)
412 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0); 418 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
413 se401_set_feature(se401, SE401_OPERATINGMODE, mode); 419 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
414 420
415 if (mode==0x03) { 421 if (mode == 0x03)
416 se401->format=FMT_BAYER; 422 se401->format = FMT_BAYER;
417 } else { 423 else
418 se401->format=FMT_JANGGU; 424 se401->format = FMT_JANGGU;
419 }
420
421 return;
422} 425}
423 426
424/* 427/*
@@ -429,29 +432,31 @@ static void se401_send_size(struct usb_se401 *se401, int width, int height)
429static int se401_start_stream(struct usb_se401 *se401) 432static int se401_start_stream(struct usb_se401 *se401)
430{ 433{
431 struct urb *urb; 434 struct urb *urb;
432 int err=0, i; 435 int err = 0, i;
433 se401->streaming=1; 436 se401->streaming = 1;
434 437
435 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); 438 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
436 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); 439 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
437 440
438 /* Set picture settings */ 441 /* Set picture settings */
439 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */ 442 /* windowed + pix intg */
443 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);
440 se401_send_pict(se401); 444 se401_send_pict(se401);
441 445
442 se401_send_size(se401, se401->cwidth, se401->cheight); 446 se401_send_size(se401, se401->cwidth, se401->cheight);
443 447
444 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0); 448 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE,
449 0, NULL, 0);
445 450
446 /* Do some memory allocation */ 451 /* Do some memory allocation */
447 for (i=0; i<SE401_NUMFRAMES; i++) { 452 for (i = 0; i < SE401_NUMFRAMES; i++) {
448 se401->frame[i].data=se401->fbuf + i * se401->maxframesize; 453 se401->frame[i].data = se401->fbuf + i * se401->maxframesize;
449 se401->frame[i].curpix=0; 454 se401->frame[i].curpix = 0;
450 } 455 }
451 for (i=0; i<SE401_NUMSBUF; i++) { 456 for (i = 0; i < SE401_NUMSBUF; i++) {
452 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); 457 se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
453 if (!se401->sbuf[i].data) { 458 if (!se401->sbuf[i].data) {
454 for(i = i - 1; i >= 0; i--) { 459 for (i = i - 1; i >= 0; i--) {
455 kfree(se401->sbuf[i].data); 460 kfree(se401->sbuf[i].data);
456 se401->sbuf[i].data = NULL; 461 se401->sbuf[i].data = NULL;
457 } 462 }
@@ -459,26 +464,26 @@ static int se401_start_stream(struct usb_se401 *se401)
459 } 464 }
460 } 465 }
461 466
462 se401->bayeroffset=0; 467 se401->bayeroffset = 0;
463 se401->scratch_next=0; 468 se401->scratch_next = 0;
464 se401->scratch_use=0; 469 se401->scratch_use = 0;
465 se401->scratch_overflow=0; 470 se401->scratch_overflow = 0;
466 for (i=0; i<SE401_NUMSCRATCH; i++) { 471 for (i = 0; i < SE401_NUMSCRATCH; i++) {
467 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL); 472 se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
468 if (!se401->scratch[i].data) { 473 if (!se401->scratch[i].data) {
469 for(i = i - 1; i >= 0; i--) { 474 for (i = i - 1; i >= 0; i--) {
470 kfree(se401->scratch[i].data); 475 kfree(se401->scratch[i].data);
471 se401->scratch[i].data = NULL; 476 se401->scratch[i].data = NULL;
472 } 477 }
473 goto nomem_sbuf; 478 goto nomem_sbuf;
474 } 479 }
475 se401->scratch[i].state=BUFFER_UNUSED; 480 se401->scratch[i].state = BUFFER_UNUSED;
476 } 481 }
477 482
478 for (i=0; i<SE401_NUMSBUF; i++) { 483 for (i = 0; i < SE401_NUMSBUF; i++) {
479 urb=usb_alloc_urb(0, GFP_KERNEL); 484 urb = usb_alloc_urb(0, GFP_KERNEL);
480 if(!urb) { 485 if (!urb) {
481 for(i = i - 1; i >= 0; i--) { 486 for (i = i - 1; i >= 0; i--) {
482 usb_kill_urb(se401->urb[i]); 487 usb_kill_urb(se401->urb[i]);
483 usb_free_urb(se401->urb[i]); 488 usb_free_urb(se401->urb[i]);
484 se401->urb[i] = NULL; 489 se401->urb[i] = NULL;
@@ -492,24 +497,24 @@ static int se401_start_stream(struct usb_se401 *se401)
492 se401_video_irq, 497 se401_video_irq,
493 se401); 498 se401);
494 499
495 se401->urb[i]=urb; 500 se401->urb[i] = urb;
496 501
497 err=usb_submit_urb(se401->urb[i], GFP_KERNEL); 502 err = usb_submit_urb(se401->urb[i], GFP_KERNEL);
498 if(err) 503 if (err)
499 err("urb burned down"); 504 err("urb burned down");
500 } 505 }
501 506
502 se401->framecount=0; 507 se401->framecount = 0;
503 508
504 return 0; 509 return 0;
505 510
506 nomem_scratch: 511 nomem_scratch:
507 for (i=0; i<SE401_NUMSCRATCH; i++) { 512 for (i = 0; i < SE401_NUMSCRATCH; i++) {
508 kfree(se401->scratch[i].data); 513 kfree(se401->scratch[i].data);
509 se401->scratch[i].data = NULL; 514 se401->scratch[i].data = NULL;
510 } 515 }
511 nomem_sbuf: 516 nomem_sbuf:
512 for (i=0; i<SE401_NUMSBUF; i++) { 517 for (i = 0; i < SE401_NUMSBUF; i++) {
513 kfree(se401->sbuf[i].data); 518 kfree(se401->sbuf[i].data);
514 se401->sbuf[i].data = NULL; 519 se401->sbuf[i].data = NULL;
515 } 520 }
@@ -523,22 +528,23 @@ static int se401_stop_stream(struct usb_se401 *se401)
523 if (!se401->streaming || !se401->dev) 528 if (!se401->streaming || !se401->dev)
524 return 1; 529 return 1;
525 530
526 se401->streaming=0; 531 se401->streaming = 0;
527 532
528 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0); 533 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
529 534
530 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0); 535 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
531 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0); 536 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
532 537
533 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) { 538 for (i = 0; i < SE401_NUMSBUF; i++)
534 usb_kill_urb(se401->urb[i]); 539 if (se401->urb[i]) {
535 usb_free_urb(se401->urb[i]); 540 usb_kill_urb(se401->urb[i]);
536 se401->urb[i]=NULL; 541 usb_free_urb(se401->urb[i]);
537 kfree(se401->sbuf[i].data); 542 se401->urb[i] = NULL;
538 } 543 kfree(se401->sbuf[i].data);
539 for (i=0; i<SE401_NUMSCRATCH; i++) { 544 }
545 for (i = 0; i < SE401_NUMSCRATCH; i++) {
540 kfree(se401->scratch[i].data); 546 kfree(se401->scratch[i].data);
541 se401->scratch[i].data=NULL; 547 se401->scratch[i].data = NULL;
542 } 548 }
543 549
544 return 0; 550 return 0;
@@ -546,9 +552,9 @@ static int se401_stop_stream(struct usb_se401 *se401)
546 552
547static int se401_set_size(struct usb_se401 *se401, int width, int height) 553static int se401_set_size(struct usb_se401 *se401, int width, int height)
548{ 554{
549 int wasstreaming=se401->streaming; 555 int wasstreaming = se401->streaming;
550 /* Check to see if we need to change */ 556 /* Check to see if we need to change */
551 if (se401->cwidth==width && se401->cheight==height) 557 if (se401->cwidth == width && se401->cheight == height)
552 return 0; 558 return 0;
553 559
554 /* Check for a valid mode */ 560 /* Check for a valid mode */
@@ -556,16 +562,16 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height)
556 return 1; 562 return 1;
557 if ((width & 1) || (height & 1)) 563 if ((width & 1) || (height & 1))
558 return 1; 564 return 1;
559 if (width>se401->width[se401->sizes-1]) 565 if (width > se401->width[se401->sizes-1])
560 return 1; 566 return 1;
561 if (height>se401->height[se401->sizes-1]) 567 if (height > se401->height[se401->sizes-1])
562 return 1; 568 return 1;
563 569
564 /* Stop a current stream and start it again at the new size */ 570 /* Stop a current stream and start it again at the new size */
565 if (wasstreaming) 571 if (wasstreaming)
566 se401_stop_stream(se401); 572 se401_stop_stream(se401);
567 se401->cwidth=width; 573 se401->cwidth = width;
568 se401->cheight=height; 574 se401->cheight = height;
569 if (wasstreaming) 575 if (wasstreaming)
570 se401_start_stream(se401); 576 se401_start_stream(se401);
571 return 0; 577 return 0;
@@ -586,68 +592,68 @@ static int se401_set_size(struct usb_se401 *se401, int width, int height)
586static inline void enhance_picture(unsigned char *frame, int len) 592static inline void enhance_picture(unsigned char *frame, int len)
587{ 593{
588 while (len--) { 594 while (len--) {
589 *frame=(((*frame^255)*(*frame^255))/255)^255; 595 *frame = (((*frame^255)*(*frame^255))/255)^255;
590 frame++; 596 frame++;
591 } 597 }
592} 598}
593 599
594static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data) 600static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
595{ 601{
596 struct se401_frame *frame=&se401->frame[se401->curframe]; 602 struct se401_frame *frame = &se401->frame[se401->curframe];
597 int linelength=se401->cwidth*3; 603 int linelength = se401->cwidth * 3;
598 604
599 if (frame->curlinepix >= linelength) { 605 if (frame->curlinepix >= linelength) {
600 frame->curlinepix=0; 606 frame->curlinepix = 0;
601 frame->curline+=linelength; 607 frame->curline += linelength;
602 } 608 }
603 609
604 /* First three are absolute, all others relative. 610 /* First three are absolute, all others relative.
605 * Format is rgb from right to left (mirrorred image), 611 * Format is rgb from right to left (mirrorred image),
606 * we flip it to get bgr from left to right. */ 612 * we flip it to get bgr from left to right. */
607 if (frame->curlinepix < 3) { 613 if (frame->curlinepix < 3)
608 *(frame->curline-frame->curlinepix)=1+data*4; 614 *(frame->curline-frame->curlinepix) = 1 + data * 4;
609 } else { 615 else
610 *(frame->curline-frame->curlinepix)= 616 *(frame->curline-frame->curlinepix) =
611 *(frame->curline-frame->curlinepix+3)+data*4; 617 *(frame->curline-frame->curlinepix + 3) + data * 4;
612 }
613 frame->curlinepix++; 618 frame->curlinepix++;
614} 619}
615 620
616static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength) 621static inline void decode_JangGu_vlc(struct usb_se401 *se401,
622 unsigned char *data, int bit_exp, int packetlength)
617{ 623{
618 int pos=0; 624 int pos = 0;
619 int vlc_cod=0; 625 int vlc_cod = 0;
620 int vlc_size=0; 626 int vlc_size = 0;
621 int vlc_data=0; 627 int vlc_data = 0;
622 int bit_cur; 628 int bit_cur;
623 int bit; 629 int bit;
624 data+=4; 630 data += 4;
625 while (pos < packetlength) { 631 while (pos < packetlength) {
626 bit_cur=8; 632 bit_cur = 8;
627 while (bit_cur && bit_exp) { 633 while (bit_cur && bit_exp) {
628 bit=((*data)>>(bit_cur-1))&1; 634 bit = ((*data) >> (bit_cur-1))&1;
629 if (!vlc_cod) { 635 if (!vlc_cod) {
630 if (bit) { 636 if (bit) {
631 vlc_size++; 637 vlc_size++;
632 } else { 638 } else {
633 if (!vlc_size) { 639 if (!vlc_size)
634 decode_JangGu_integrate(se401, 0); 640 decode_JangGu_integrate(se401, 0);
635 } else { 641 else {
636 vlc_cod=2; 642 vlc_cod = 2;
637 vlc_data=0; 643 vlc_data = 0;
638 } 644 }
639 } 645 }
640 } else { 646 } else {
641 if (vlc_cod==2) { 647 if (vlc_cod == 2) {
642 if (!bit) 648 if (!bit)
643 vlc_data = -(1<<vlc_size) + 1; 649 vlc_data = -(1 << vlc_size) + 1;
644 vlc_cod--; 650 vlc_cod--;
645 } 651 }
646 vlc_size--; 652 vlc_size--;
647 vlc_data+=bit<<vlc_size; 653 vlc_data += bit << vlc_size;
648 if (!vlc_size) { 654 if (!vlc_size) {
649 decode_JangGu_integrate(se401, vlc_data); 655 decode_JangGu_integrate(se401, vlc_data);
650 vlc_cod=0; 656 vlc_cod = 0;
651 } 657 }
652 } 658 }
653 bit_cur--; 659 bit_cur--;
@@ -658,186 +664,188 @@ static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *da
658 } 664 }
659} 665}
660 666
661static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer) 667static inline void decode_JangGu(struct usb_se401 *se401,
668 struct se401_scratch *buffer)
662{ 669{
663 unsigned char *data=buffer->data; 670 unsigned char *data = buffer->data;
664 int len=buffer->length; 671 int len = buffer->length;
665 int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size; 672 int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size;
666 int datapos=0; 673 int datapos = 0;
667 674
668 /* New image? */ 675 /* New image? */
669 if (!se401->frame[se401->curframe].curpix) { 676 if (!se401->frame[se401->curframe].curpix) {
670 se401->frame[se401->curframe].curlinepix=0; 677 se401->frame[se401->curframe].curlinepix = 0;
671 se401->frame[se401->curframe].curline= 678 se401->frame[se401->curframe].curline =
672 se401->frame[se401->curframe].data+ 679 se401->frame[se401->curframe].data+
673 se401->cwidth*3-1; 680 se401->cwidth * 3 - 1;
674 if (se401->frame[se401->curframe].grabstate==FRAME_READY) 681 if (se401->frame[se401->curframe].grabstate == FRAME_READY)
675 se401->frame[se401->curframe].grabstate=FRAME_GRABBING; 682 se401->frame[se401->curframe].grabstate = FRAME_GRABBING;
676 se401->vlcdatapos=0; 683 se401->vlcdatapos = 0;
677 } 684 }
678 while (datapos < len) { 685 while (datapos < len) {
679 size=1024-se401->vlcdatapos; 686 size = 1024 - se401->vlcdatapos;
680 if (size+datapos > len) 687 if (size+datapos > len)
681 size=len-datapos; 688 size = len-datapos;
682 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size); 689 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
683 se401->vlcdatapos+=size; 690 se401->vlcdatapos += size;
684 packetlength=0; 691 packetlength = 0;
685 if (se401->vlcdatapos >= 4) { 692 if (se401->vlcdatapos >= 4) {
686 bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8); 693 bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8);
687 pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8); 694 pix_exp = se401->vlcdata[1] +
688 frameinfo=se401->vlcdata[0]&0xc0; 695 ((se401->vlcdata[0] & 0x3f) << 8);
689 packetlength=((bit_exp+47)>>4)<<1; 696 frameinfo = se401->vlcdata[0] & 0xc0;
697 packetlength = ((bit_exp + 47) >> 4) << 1;
690 if (packetlength > 1024) { 698 if (packetlength > 1024) {
691 se401->vlcdatapos=0; 699 se401->vlcdatapos = 0;
692 datapos=len; 700 datapos = len;
693 packetlength=0; 701 packetlength = 0;
694 se401->error++; 702 se401->error++;
695 se401->frame[se401->curframe].curpix=0; 703 se401->frame[se401->curframe].curpix = 0;
696 } 704 }
697 } 705 }
698 if (packetlength && se401->vlcdatapos >= packetlength) { 706 if (packetlength && se401->vlcdatapos >= packetlength) {
699 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength); 707 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp,
700 se401->frame[se401->curframe].curpix+=pix_exp*3; 708 packetlength);
701 datapos+=size-(se401->vlcdatapos-packetlength); 709 se401->frame[se401->curframe].curpix += pix_exp * 3;
702 se401->vlcdatapos=0; 710 datapos += size-(se401->vlcdatapos-packetlength);
703 if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) { 711 se401->vlcdatapos = 0;
704 if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) { 712 if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) {
705 if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) { 713 if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) {
706 se401->frame[se401->curframe].grabstate=FRAME_DONE; 714 if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) {
715 se401->frame[se401->curframe].grabstate = FRAME_DONE;
707 se401->framecount++; 716 se401->framecount++;
708 se401->readcount++; 717 se401->readcount++;
709 } 718 }
710 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) { 719 if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY)
711 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1); 720 se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1);
712 } 721 } else
713 } else {
714 se401->error++; 722 se401->error++;
715 } 723 se401->frame[se401->curframe].curpix = 0;
716 se401->frame[se401->curframe].curpix=0; 724 datapos = len;
717 datapos=len;
718 } 725 }
719 } else { 726 } else
720 datapos+=size; 727 datapos += size;
721 }
722 } 728 }
723} 729}
724 730
725static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer) 731static inline void decode_bayer(struct usb_se401 *se401,
732 struct se401_scratch *buffer)
726{ 733{
727 unsigned char *data=buffer->data; 734 unsigned char *data = buffer->data;
728 int len=buffer->length; 735 int len = buffer->length;
729 int offset=buffer->offset; 736 int offset = buffer->offset;
730 int datasize=se401->cwidth*se401->cheight; 737 int datasize = se401->cwidth * se401->cheight;
731 struct se401_frame *frame=&se401->frame[se401->curframe]; 738 struct se401_frame *frame = &se401->frame[se401->curframe];
739 unsigned char *framedata = frame->data, *curline, *nextline;
740 int width = se401->cwidth;
741 int blineoffset = 0, bline;
742 int linelength = width * 3, i;
732 743
733 unsigned char *framedata=frame->data, *curline, *nextline;
734 int width=se401->cwidth;
735 int blineoffset=0, bline;
736 int linelength=width*3, i;
737 744
745 if (frame->curpix == 0) {
746 if (frame->grabstate == FRAME_READY)
747 frame->grabstate = FRAME_GRABBING;
738 748
739 if (frame->curpix==0) { 749 frame->curline = framedata + linelength;
740 if (frame->grabstate==FRAME_READY) { 750 frame->curlinepix = 0;
741 frame->grabstate=FRAME_GRABBING;
742 }
743 frame->curline=framedata+linelength;
744 frame->curlinepix=0;
745 } 751 }
746 752
747 if (offset!=frame->curpix) { 753 if (offset != frame->curpix) {
748 /* Regard frame as lost :( */ 754 /* Regard frame as lost :( */
749 frame->curpix=0; 755 frame->curpix = 0;
750 se401->error++; 756 se401->error++;
751 return; 757 return;
752 } 758 }
753 759
754 /* Check if we have to much data */ 760 /* Check if we have to much data */
755 if (frame->curpix+len > datasize) { 761 if (frame->curpix + len > datasize)
756 len=datasize-frame->curpix; 762 len = datasize-frame->curpix;
757 } 763
758 if (se401->cheight%4) 764 if (se401->cheight % 4)
759 blineoffset=1; 765 blineoffset = 1;
760 bline=frame->curpix/se401->cwidth+blineoffset; 766 bline = frame->curpix / se401->cwidth+blineoffset;
761 767
762 curline=frame->curline; 768 curline = frame->curline;
763 nextline=curline+linelength; 769 nextline = curline + linelength;
764 if (nextline >= framedata+datasize*3) 770 if (nextline >= framedata+datasize * 3)
765 nextline=curline; 771 nextline = curline;
766 while (len) { 772 while (len) {
767 if (frame->curlinepix>=width) { 773 if (frame->curlinepix >= width) {
768 frame->curlinepix-=width; 774 frame->curlinepix -= width;
769 bline=frame->curpix/width+blineoffset; 775 bline = frame->curpix / width + blineoffset;
770 curline+=linelength*2; 776 curline += linelength*2;
771 nextline+=linelength*2; 777 nextline += linelength*2;
772 if (curline >= framedata+datasize*3) { 778 if (curline >= framedata+datasize * 3) {
773 frame->curlinepix++; 779 frame->curlinepix++;
774 curline-=3; 780 curline -= 3;
775 nextline-=3; 781 nextline -= 3;
776 len--; 782 len--;
777 data++; 783 data++;
778 frame->curpix++; 784 frame->curpix++;
779 } 785 }
780 if (nextline >= framedata+datasize*3) 786 if (nextline >= framedata+datasize*3)
781 nextline=curline; 787 nextline = curline;
782 } 788 }
783 if ((bline&1)) { 789 if (bline & 1) {
784 if ((frame->curlinepix&1)) { 790 if (frame->curlinepix & 1) {
785 *(curline+2)=*data; 791 *(curline + 2) = *data;
786 *(curline-1)=*data; 792 *(curline - 1) = *data;
787 *(nextline+2)=*data; 793 *(nextline + 2) = *data;
788 *(nextline-1)=*data; 794 *(nextline - 1) = *data;
789 } else { 795 } else {
790 *(curline+1)= 796 *(curline + 1) =
791 (*(curline+1)+*data)/2; 797 (*(curline + 1) + *data) / 2;
792 *(curline-2)= 798 *(curline-2) =
793 (*(curline-2)+*data)/2; 799 (*(curline - 2) + *data) / 2;
794 *(nextline+1)=*data; 800 *(nextline + 1) = *data;
795 *(nextline-2)=*data; 801 *(nextline - 2) = *data;
796 } 802 }
797 } else { 803 } else {
798 if ((frame->curlinepix&1)) { 804 if (frame->curlinepix & 1) {
799 *(curline+1)= 805 *(curline + 1) =
800 (*(curline+1)+*data)/2; 806 (*(curline + 1) + *data) / 2;
801 *(curline-2)= 807 *(curline - 2) =
802 (*(curline-2)+*data)/2; 808 (*(curline - 2) + *data) / 2;
803 *(nextline+1)=*data; 809 *(nextline + 1) = *data;
804 *(nextline-2)=*data; 810 *(nextline - 2) = *data;
805 } else { 811 } else {
806 *curline=*data; 812 *curline = *data;
807 *(curline-3)=*data; 813 *(curline - 3) = *data;
808 *nextline=*data; 814 *nextline = *data;
809 *(nextline-3)=*data; 815 *(nextline - 3) = *data;
810 } 816 }
811 } 817 }
812 frame->curlinepix++; 818 frame->curlinepix++;
813 curline-=3; 819 curline -= 3;
814 nextline-=3; 820 nextline -= 3;
815 len--; 821 len--;
816 data++; 822 data++;
817 frame->curpix++; 823 frame->curpix++;
818 } 824 }
819 frame->curline=curline; 825 frame->curline = curline;
820 826
821 if (frame->curpix>=datasize) { 827 if (frame->curpix >= datasize) {
822 /* Fix the top line */ 828 /* Fix the top line */
823 framedata+=linelength; 829 framedata += linelength;
824 for (i=0; i<linelength; i++) { 830 for (i = 0; i < linelength; i++) {
825 framedata--; 831 framedata--;
826 *framedata=*(framedata+linelength); 832 *framedata = *(framedata + linelength);
827 } 833 }
828 /* Fix the left side (green is already present) */ 834 /* Fix the left side (green is already present) */
829 for (i=0; i<se401->cheight; i++) { 835 for (i = 0; i < se401->cheight; i++) {
830 *framedata=*(framedata+3); 836 *framedata = *(framedata + 3);
831 *(framedata+1)=*(framedata+4); 837 *(framedata + 1) = *(framedata + 4);
832 *(framedata+2)=*(framedata+5); 838 *(framedata + 2) = *(framedata + 5);
833 framedata+=linelength; 839 framedata += linelength;
834 } 840 }
835 frame->curpix=0; 841 frame->curpix = 0;
836 frame->grabstate=FRAME_DONE; 842 frame->grabstate = FRAME_DONE;
837 se401->framecount++; 843 se401->framecount++;
838 se401->readcount++; 844 se401->readcount++;
839 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) { 845 if (se401->frame[(se401->curframe + 1) &
840 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1); 846 (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) {
847 se401->curframe = (se401->curframe+1) &
848 (SE401_NUMFRAMES-1);
841 } 849 }
842 } 850 }
843} 851}
@@ -845,72 +853,76 @@ static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *
845static int se401_newframe(struct usb_se401 *se401, int framenr) 853static int se401_newframe(struct usb_se401 *se401, int framenr)
846{ 854{
847 DECLARE_WAITQUEUE(wait, current); 855 DECLARE_WAITQUEUE(wait, current);
848 int errors=0; 856 int errors = 0;
849 857
850 while (se401->streaming && 858 while (se401->streaming &&
851 (se401->frame[framenr].grabstate==FRAME_READY || 859 (se401->frame[framenr].grabstate == FRAME_READY ||
852 se401->frame[framenr].grabstate==FRAME_GRABBING) ) { 860 se401->frame[framenr].grabstate == FRAME_GRABBING)) {
853 if(!se401->frame[framenr].curpix) { 861 if (!se401->frame[framenr].curpix)
854 errors++; 862 errors++;
855 } 863
856 wait_interruptible( 864 wait_interruptible(
857 se401->scratch[se401->scratch_use].state!=BUFFER_READY, 865 se401->scratch[se401->scratch_use].state != BUFFER_READY,
858 &se401->wq, 866 &se401->wq, &wait);
859 &wait
860 );
861 if (se401->nullpackets > SE401_MAX_NULLPACKETS) { 867 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
862 se401->nullpackets=0; 868 se401->nullpackets = 0;
863 dev_info(&se401->dev->dev, 869 dev_info(&se401->dev->dev,
864 "too many null length packets, restarting capture\n"); 870 "too many null length packets, restarting capture\n");
865 se401_stop_stream(se401); 871 se401_stop_stream(se401);
866 se401_start_stream(se401); 872 se401_start_stream(se401);
867 } else { 873 } else {
868 if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) { 874 if (se401->scratch[se401->scratch_use].state !=
869 se401->frame[framenr].grabstate=FRAME_ERROR; 875 BUFFER_READY) {
876 se401->frame[framenr].grabstate = FRAME_ERROR;
870 return -EIO; 877 return -EIO;
871 } 878 }
872 se401->scratch[se401->scratch_use].state=BUFFER_BUSY; 879 se401->scratch[se401->scratch_use].state = BUFFER_BUSY;
873 if (se401->format==FMT_JANGGU) { 880 if (se401->format == FMT_JANGGU)
874 decode_JangGu(se401, &se401->scratch[se401->scratch_use]); 881 decode_JangGu(se401,
875 } else { 882 &se401->scratch[se401->scratch_use]);
876 decode_bayer(se401, &se401->scratch[se401->scratch_use]); 883 else
877 } 884 decode_bayer(se401,
878 se401->scratch[se401->scratch_use].state=BUFFER_UNUSED; 885 &se401->scratch[se401->scratch_use]);
886
887 se401->scratch[se401->scratch_use].state =
888 BUFFER_UNUSED;
879 se401->scratch_use++; 889 se401->scratch_use++;
880 if (se401->scratch_use>=SE401_NUMSCRATCH) 890 if (se401->scratch_use >= SE401_NUMSCRATCH)
881 se401->scratch_use=0; 891 se401->scratch_use = 0;
882 if (errors > SE401_MAX_ERRORS) { 892 if (errors > SE401_MAX_ERRORS) {
883 errors=0; 893 errors = 0;
884 dev_info(&se401->dev->dev, 894 dev_info(&se401->dev->dev,
885 "too many errors, restarting capture\n"); 895 "too many errors, restarting capture\n");
886 se401_stop_stream(se401); 896 se401_stop_stream(se401);
887 se401_start_stream(se401); 897 se401_start_stream(se401);
888 } 898 }
889 } 899 }
890 } 900 }
891 901
892 if (se401->frame[framenr].grabstate==FRAME_DONE) 902 if (se401->frame[framenr].grabstate == FRAME_DONE)
893 if (se401->enhance) 903 if (se401->enhance)
894 enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3); 904 enhance_picture(se401->frame[framenr].data,
905 se401->cheight * se401->cwidth * 3);
895 return 0; 906 return 0;
896} 907}
897 908
898static void usb_se401_remove_disconnected (struct usb_se401 *se401) 909static void usb_se401_remove_disconnected(struct usb_se401 *se401)
899{ 910{
900 int i; 911 int i;
901 912
902 se401->dev = NULL; 913 se401->dev = NULL;
903 914
904 for (i=0; i<SE401_NUMSBUF; i++) 915 for (i = 0; i < SE401_NUMSBUF; i++)
905 if (se401->urb[i]) { 916 if (se401->urb[i]) {
906 usb_kill_urb(se401->urb[i]); 917 usb_kill_urb(se401->urb[i]);
907 usb_free_urb(se401->urb[i]); 918 usb_free_urb(se401->urb[i]);
908 se401->urb[i] = NULL; 919 se401->urb[i] = NULL;
909 kfree(se401->sbuf[i].data); 920 kfree(se401->sbuf[i].data);
910 } 921 }
911 for (i=0; i<SE401_NUMSCRATCH; i++) { 922
923 for (i = 0; i < SE401_NUMSCRATCH; i++)
912 kfree(se401->scratch[i].data); 924 kfree(se401->scratch[i].data);
913 } 925
914 if (se401->inturb) { 926 if (se401->inturb) {
915 usb_kill_urb(se401->inturb); 927 usb_kill_urb(se401->inturb);
916 usb_free_urb(se401->inturb); 928 usb_free_urb(se401->inturb);
@@ -965,11 +977,11 @@ static int se401_close(struct file *file)
965 dev_info(&se401->dev->dev, "device unregistered\n"); 977 dev_info(&se401->dev->dev, "device unregistered\n");
966 usb_se401_remove_disconnected(se401); 978 usb_se401_remove_disconnected(se401);
967 } else { 979 } else {
968 for (i=0; i<SE401_NUMFRAMES; i++) 980 for (i = 0; i < SE401_NUMFRAMES; i++)
969 se401->frame[i].grabstate=FRAME_UNUSED; 981 se401->frame[i].grabstate = FRAME_UNUSED;
970 if (se401->streaming) 982 if (se401->streaming)
971 se401_stop_stream(se401); 983 se401_stop_stream(se401);
972 se401->user=0; 984 se401->user = 0;
973 } 985 }
974 file->private_data = NULL; 986 file->private_data = NULL;
975 return 0; 987 return 0;
@@ -1065,7 +1077,7 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1065 memset(vm, 0, sizeof(*vm)); 1077 memset(vm, 0, sizeof(*vm));
1066 vm->size = SE401_NUMFRAMES * se401->maxframesize; 1078 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1067 vm->frames = SE401_NUMFRAMES; 1079 vm->frames = SE401_NUMFRAMES;
1068 for (i=0; i<SE401_NUMFRAMES; i++) 1080 for (i = 0; i < SE401_NUMFRAMES; i++)
1069 vm->offsets[i] = se401->maxframesize * i; 1081 vm->offsets[i] = se401->maxframesize * i;
1070 return 0; 1082 return 0;
1071 } 1083 }
@@ -1083,16 +1095,16 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1083 /* Is this according to the v4l spec??? */ 1095 /* Is this according to the v4l spec??? */
1084 if (se401_set_size(se401, vm->width, vm->height)) 1096 if (se401_set_size(se401, vm->width, vm->height))
1085 return -EINVAL; 1097 return -EINVAL;
1086 se401->frame[vm->frame].grabstate=FRAME_READY; 1098 se401->frame[vm->frame].grabstate = FRAME_READY;
1087 1099
1088 if (!se401->streaming) 1100 if (!se401->streaming)
1089 se401_start_stream(se401); 1101 se401_start_stream(se401);
1090 1102
1091 /* Set the picture properties */ 1103 /* Set the picture properties */
1092 if (se401->framecount==0) 1104 if (se401->framecount == 0)
1093 se401_send_pict(se401); 1105 se401_send_pict(se401);
1094 /* Calibrate the reset level after a few frames. */ 1106 /* Calibrate the reset level after a few frames. */
1095 if (se401->framecount%20==1) 1107 if (se401->framecount % 20 == 1)
1096 se401_auto_resetlevel(se401); 1108 se401_auto_resetlevel(se401);
1097 1109
1098 return 0; 1110 return 0;
@@ -1100,13 +1112,13 @@ static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1100 case VIDIOCSYNC: 1112 case VIDIOCSYNC:
1101 { 1113 {
1102 int *frame = arg; 1114 int *frame = arg;
1103 int ret=0; 1115 int ret = 0;
1104 1116
1105 if(*frame <0 || *frame >= SE401_NUMFRAMES) 1117 if (*frame < 0 || *frame >= SE401_NUMFRAMES)
1106 return -EINVAL; 1118 return -EINVAL;
1107 1119
1108 ret=se401_newframe(se401, *frame); 1120 ret = se401_newframe(se401, *frame);
1109 se401->frame[*frame].grabstate=FRAME_UNUSED; 1121 se401->frame[*frame].grabstate = FRAME_UNUSED;
1110 return ret; 1122 return ret;
1111 } 1123 }
1112 case VIDIOCGFBUF: 1124 case VIDIOCGFBUF:
@@ -1147,36 +1159,36 @@ static long se401_ioctl(struct file *file,
1147static ssize_t se401_read(struct file *file, char __user *buf, 1159static ssize_t se401_read(struct file *file, char __user *buf,
1148 size_t count, loff_t *ppos) 1160 size_t count, loff_t *ppos)
1149{ 1161{
1150 int realcount=count, ret=0; 1162 int realcount = count, ret = 0;
1151 struct video_device *dev = file->private_data; 1163 struct video_device *dev = file->private_data;
1152 struct usb_se401 *se401 = (struct usb_se401 *)dev; 1164 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1153 1165
1154 1166
1155 if (se401->dev == NULL) 1167 if (se401->dev == NULL)
1156 return -EIO; 1168 return -EIO;
1157 if (realcount > se401->cwidth*se401->cheight*3) 1169 if (realcount > se401->cwidth*se401->cheight*3)
1158 realcount=se401->cwidth*se401->cheight*3; 1170 realcount = se401->cwidth*se401->cheight*3;
1159 1171
1160 /* Shouldn't happen: */ 1172 /* Shouldn't happen: */
1161 if (se401->frame[0].grabstate==FRAME_GRABBING) 1173 if (se401->frame[0].grabstate == FRAME_GRABBING)
1162 return -EBUSY; 1174 return -EBUSY;
1163 se401->frame[0].grabstate=FRAME_READY; 1175 se401->frame[0].grabstate = FRAME_READY;
1164 se401->frame[1].grabstate=FRAME_UNUSED; 1176 se401->frame[1].grabstate = FRAME_UNUSED;
1165 se401->curframe=0; 1177 se401->curframe = 0;
1166 1178
1167 if (!se401->streaming) 1179 if (!se401->streaming)
1168 se401_start_stream(se401); 1180 se401_start_stream(se401);
1169 1181
1170 /* Set the picture properties */ 1182 /* Set the picture properties */
1171 if (se401->framecount==0) 1183 if (se401->framecount == 0)
1172 se401_send_pict(se401); 1184 se401_send_pict(se401);
1173 /* Calibrate the reset level after a few frames. */ 1185 /* Calibrate the reset level after a few frames. */
1174 if (se401->framecount%20==1) 1186 if (se401->framecount%20 == 1)
1175 se401_auto_resetlevel(se401); 1187 se401_auto_resetlevel(se401);
1176 1188
1177 ret=se401_newframe(se401, 0); 1189 ret = se401_newframe(se401, 0);
1178 1190
1179 se401->frame[0].grabstate=FRAME_UNUSED; 1191 se401->frame[0].grabstate = FRAME_UNUSED;
1180 if (ret) 1192 if (ret)
1181 return ret; 1193 return ret;
1182 if (copy_to_user(buf, se401->frame[0].data, realcount)) 1194 if (copy_to_user(buf, se401->frame[0].data, realcount))
@@ -1195,11 +1207,12 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1195 1207
1196 mutex_lock(&se401->lock); 1208 mutex_lock(&se401->lock);
1197 1209
1198 if (se401->dev == NULL) { 1210 if (se401->dev == NULL) {
1199 mutex_unlock(&se401->lock); 1211 mutex_unlock(&se401->lock);
1200 return -EIO; 1212 return -EIO;
1201 } 1213 }
1202 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) { 1214 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1)
1215 & ~(PAGE_SIZE - 1))) {
1203 mutex_unlock(&se401->lock); 1216 mutex_unlock(&se401->lock);
1204 return -EINVAL; 1217 return -EINVAL;
1205 } 1218 }
@@ -1210,10 +1223,10 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1210 mutex_unlock(&se401->lock); 1223 mutex_unlock(&se401->lock);
1211 return -EAGAIN; 1224 return -EAGAIN;
1212 } 1225 }
1213 start += PAGE_SIZE; 1226 start += PAGE_SIZE;
1214 pos += PAGE_SIZE; 1227 pos += PAGE_SIZE;
1215 if (size > PAGE_SIZE) 1228 if (size > PAGE_SIZE)
1216 size -= PAGE_SIZE; 1229 size -= PAGE_SIZE;
1217 else 1230 else
1218 size = 0; 1231 size = 0;
1219 } 1232 }
@@ -1223,7 +1236,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1223} 1236}
1224 1237
1225static const struct v4l2_file_operations se401_fops = { 1238static const struct v4l2_file_operations se401_fops = {
1226 .owner = THIS_MODULE, 1239 .owner = THIS_MODULE,
1227 .open = se401_open, 1240 .open = se401_open,
1228 .release = se401_close, 1241 .release = se401_close,
1229 .read = se401_read, 1242 .read = se401_read,
@@ -1241,71 +1254,76 @@ static struct video_device se401_template = {
1241/***************************/ 1254/***************************/
1242static int se401_init(struct usb_se401 *se401, int button) 1255static int se401_init(struct usb_se401 *se401, int button)
1243{ 1256{
1244 int i=0, rc; 1257 int i = 0, rc;
1245 unsigned char cp[0x40]; 1258 unsigned char cp[0x40];
1246 char temp[200]; 1259 char temp[200];
1260 int slen;
1247 1261
1248 /* led on */ 1262 /* led on */
1249 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0); 1263 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1250 1264
1251 /* get camera descriptor */ 1265 /* get camera descriptor */
1252 rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp)); 1266 rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0,
1253 if (cp[1]!=0x41) { 1267 cp, sizeof(cp));
1268 if (cp[1] != 0x41) {
1254 err("Wrong descriptor type"); 1269 err("Wrong descriptor type");
1255 return 1; 1270 return 1;
1256 } 1271 }
1257 sprintf (temp, "ExtraFeatures: %d", cp[3]); 1272 slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]);
1258 1273
1259 se401->sizes=cp[4]+cp[5]*256; 1274 se401->sizes = cp[4] + cp[5] * 256;
1260 se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); 1275 se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1261 if (!se401->width) 1276 if (!se401->width)
1262 return 1; 1277 return 1;
1263 se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL); 1278 se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1264 if (!se401->height) { 1279 if (!se401->height) {
1265 kfree(se401->width); 1280 kfree(se401->width);
1266 return 1; 1281 return 1;
1267 } 1282 }
1268 for (i=0; i<se401->sizes; i++) { 1283 for (i = 0; i < se401->sizes; i++) {
1269 se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256; 1284 se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256;
1270 se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256; 1285 se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256;
1271 } 1286 }
1272 sprintf (temp, "%s Sizes:", temp); 1287 slen += snprintf(temp + slen, 200 - slen, " Sizes:");
1273 for (i=0; i<se401->sizes; i++) { 1288 for (i = 0; i < se401->sizes; i++) {
1274 sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]); 1289 slen += snprintf(temp + slen, 200 - slen,
1290 " %dx%d", se401->width[i], se401->height[i]);
1275 } 1291 }
1276 dev_info(&se401->dev->dev, "%s\n", temp); 1292 dev_info(&se401->dev->dev, "%s\n", temp);
1277 se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3; 1293 se401->maxframesize = se401->width[se401->sizes-1] *
1294 se401->height[se401->sizes - 1] * 3;
1278 1295
1279 rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp)); 1296 rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1280 se401->cwidth=cp[0]+cp[1]*256; 1297 se401->cwidth = cp[0]+cp[1]*256;
1281 rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp)); 1298 rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1282 se401->cheight=cp[0]+cp[1]*256; 1299 se401->cheight = cp[0]+cp[1]*256;
1283 1300
1284 if (!(cp[2] & SE401_FORMAT_BAYER)) { 1301 if (!(cp[2] & SE401_FORMAT_BAYER)) {
1285 err("Bayer format not supported!"); 1302 err("Bayer format not supported!");
1286 return 1; 1303 return 1;
1287 } 1304 }
1288 /* set output mode (BAYER) */ 1305 /* set output mode (BAYER) */
1289 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0); 1306 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE,
1307 SE401_FORMAT_BAYER, NULL, 0);
1290 1308
1291 rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp)); 1309 rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1292 se401->brightness=cp[0]+cp[1]*256; 1310 se401->brightness = cp[0]+cp[1]*256;
1293 /* some default values */ 1311 /* some default values */
1294 se401->resetlevel=0x2d; 1312 se401->resetlevel = 0x2d;
1295 se401->rgain=0x20; 1313 se401->rgain = 0x20;
1296 se401->ggain=0x20; 1314 se401->ggain = 0x20;
1297 se401->bgain=0x20; 1315 se401->bgain = 0x20;
1298 se401_set_exposure(se401, 20000); 1316 se401_set_exposure(se401, 20000);
1299 se401->palette=VIDEO_PALETTE_RGB24; 1317 se401->palette = VIDEO_PALETTE_RGB24;
1300 se401->enhance=1; 1318 se401->enhance = 1;
1301 se401->dropped=0; 1319 se401->dropped = 0;
1302 se401->error=0; 1320 se401->error = 0;
1303 se401->framecount=0; 1321 se401->framecount = 0;
1304 se401->readcount=0; 1322 se401->readcount = 0;
1305 1323
1306 /* Start interrupt transfers for snapshot button */ 1324 /* Start interrupt transfers for snapshot button */
1307 if (button) { 1325 if (button) {
1308 se401->inturb=usb_alloc_urb(0, GFP_KERNEL); 1326 se401->inturb = usb_alloc_urb(0, GFP_KERNEL);
1309 if (!se401->inturb) { 1327 if (!se401->inturb) {
1310 dev_info(&se401->dev->dev, 1328 dev_info(&se401->dev->dev,
1311 "Allocation of inturb failed\n"); 1329 "Allocation of inturb failed\n");
@@ -1323,7 +1341,7 @@ static int se401_init(struct usb_se401 *se401, int button)
1323 return 1; 1341 return 1;
1324 } 1342 }
1325 } else 1343 } else
1326 se401->inturb=NULL; 1344 se401->inturb = NULL;
1327 1345
1328 /* Flash the led */ 1346 /* Flash the led */
1329 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0); 1347 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
@@ -1340,8 +1358,8 @@ static int se401_probe(struct usb_interface *intf,
1340 struct usb_device *dev = interface_to_usbdev(intf); 1358 struct usb_device *dev = interface_to_usbdev(intf);
1341 struct usb_interface_descriptor *interface; 1359 struct usb_interface_descriptor *interface;
1342 struct usb_se401 *se401; 1360 struct usb_se401 *se401;
1343 char *camera_name=NULL; 1361 char *camera_name = NULL;
1344 int button=1; 1362 int button = 1;
1345 1363
1346 /* We don't handle multi-config cameras */ 1364 /* We don't handle multi-config cameras */
1347 if (dev->descriptor.bNumConfigurations != 1) 1365 if (dev->descriptor.bNumConfigurations != 1)
@@ -1350,22 +1368,22 @@ static int se401_probe(struct usb_interface *intf,
1350 interface = &intf->cur_altsetting->desc; 1368 interface = &intf->cur_altsetting->desc;
1351 1369
1352 /* Is it an se401? */ 1370 /* Is it an se401? */
1353 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 && 1371 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1354 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) { 1372 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1355 camera_name="Endpoints/Aox SE401"; 1373 camera_name = "Endpoints/Aox SE401";
1356 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 && 1374 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1357 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) { 1375 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1358 camera_name="Philips PCVC665K"; 1376 camera_name = "Philips PCVC665K";
1359 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && 1377 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1360 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) { 1378 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1361 camera_name="Kensington VideoCAM 67014"; 1379 camera_name = "Kensington VideoCAM 67014";
1362 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && 1380 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1363 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) { 1381 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1364 camera_name="Kensington VideoCAM 6701(5/7)"; 1382 camera_name = "Kensington VideoCAM 6701(5/7)";
1365 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d && 1383 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1366 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) { 1384 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1367 camera_name="Kensington VideoCAM 67016"; 1385 camera_name = "Kensington VideoCAM 67016";
1368 button=0; 1386 button = 0;
1369 } else 1387 } else
1370 return -ENODEV; 1388 return -ENODEV;
1371 1389
@@ -1378,7 +1396,8 @@ static int se401_probe(struct usb_interface *intf,
1378 /* We found one */ 1396 /* We found one */
1379 dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name); 1397 dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name);
1380 1398
1381 if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { 1399 se401 = kzalloc(sizeof(*se401), GFP_KERNEL);
1400 if (se401 == NULL) {
1382 err("couldn't kmalloc se401 struct"); 1401 err("couldn't kmalloc se401 struct");
1383 return -ENOMEM; 1402 return -ENOMEM;
1384 } 1403 }
@@ -1396,12 +1415,14 @@ static int se401_probe(struct usb_interface *intf,
1396 } 1415 }
1397 1416
1398 memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); 1417 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1399 memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name)); 1418 memcpy(se401->vdev.name, se401->camera_name,
1419 strlen(se401->camera_name));
1400 init_waitqueue_head(&se401->wq); 1420 init_waitqueue_head(&se401->wq);
1401 mutex_init(&se401->lock); 1421 mutex_init(&se401->lock);
1402 wmb(); 1422 wmb();
1403 1423
1404 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { 1424 if (video_register_device(&se401->vdev,
1425 VFL_TYPE_GRABBER, video_nr) < 0) {
1405 kfree(se401); 1426 kfree(se401);
1406 err("video_register_device failed"); 1427 err("video_register_device failed");
1407 return -EIO; 1428 return -EIO;
@@ -1409,20 +1430,20 @@ static int se401_probe(struct usb_interface *intf,
1409 dev_info(&intf->dev, "registered new video device: video%d\n", 1430 dev_info(&intf->dev, "registered new video device: video%d\n",
1410 se401->vdev.num); 1431 se401->vdev.num);
1411 1432
1412 usb_set_intfdata (intf, se401); 1433 usb_set_intfdata(intf, se401);
1413 return 0; 1434 return 0;
1414} 1435}
1415 1436
1416static void se401_disconnect(struct usb_interface *intf) 1437static void se401_disconnect(struct usb_interface *intf)
1417{ 1438{
1418 struct usb_se401 *se401 = usb_get_intfdata (intf); 1439 struct usb_se401 *se401 = usb_get_intfdata(intf);
1419 1440
1420 usb_set_intfdata (intf, NULL); 1441 usb_set_intfdata(intf, NULL);
1421 if (se401) { 1442 if (se401) {
1422 video_unregister_device(&se401->vdev); 1443 video_unregister_device(&se401->vdev);
1423 if (!se401->user){ 1444 if (!se401->user)
1424 usb_se401_remove_disconnected(se401); 1445 usb_se401_remove_disconnected(se401);
1425 } else { 1446 else {
1426 se401->frame[0].grabstate = FRAME_ERROR; 1447 se401->frame[0].grabstate = FRAME_ERROR;
1427 se401->frame[0].grabstate = FRAME_ERROR; 1448 se401->frame[0].grabstate = FRAME_ERROR;
1428 1449
@@ -1435,10 +1456,10 @@ static void se401_disconnect(struct usb_interface *intf)
1435} 1456}
1436 1457
1437static struct usb_driver se401_driver = { 1458static struct usb_driver se401_driver = {
1438 .name = "se401", 1459 .name = "se401",
1439 .id_table = device_table, 1460 .id_table = device_table,
1440 .probe = se401_probe, 1461 .probe = se401_probe,
1441 .disconnect = se401_disconnect, 1462 .disconnect = se401_disconnect,
1442}; 1463};
1443 1464
1444 1465
@@ -1451,9 +1472,10 @@ static struct usb_driver se401_driver = {
1451 1472
1452static int __init usb_se401_init(void) 1473static int __init usb_se401_init(void)
1453{ 1474{
1454 printk(KERN_INFO "SE401 usb camera driver version %s registering\n", version); 1475 printk(KERN_INFO "SE401 usb camera driver version %s registering\n",
1476 version);
1455 if (flickerless) 1477 if (flickerless)
1456 if (flickerless!=50 && flickerless!=60) { 1478 if (flickerless != 50 && flickerless != 60) {
1457 printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n"); 1479 printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
1458 return -1; 1480 return -1;
1459 } 1481 }
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index 2ce685db5d8b..bf7d2e9765b0 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -2,7 +2,7 @@
2#ifndef __LINUX_se401_H 2#ifndef __LINUX_se401_H
3#define __LINUX_se401_H 3#define __LINUX_se401_H
4 4
5#include <asm/uaccess.h> 5#include <linux/uaccess.h>
6#include <linux/videodev.h> 6#include <linux/videodev.h>
7#include <media/v4l2-common.h> 7#include <media/v4l2-common.h>
8#include <media/v4l2-ioctl.h> 8#include <media/v4l2-ioctl.h>
@@ -12,9 +12,10 @@
12 12
13#ifdef se401_DEBUG 13#ifdef se401_DEBUG
14# define PDEBUG(level, fmt, args...) \ 14# define PDEBUG(level, fmt, args...) \
15if (debug >= level) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args) 15if (debug >= level) \
16 info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
16#else 17#else
17# define PDEBUG(level, fmt, args...) do {} while(0) 18# define PDEBUG(level, fmt, args...) do {} while (0)
18#endif 19#endif
19 20
20/* An almost drop-in replacement for sleep_on_interruptible */ 21/* An almost drop-in replacement for sleep_on_interruptible */
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index b5e37a530c62..d369e8409ab8 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -81,7 +81,6 @@ struct sh_mobile_ceu_buffer {
81}; 81};
82 82
83struct sh_mobile_ceu_dev { 83struct sh_mobile_ceu_dev {
84 struct device *dev;
85 struct soc_camera_host ici; 84 struct soc_camera_host ici;
86 struct soc_camera_device *icd; 85 struct soc_camera_device *icd;
87 86
@@ -617,7 +616,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
617 xlate->cam_fmt = icd->formats + idx; 616 xlate->cam_fmt = icd->formats + idx;
618 xlate->buswidth = icd->formats[idx].depth; 617 xlate->buswidth = icd->formats[idx].depth;
619 xlate++; 618 xlate++;
620 dev_dbg(&ici->dev, "Providing format %s using %s\n", 619 dev_dbg(ici->dev, "Providing format %s using %s\n",
621 sh_mobile_ceu_formats[k].name, 620 sh_mobile_ceu_formats[k].name,
622 icd->formats[idx].name); 621 icd->formats[idx].name);
623 } 622 }
@@ -630,7 +629,7 @@ add_single_format:
630 xlate->cam_fmt = icd->formats + idx; 629 xlate->cam_fmt = icd->formats + idx;
631 xlate->buswidth = icd->formats[idx].depth; 630 xlate->buswidth = icd->formats[idx].depth;
632 xlate++; 631 xlate++;
633 dev_dbg(&ici->dev, 632 dev_dbg(ici->dev,
634 "Providing format %s in pass-through mode\n", 633 "Providing format %s in pass-through mode\n",
635 icd->formats[idx].name); 634 icd->formats[idx].name);
636 } 635 }
@@ -657,7 +656,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
657 656
658 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 657 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
659 if (!xlate) { 658 if (!xlate) {
660 dev_warn(&ici->dev, "Format %x not found\n", pixfmt); 659 dev_warn(ici->dev, "Format %x not found\n", pixfmt);
661 return -EINVAL; 660 return -EINVAL;
662 } 661 }
663 662
@@ -684,7 +683,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
684 683
685 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 684 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
686 if (!xlate) { 685 if (!xlate) {
687 dev_warn(&ici->dev, "Format %x not found\n", pixfmt); 686 dev_warn(ici->dev, "Format %x not found\n", pixfmt);
688 return -EINVAL; 687 return -EINVAL;
689 } 688 }
690 689
@@ -782,7 +781,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
782 781
783 videobuf_queue_dma_contig_init(q, 782 videobuf_queue_dma_contig_init(q,
784 &sh_mobile_ceu_videobuf_ops, 783 &sh_mobile_ceu_videobuf_ops,
785 &ici->dev, &pcdev->lock, 784 ici->dev, &pcdev->lock,
786 V4L2_BUF_TYPE_VIDEO_CAPTURE, 785 V4L2_BUF_TYPE_VIDEO_CAPTURE,
787 pcdev->is_interlaced ? 786 pcdev->is_interlaced ?
788 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, 787 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
@@ -829,7 +828,6 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
829 goto exit; 828 goto exit;
830 } 829 }
831 830
832 platform_set_drvdata(pdev, pcdev);
833 INIT_LIST_HEAD(&pcdev->capture); 831 INIT_LIST_HEAD(&pcdev->capture);
834 spin_lock_init(&pcdev->lock); 832 spin_lock_init(&pcdev->lock);
835 833
@@ -840,7 +838,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
840 goto exit_kfree; 838 goto exit_kfree;
841 } 839 }
842 840
843 base = ioremap_nocache(res->start, res->end - res->start + 1); 841 base = ioremap_nocache(res->start, resource_size(res));
844 if (!base) { 842 if (!base) {
845 err = -ENXIO; 843 err = -ENXIO;
846 dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); 844 dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
@@ -850,13 +848,12 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
850 pcdev->irq = irq; 848 pcdev->irq = irq;
851 pcdev->base = base; 849 pcdev->base = base;
852 pcdev->video_limit = 0; /* only enabled if second resource exists */ 850 pcdev->video_limit = 0; /* only enabled if second resource exists */
853 pcdev->dev = &pdev->dev;
854 851
855 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 852 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
856 if (res) { 853 if (res) {
857 err = dma_declare_coherent_memory(&pdev->dev, res->start, 854 err = dma_declare_coherent_memory(&pdev->dev, res->start,
858 res->start, 855 res->start,
859 (res->end - res->start) + 1, 856 resource_size(res),
860 DMA_MEMORY_MAP | 857 DMA_MEMORY_MAP |
861 DMA_MEMORY_EXCLUSIVE); 858 DMA_MEMORY_EXCLUSIVE);
862 if (!err) { 859 if (!err) {
@@ -865,7 +862,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
865 goto exit_iounmap; 862 goto exit_iounmap;
866 } 863 }
867 864
868 pcdev->video_limit = (res->end - res->start) + 1; 865 pcdev->video_limit = resource_size(res);
869 } 866 }
870 867
871 /* request irq */ 868 /* request irq */
@@ -885,7 +882,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
885 } 882 }
886 883
887 pcdev->ici.priv = pcdev; 884 pcdev->ici.priv = pcdev;
888 pcdev->ici.dev.parent = &pdev->dev; 885 pcdev->ici.dev = &pdev->dev;
889 pcdev->ici.nr = pdev->id; 886 pcdev->ici.nr = pdev->id;
890 pcdev->ici.drv_name = dev_name(&pdev->dev); 887 pcdev->ici.drv_name = dev_name(&pdev->dev);
891 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 888 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
@@ -913,9 +910,11 @@ exit:
913 910
914static int sh_mobile_ceu_remove(struct platform_device *pdev) 911static int sh_mobile_ceu_remove(struct platform_device *pdev)
915{ 912{
916 struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev); 913 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
914 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
915 struct sh_mobile_ceu_dev, ici);
917 916
918 soc_camera_host_unregister(&pcdev->ici); 917 soc_camera_host_unregister(soc_host);
919 clk_put(pcdev->clk); 918 clk_put(pcdev->clk);
920 free_irq(pcdev->irq, pcdev); 919 free_irq(pcdev->irq, pcdev);
921 if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) 920 if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 0e890cc23377..16f595d4337a 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -16,19 +16,21 @@
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/device.h> 19#include <linux/device.h>
22#include <linux/list.h>
23#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/i2c.h>
22#include <linux/init.h>
23#include <linux/list.h>
24#include <linux/module.h>
24#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/platform_device.h>
25#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
26 28
29#include <media/soc_camera.h>
27#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
28#include <media/v4l2-ioctl.h>
29#include <media/v4l2-dev.h> 31#include <media/v4l2-dev.h>
32#include <media/v4l2-ioctl.h>
30#include <media/videobuf-core.h> 33#include <media/videobuf-core.h>
31#include <media/soc_camera.h>
32 34
33/* Default to VGA resolution */ 35/* Default to VGA resolution */
34#define DEFAULT_WIDTH 640 36#define DEFAULT_WIDTH 640
@@ -279,7 +281,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
279 return ret; 281 return ret;
280 } else if (!icd->current_fmt || 282 } else if (!icd->current_fmt ||
281 icd->current_fmt->fourcc != pix->pixelformat) { 283 icd->current_fmt->fourcc != pix->pixelformat) {
282 dev_err(&ici->dev, 284 dev_err(ici->dev,
283 "Host driver hasn't set up current format correctly!\n"); 285 "Host driver hasn't set up current format correctly!\n");
284 return -EINVAL; 286 return -EINVAL;
285 } 287 }
@@ -794,7 +796,7 @@ static void scan_add_host(struct soc_camera_host *ici)
794 796
795 list_for_each_entry(icd, &devices, list) { 797 list_for_each_entry(icd, &devices, list) {
796 if (icd->iface == ici->nr) { 798 if (icd->iface == ici->nr) {
797 icd->dev.parent = &ici->dev; 799 icd->dev.parent = ici->dev;
798 device_register_link(icd); 800 device_register_link(icd);
799 } 801 }
800 } 802 }
@@ -818,7 +820,7 @@ static int scan_add_device(struct soc_camera_device *icd)
818 list_for_each_entry(ici, &hosts, list) { 820 list_for_each_entry(ici, &hosts, list) {
819 if (icd->iface == ici->nr) { 821 if (icd->iface == ici->nr) {
820 ret = 1; 822 ret = 1;
821 icd->dev.parent = &ici->dev; 823 icd->dev.parent = ici->dev;
822 break; 824 break;
823 } 825 }
824 } 826 }
@@ -952,7 +954,6 @@ static void dummy_release(struct device *dev)
952 954
953int soc_camera_host_register(struct soc_camera_host *ici) 955int soc_camera_host_register(struct soc_camera_host *ici)
954{ 956{
955 int ret;
956 struct soc_camera_host *ix; 957 struct soc_camera_host *ix;
957 958
958 if (!ici || !ici->ops || 959 if (!ici || !ici->ops ||
@@ -965,12 +966,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
965 !ici->ops->reqbufs || 966 !ici->ops->reqbufs ||
966 !ici->ops->add || 967 !ici->ops->add ||
967 !ici->ops->remove || 968 !ici->ops->remove ||
968 !ici->ops->poll) 969 !ici->ops->poll ||
970 !ici->dev)
969 return -EINVAL; 971 return -EINVAL;
970 972
971 /* Number might be equal to the platform device ID */
972 dev_set_name(&ici->dev, "camera_host%d", ici->nr);
973
974 mutex_lock(&list_lock); 973 mutex_lock(&list_lock);
975 list_for_each_entry(ix, &hosts, list) { 974 list_for_each_entry(ix, &hosts, list) {
976 if (ix->nr == ici->nr) { 975 if (ix->nr == ici->nr) {
@@ -979,26 +978,14 @@ int soc_camera_host_register(struct soc_camera_host *ici)
979 } 978 }
980 } 979 }
981 980
981 dev_set_drvdata(ici->dev, ici);
982
982 list_add_tail(&ici->list, &hosts); 983 list_add_tail(&ici->list, &hosts);
983 mutex_unlock(&list_lock); 984 mutex_unlock(&list_lock);
984 985
985 ici->dev.release = dummy_release;
986
987 ret = device_register(&ici->dev);
988
989 if (ret)
990 goto edevr;
991
992 scan_add_host(ici); 986 scan_add_host(ici);
993 987
994 return 0; 988 return 0;
995
996edevr:
997 mutex_lock(&list_lock);
998 list_del(&ici->list);
999 mutex_unlock(&list_lock);
1000
1001 return ret;
1002} 989}
1003EXPORT_SYMBOL(soc_camera_host_register); 990EXPORT_SYMBOL(soc_camera_host_register);
1004 991
@@ -1012,7 +999,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1012 list_del(&ici->list); 999 list_del(&ici->list);
1013 1000
1014 list_for_each_entry(icd, &devices, list) { 1001 list_for_each_entry(icd, &devices, list) {
1015 if (icd->dev.parent == &ici->dev) { 1002 if (icd->dev.parent == ici->dev) {
1016 device_unregister(&icd->dev); 1003 device_unregister(&icd->dev);
1017 /* Not before device_unregister(), .remove 1004 /* Not before device_unregister(), .remove
1018 * needs parent to call ici->ops->remove() */ 1005 * needs parent to call ici->ops->remove() */
@@ -1023,7 +1010,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1023 1010
1024 mutex_unlock(&list_lock); 1011 mutex_unlock(&list_lock);
1025 1012
1026 device_unregister(&ici->dev); 1013 dev_set_drvdata(ici->dev, NULL);
1027} 1014}
1028EXPORT_SYMBOL(soc_camera_host_unregister); 1015EXPORT_SYMBOL(soc_camera_host_unregister);
1029 1016
@@ -1130,7 +1117,7 @@ int soc_camera_video_start(struct soc_camera_device *icd)
1130 vdev = video_device_alloc(); 1117 vdev = video_device_alloc();
1131 if (!vdev) 1118 if (!vdev)
1132 goto evidallocd; 1119 goto evidallocd;
1133 dev_dbg(&ici->dev, "Allocated video_device %p\n", vdev); 1120 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
1134 1121
1135 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1122 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
1136 1123
@@ -1174,6 +1161,57 @@ void soc_camera_video_stop(struct soc_camera_device *icd)
1174} 1161}
1175EXPORT_SYMBOL(soc_camera_video_stop); 1162EXPORT_SYMBOL(soc_camera_video_stop);
1176 1163
1164static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1165{
1166 struct soc_camera_link *icl = pdev->dev.platform_data;
1167 struct i2c_adapter *adap;
1168 struct i2c_client *client;
1169
1170 if (!icl)
1171 return -EINVAL;
1172
1173 adap = i2c_get_adapter(icl->i2c_adapter_id);
1174 if (!adap) {
1175 dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
1176 icl->i2c_adapter_id);
1177 /* -ENODEV and -ENXIO do not produce an error on probe()... */
1178 return -ENOENT;
1179 }
1180
1181 icl->board_info->platform_data = icl;
1182 client = i2c_new_device(adap, icl->board_info);
1183 if (!client) {
1184 i2c_put_adapter(adap);
1185 return -ENOMEM;
1186 }
1187
1188 platform_set_drvdata(pdev, client);
1189
1190 return 0;
1191}
1192
1193static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1194{
1195 struct i2c_client *client = platform_get_drvdata(pdev);
1196
1197 if (!client)
1198 return -ENODEV;
1199
1200 i2c_unregister_device(client);
1201 i2c_put_adapter(client->adapter);
1202
1203 return 0;
1204}
1205
1206static struct platform_driver __refdata soc_camera_pdrv = {
1207 .probe = soc_camera_pdrv_probe,
1208 .remove = __devexit_p(soc_camera_pdrv_remove),
1209 .driver = {
1210 .name = "soc-camera-pdrv",
1211 .owner = THIS_MODULE,
1212 },
1213};
1214
1177static int __init soc_camera_init(void) 1215static int __init soc_camera_init(void)
1178{ 1216{
1179 int ret = bus_register(&soc_camera_bus_type); 1217 int ret = bus_register(&soc_camera_bus_type);
@@ -1183,8 +1221,14 @@ static int __init soc_camera_init(void)
1183 if (ret) 1221 if (ret)
1184 goto edrvr; 1222 goto edrvr;
1185 1223
1224 ret = platform_driver_register(&soc_camera_pdrv);
1225 if (ret)
1226 goto epdr;
1227
1186 return 0; 1228 return 0;
1187 1229
1230epdr:
1231 driver_unregister(&ic_drv);
1188edrvr: 1232edrvr:
1189 bus_unregister(&soc_camera_bus_type); 1233 bus_unregister(&soc_camera_bus_type);
1190 return ret; 1234 return ret;
@@ -1192,6 +1236,7 @@ edrvr:
1192 1236
1193static void __exit soc_camera_exit(void) 1237static void __exit soc_camera_exit(void)
1194{ 1238{
1239 platform_driver_unregister(&soc_camera_pdrv);
1195 driver_unregister(&ic_drv); 1240 driver_unregister(&ic_drv);
1196 bus_unregister(&soc_camera_bus_type); 1241 bus_unregister(&soc_camera_bus_type);
1197} 1242}
@@ -1202,3 +1247,4 @@ module_exit(soc_camera_exit);
1202MODULE_DESCRIPTION("Image capture bus driver"); 1247MODULE_DESCRIPTION("Image capture bus driver");
1203MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); 1248MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
1204MODULE_LICENSE("GPL"); 1249MODULE_LICENSE("GPL");
1250MODULE_ALIAS("platform:soc-camera-pdrv");
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 1a6d39cbd6f3..2e5937047278 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -1137,7 +1137,7 @@ static int stk_vidioc_querybuf(struct file *filp,
1137 struct stk_camera *dev = priv; 1137 struct stk_camera *dev = priv;
1138 struct stk_sio_buffer *sbuf; 1138 struct stk_sio_buffer *sbuf;
1139 1139
1140 if (buf->index < 0 || buf->index >= dev->n_sbufs) 1140 if (buf->index >= dev->n_sbufs)
1141 return -EINVAL; 1141 return -EINVAL;
1142 sbuf = dev->sio_bufs + buf->index; 1142 sbuf = dev->sio_bufs + buf->index;
1143 *buf = sbuf->v4lbuf; 1143 *buf = sbuf->v4lbuf;
@@ -1154,7 +1154,7 @@ static int stk_vidioc_qbuf(struct file *filp,
1154 if (buf->memory != V4L2_MEMORY_MMAP) 1154 if (buf->memory != V4L2_MEMORY_MMAP)
1155 return -EINVAL; 1155 return -EINVAL;
1156 1156
1157 if (buf->index < 0 || buf->index >= dev->n_sbufs) 1157 if (buf->index >= dev->n_sbufs)
1158 return -EINVAL; 1158 return -EINVAL;
1159 sbuf = dev->sio_bufs + buf->index; 1159 sbuf = dev->sio_bufs + buf->index;
1160 if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) 1160 if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED)
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 005f8a468031..80f1cee23fa5 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -20,20 +20,6 @@
20 * loudness - set between 0 and 15 for varying degrees of loudness effect 20 * loudness - set between 0 and 15 for varying degrees of loudness effect
21 * 21 *
22 * maxvol - set maximium volume to +20db (1), default is 0db(0) 22 * maxvol - set maximium volume to +20db (1), default is 0db(0)
23 *
24 *
25 * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db
26 * store if muted so we can return it
27 * change balance only if flaged to
28 * Revision: 0.6 - added tone controls
29 * Revision: 0.5 - Fixed odd balance problem
30 * Revision: 0.4 - added muting
31 * Revision: 0.3 - Fixed silly reversed volume controls. :)
32 * Revision: 0.2 - Cleaned up #defines
33 * fixed volume control
34 * Added I2C_DRIVERID_TDA7432
35 * added loudness insmod control
36 * Revision: 0.1 - initial version
37 */ 23 */
38 24
39#include <linux/module.h> 25#include <linux/module.h>
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index d4a9ed45764b..1585839bd0bd 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -141,7 +141,6 @@ static const struct v4l2_subdev_ops tea6415c_ops = {
141 .video = &tea6415c_video_ops, 141 .video = &tea6415c_video_ops,
142}; 142};
143 143
144/* this function is called by i2c_probe */
145static int tea6415c_probe(struct i2c_client *client, 144static int tea6415c_probe(struct i2c_client *client,
146 const struct i2c_device_id *id) 145 const struct i2c_device_id *id)
147{ 146{
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index ced6eadf347a..0446524d3543 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -112,7 +112,6 @@ static const struct v4l2_subdev_ops tea6420_ops = {
112 .audio = &tea6420_audio_ops, 112 .audio = &tea6420_audio_ops,
113}; 113};
114 114
115/* this function is called by i2c_probe */
116static int tea6420_probe(struct i2c_client *client, 115static int tea6420_probe(struct i2c_client *client,
117 const struct i2c_device_id *id) 116 const struct i2c_device_id *id)
118{ 117{
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c
new file mode 100644
index 000000000000..21781f8a0e8e
--- /dev/null
+++ b/drivers/media/video/ths7303.c
@@ -0,0 +1,151 @@
1/*
2 * ths7303- THS7303 Video Amplifier driver
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
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 as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/ctype.h>
19#include <linux/i2c.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/module.h>
23#include <linux/uaccess.h>
24#include <linux/videodev2.h>
25
26#include <media/v4l2-device.h>
27#include <media/v4l2-subdev.h>
28#include <media/v4l2-chip-ident.h>
29
30MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
31MODULE_AUTHOR("Chaithrika U S");
32MODULE_LICENSE("GPL");
33
34static int debug;
35module_param(debug, int, 0644);
36MODULE_PARM_DESC(debug, "Debug level 0-1");
37
38/* following function is used to set ths7303 */
39static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std)
40{
41 int err = 0;
42 u8 val;
43 struct i2c_client *client;
44
45 client = v4l2_get_subdevdata(sd);
46
47 if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
48 val = 0x02;
49 v4l2_dbg(1, debug, sd, "setting value for SDTV format\n");
50 } else {
51 val = 0x00;
52 v4l2_dbg(1, debug, sd, "disabling all channels\n");
53 }
54
55 err |= i2c_smbus_write_byte_data(client, 0x01, val);
56 err |= i2c_smbus_write_byte_data(client, 0x02, val);
57 err |= i2c_smbus_write_byte_data(client, 0x03, val);
58
59 if (err)
60 v4l2_err(sd, "write failed\n");
61
62 return err;
63}
64
65static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
66{
67 return ths7303_setvalue(sd, norm);
68}
69
70static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
71 struct v4l2_dbg_chip_ident *chip)
72{
73 struct i2c_client *client = v4l2_get_subdevdata(sd);
74
75 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7303, 0);
76}
77
78static const struct v4l2_subdev_video_ops ths7303_video_ops = {
79 .s_std_output = ths7303_s_std_output,
80};
81
82static const struct v4l2_subdev_core_ops ths7303_core_ops = {
83 .g_chip_ident = ths7303_g_chip_ident,
84};
85
86static const struct v4l2_subdev_ops ths7303_ops = {
87 .core = &ths7303_core_ops,
88 .video = &ths7303_video_ops,
89};
90
91static int ths7303_probe(struct i2c_client *client,
92 const struct i2c_device_id *id)
93{
94 struct v4l2_subdev *sd;
95 v4l2_std_id std_id = V4L2_STD_NTSC;
96
97 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
98 return -ENODEV;
99
100 v4l_info(client, "chip found @ 0x%x (%s)\n",
101 client->addr << 1, client->adapter->name);
102
103 sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
104 if (sd == NULL)
105 return -ENOMEM;
106
107 v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
108
109 return ths7303_setvalue(sd, std_id);
110}
111
112static int ths7303_remove(struct i2c_client *client)
113{
114 struct v4l2_subdev *sd = i2c_get_clientdata(client);
115
116 v4l2_device_unregister_subdev(sd);
117 kfree(sd);
118
119 return 0;
120}
121
122static const struct i2c_device_id ths7303_id[] = {
123 {"ths7303", 0},
124 {},
125};
126
127MODULE_DEVICE_TABLE(i2c, ths7303_id);
128
129static struct i2c_driver ths7303_driver = {
130 .driver = {
131 .owner = THIS_MODULE,
132 .name = "ths7303",
133 },
134 .probe = ths7303_probe,
135 .remove = ths7303_remove,
136 .id_table = ths7303_id,
137};
138
139static int __init ths7303_init(void)
140{
141 return i2c_add_driver(&ths7303_driver);
142}
143
144static void __exit ths7303_exit(void)
145{
146 i2c_del_driver(&ths7303_driver);
147}
148
149module_init(ths7303_init);
150module_exit(ths7303_exit);
151
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 78c377a399cb..537594211a90 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -309,32 +309,6 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
309 } 309 }
310} 310}
311 311
312static void tuner_i2c_address_check(struct tuner *t)
313{
314 if ((t->type == UNSET || t->type == TUNER_ABSENT) ||
315 ((t->i2c->addr < 0x64) || (t->i2c->addr > 0x6f)))
316 return;
317
318 /* We already know that the XC5000 can only be located at
319 * i2c address 0x61, 0x62, 0x63 or 0x64 */
320 if ((t->type == TUNER_XC5000) &&
321 ((t->i2c->addr <= 0x64)) && (t->i2c->addr >= 0x61))
322 return;
323
324 tuner_warn("====================== WARNING! ======================\n");
325 tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n");
326 tuner_warn("will soon be dropped. This message indicates that your\n");
327 tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n",
328 t->name, t->i2c->addr);
329 tuner_warn("To ensure continued support for your device, please\n");
330 tuner_warn("send a copy of this message, along with full dmesg\n");
331 tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n");
332 tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n");
333 tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n",
334 t->i2c->adapter->name, t->i2c->addr, t->type, t->name);
335 tuner_warn("====================== WARNING! ======================\n");
336}
337
338static struct xc5000_config xc5000_cfg; 312static struct xc5000_config xc5000_cfg;
339 313
340static void set_type(struct i2c_client *c, unsigned int type, 314static void set_type(struct i2c_client *c, unsigned int type,
@@ -438,18 +412,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
438 break; 412 break;
439 case TUNER_XC5000: 413 case TUNER_XC5000:
440 { 414 {
441 struct dvb_tuner_ops *xc_tuner_ops;
442
443 xc5000_cfg.i2c_address = t->i2c->addr; 415 xc5000_cfg.i2c_address = t->i2c->addr;
444 /* if_khz will be set when the digital dvb_attach() occurs */ 416 /* if_khz will be set when the digital dvb_attach() occurs */
445 xc5000_cfg.if_khz = 0; 417 xc5000_cfg.if_khz = 0;
446 if (!dvb_attach(xc5000_attach, 418 if (!dvb_attach(xc5000_attach,
447 &t->fe, t->i2c->adapter, &xc5000_cfg)) 419 &t->fe, t->i2c->adapter, &xc5000_cfg))
448 goto attach_failed; 420 goto attach_failed;
449
450 xc_tuner_ops = &t->fe.ops.tuner_ops;
451 if (xc_tuner_ops->init)
452 xc_tuner_ops->init(&t->fe);
453 break; 421 break;
454 } 422 }
455 default: 423 default:
@@ -490,7 +458,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
490 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", 458 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
491 c->adapter->name, c->driver->driver.name, c->addr << 1, type, 459 c->adapter->name, c->driver->driver.name, c->addr << 1, type,
492 t->mode_mask); 460 t->mode_mask);
493 tuner_i2c_address_check(t);
494 return; 461 return;
495 462
496attach_failed: 463attach_failed:
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index e24a38c7fa46..ac02808106c1 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -184,7 +184,7 @@ hauppauge_tuner[] =
184 { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, 184 { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"},
185 { TUNER_ABSENT, "Thompson DTT757"}, 185 { TUNER_ABSENT, "Thompson DTT757"},
186 /* 80-89 */ 186 /* 80-89 */
187 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216LME MK3"}, 187 { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK3"},
188 { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, 188 { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
189 { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, 189 { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, 190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
@@ -210,7 +210,7 @@ hauppauge_tuner[] =
210 { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, 210 { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
211 { TUNER_ABSENT, "Panasonic ENV57H12D5"}, 211 { TUNER_ABSENT, "Panasonic ENV57H12D5"},
212 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, 212 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
213 { TUNER_ABSENT, "TCL MNM05-4"}, 213 { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"},
214 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, 214 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
215 { TUNER_ABSENT, "TCL MQNM05-4"}, 215 { TUNER_ABSENT, "TCL MQNM05-4"},
216 { TUNER_ABSENT, "LG TAPC-W701D"}, 216 { TUNER_ABSENT, "LG TAPC-W701D"},
@@ -229,7 +229,7 @@ hauppauge_tuner[] =
229 { TUNER_ABSENT, "Samsung THPD5222FG30A"}, 229 { TUNER_ABSENT, "Samsung THPD5222FG30A"},
230 /* 120-129 */ 230 /* 120-129 */
231 { TUNER_XC2028, "Xceive XC3028"}, 231 { TUNER_XC2028, "Xceive XC3028"},
232 { TUNER_ABSENT, "Philips FQ1216LME MK5"}, 232 { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK5"},
233 { TUNER_ABSENT, "Philips FQD1216LME"}, 233 { TUNER_ABSENT, "Philips FQD1216LME"},
234 { TUNER_ABSENT, "Conexant CX24118A"}, 234 { TUNER_ABSENT, "Conexant CX24118A"},
235 { TUNER_ABSENT, "TCL DMF11WIP"}, 235 { TUNER_ABSENT, "TCL DMF11WIP"},
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 4262e60b8116..3750f7fadb12 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -692,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
692 break; /* Input detected */ 692 break; /* Input detected */
693 } 693 }
694 694
695 if ((current_std == STD_INVALID) || (try_count <= 0)) 695 if ((current_std == STD_INVALID) || (try_count < 0))
696 return -EINVAL; 696 return -EINVAL;
697 697
698 decoder->current_std = current_std; 698 decoder->current_std = current_std;
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 900ec2129ca1..31d57f2d09e1 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -240,7 +240,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
240 input_dev->dev.parent = &dev->dev; 240 input_dev->dev.parent = &dev->dev;
241 241
242 input_dev->evbit[0] = BIT_MASK(EV_KEY); 242 input_dev->evbit[0] = BIT_MASK(EV_KEY);
243 input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); 243 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
244 244
245 error = input_register_device(cam->input); 245 error = input_register_device(cam->input);
246 if (error) { 246 if (error) {
@@ -263,7 +263,7 @@ static void konicawc_unregister_input(struct konicawc *cam)
263static void konicawc_report_buttonstat(struct konicawc *cam) 263static void konicawc_report_buttonstat(struct konicawc *cam)
264{ 264{
265 if (cam->input) { 265 if (cam->input) {
266 input_report_key(cam->input, BTN_0, cam->buttonsts); 266 input_report_key(cam->input, KEY_CAMERA, cam->buttonsts);
267 input_sync(cam->input); 267 input_sync(cam->input);
268 } 268 }
269} 269}
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index fd112f0b9d35..803d3e4e29a2 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -103,7 +103,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
103 input_dev->dev.parent = &dev->dev; 103 input_dev->dev.parent = &dev->dev;
104 104
105 input_dev->evbit[0] = BIT_MASK(EV_KEY); 105 input_dev->evbit[0] = BIT_MASK(EV_KEY);
106 input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); 106 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
107 107
108 error = input_register_device(cam->input); 108 error = input_register_device(cam->input);
109 if (error) { 109 if (error) {
@@ -126,7 +126,7 @@ static void qcm_unregister_input(struct qcm *cam)
126static void qcm_report_buttonstat(struct qcm *cam) 126static void qcm_report_buttonstat(struct qcm *cam)
127{ 127{
128 if (cam->input) { 128 if (cam->input) {
129 input_report_key(cam->input, BTN_0, cam->button_sts); 129 input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
130 input_sync(cam->input); 130 input_sync(cam->input);
131 } 131 }
132} 132}
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 8bc03b9e1315..6ba16abeebdd 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -390,10 +390,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
390 390
391void usbvision_scratch_free(struct usb_usbvision *usbvision) 391void usbvision_scratch_free(struct usb_usbvision *usbvision)
392{ 392{
393 if (usbvision->scratch != NULL) { 393 vfree(usbvision->scratch);
394 vfree(usbvision->scratch); 394 usbvision->scratch = NULL;
395 usbvision->scratch = NULL; 395
396 }
397} 396}
398 397
399/* 398/*
@@ -506,10 +505,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
506 */ 505 */
507void usbvision_decompress_free(struct usb_usbvision *usbvision) 506void usbvision_decompress_free(struct usb_usbvision *usbvision)
508{ 507{
509 if (usbvision->IntraFrameBuffer != NULL) { 508 vfree(usbvision->IntraFrameBuffer);
510 vfree(usbvision->IntraFrameBuffer); 509 usbvision->IntraFrameBuffer = NULL;
511 usbvision->IntraFrameBuffer = NULL; 510
512 }
513} 511}
514 512
515/************************************************************ 513/************************************************************
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index d7056a5b7f9b..90b58914f984 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -541,7 +541,7 @@ static int vidioc_enum_input (struct file *file, void *priv,
541 struct usb_usbvision *usbvision = video_drvdata(file); 541 struct usb_usbvision *usbvision = video_drvdata(file);
542 int chan; 542 int chan;
543 543
544 if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) ) 544 if (vi->index >= usbvision->video_inputs)
545 return -EINVAL; 545 return -EINVAL;
546 if (usbvision->have_tuner) { 546 if (usbvision->have_tuner) {
547 chan = vi->index; 547 chan = vi->index;
@@ -1794,7 +1794,7 @@ static struct usb_driver usbvision_driver = {
1794 .name = "usbvision", 1794 .name = "usbvision",
1795 .id_table = usbvision_table, 1795 .id_table = usbvision_table,
1796 .probe = usbvision_probe, 1796 .probe = usbvision_probe,
1797 .disconnect = usbvision_disconnect 1797 .disconnect = __devexit_p(usbvision_disconnect),
1798}; 1798};
1799 1799
1800/* 1800/*
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 0d7e38d6ff6a..36a6ba92df27 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1372,21 +1372,19 @@ end:
1372} 1372}
1373 1373
1374/* 1374/*
1375 * Prune an entity of its bogus controls. This currently includes processing 1375 * Prune an entity of its bogus controls using a blacklist. Bogus controls
1376 * unit auto controls for which no corresponding manual control is available. 1376 * are currently the ones that crash the camera or unconditionally return an
1377 * Such auto controls make little sense if any, and are known to crash at 1377 * error when queried.
1378 * least the SiGma Micro webcam.
1379 */ 1378 */
1380static void 1379static void
1381uvc_ctrl_prune_entity(struct uvc_entity *entity) 1380uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
1382{ 1381{
1383 static const struct { 1382 static const struct {
1384 u8 idx_manual; 1383 struct usb_device_id id;
1385 u8 idx_auto; 1384 u8 index;
1386 } blacklist[] = { 1385 } blacklist[] = {
1387 { 2, 11 }, /* Hue */ 1386 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
1388 { 6, 12 }, /* White Balance Temperature */ 1387 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
1389 { 7, 13 }, /* White Balance Component */
1390 }; 1388 };
1391 1389
1392 u8 *controls; 1390 u8 *controls;
@@ -1400,19 +1398,17 @@ uvc_ctrl_prune_entity(struct uvc_entity *entity)
1400 size = entity->processing.bControlSize; 1398 size = entity->processing.bControlSize;
1401 1399
1402 for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { 1400 for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
1403 if (blacklist[i].idx_auto >= 8 * size || 1401 if (!usb_match_id(dev->intf, &blacklist[i].id))
1404 blacklist[i].idx_manual >= 8 * size)
1405 continue; 1402 continue;
1406 1403
1407 if (!uvc_test_bit(controls, blacklist[i].idx_auto) || 1404 if (blacklist[i].index >= 8 * size ||
1408 uvc_test_bit(controls, blacklist[i].idx_manual)) 1405 !uvc_test_bit(controls, blacklist[i].index))
1409 continue; 1406 continue;
1410 1407
1411 uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no " 1408 uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
1412 "matching manual control, removing it.\n", entity->id, 1409 "removing it.\n", entity->id, blacklist[i].index);
1413 blacklist[i].idx_auto);
1414 1410
1415 uvc_clear_bit(controls, blacklist[i].idx_auto); 1411 uvc_clear_bit(controls, blacklist[i].index);
1416 } 1412 }
1417} 1413}
1418 1414
@@ -1442,8 +1438,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
1442 bControlSize = entity->camera.bControlSize; 1438 bControlSize = entity->camera.bControlSize;
1443 } 1439 }
1444 1440
1445 if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS) 1441 uvc_ctrl_prune_entity(dev, entity);
1446 uvc_ctrl_prune_entity(entity);
1447 1442
1448 for (i = 0; i < bControlSize; ++i) 1443 for (i = 0; i < bControlSize; ++i)
1449 ncontrols += hweight8(bmControls[i]); 1444 ncontrols += hweight8(bmControls[i]);
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 507dc85646b2..89927b7aec28 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -289,10 +289,8 @@ static int uvc_parse_format(struct uvc_device *dev,
289 struct uvc_format_desc *fmtdesc; 289 struct uvc_format_desc *fmtdesc;
290 struct uvc_frame *frame; 290 struct uvc_frame *frame;
291 const unsigned char *start = buffer; 291 const unsigned char *start = buffer;
292 unsigned char *_buffer;
293 unsigned int interval; 292 unsigned int interval;
294 unsigned int i, n; 293 unsigned int i, n;
295 int _buflen;
296 __u8 ftype; 294 __u8 ftype;
297 295
298 format->type = buffer[2]; 296 format->type = buffer[2];
@@ -303,7 +301,7 @@ static int uvc_parse_format(struct uvc_device *dev,
303 case VS_FORMAT_FRAME_BASED: 301 case VS_FORMAT_FRAME_BASED:
304 n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; 302 n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28;
305 if (buflen < n) { 303 if (buflen < n) {
306 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 304 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
307 "interface %d FORMAT error\n", 305 "interface %d FORMAT error\n",
308 dev->udev->devnum, 306 dev->udev->devnum,
309 alts->desc.bInterfaceNumber); 307 alts->desc.bInterfaceNumber);
@@ -338,7 +336,7 @@ static int uvc_parse_format(struct uvc_device *dev,
338 336
339 case VS_FORMAT_MJPEG: 337 case VS_FORMAT_MJPEG:
340 if (buflen < 11) { 338 if (buflen < 11) {
341 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 339 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
342 "interface %d FORMAT error\n", 340 "interface %d FORMAT error\n",
343 dev->udev->devnum, 341 dev->udev->devnum,
344 alts->desc.bInterfaceNumber); 342 alts->desc.bInterfaceNumber);
@@ -354,7 +352,7 @@ static int uvc_parse_format(struct uvc_device *dev,
354 352
355 case VS_FORMAT_DV: 353 case VS_FORMAT_DV:
356 if (buflen < 9) { 354 if (buflen < 9) {
357 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 355 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
358 "interface %d FORMAT error\n", 356 "interface %d FORMAT error\n",
359 dev->udev->devnum, 357 dev->udev->devnum,
360 alts->desc.bInterfaceNumber); 358 alts->desc.bInterfaceNumber);
@@ -372,7 +370,7 @@ static int uvc_parse_format(struct uvc_device *dev,
372 strlcpy(format->name, "HD-DV", sizeof format->name); 370 strlcpy(format->name, "HD-DV", sizeof format->name);
373 break; 371 break;
374 default: 372 default:
375 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 373 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
376 "interface %d: unknown DV format %u\n", 374 "interface %d: unknown DV format %u\n",
377 dev->udev->devnum, 375 dev->udev->devnum,
378 alts->desc.bInterfaceNumber, buffer[8]); 376 alts->desc.bInterfaceNumber, buffer[8]);
@@ -401,7 +399,7 @@ static int uvc_parse_format(struct uvc_device *dev,
401 case VS_FORMAT_STREAM_BASED: 399 case VS_FORMAT_STREAM_BASED:
402 /* Not supported yet. */ 400 /* Not supported yet. */
403 default: 401 default:
404 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 402 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
405 "interface %d unsupported format %u\n", 403 "interface %d unsupported format %u\n",
406 dev->udev->devnum, alts->desc.bInterfaceNumber, 404 dev->udev->devnum, alts->desc.bInterfaceNumber,
407 buffer[2]); 405 buffer[2]);
@@ -413,20 +411,11 @@ static int uvc_parse_format(struct uvc_device *dev,
413 buflen -= buffer[0]; 411 buflen -= buffer[0];
414 buffer += buffer[0]; 412 buffer += buffer[0];
415 413
416 /* Count the number of frame descriptors to test the bFrameIndex
417 * field when parsing the descriptors. We can't rely on the
418 * bNumFrameDescriptors field as some cameras don't initialize it
419 * properly.
420 */
421 for (_buflen = buflen, _buffer = buffer;
422 _buflen > 2 && _buffer[2] == ftype;
423 _buflen -= _buffer[0], _buffer += _buffer[0])
424 format->nframes++;
425
426 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame 414 /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
427 * based formats have frame descriptors. 415 * based formats have frame descriptors.
428 */ 416 */
429 while (buflen > 2 && buffer[2] == ftype) { 417 while (buflen > 2 && buffer[2] == ftype) {
418 frame = &format->frame[format->nframes];
430 if (ftype != VS_FRAME_FRAME_BASED) 419 if (ftype != VS_FRAME_FRAME_BASED)
431 n = buflen > 25 ? buffer[25] : 0; 420 n = buflen > 25 ? buffer[25] : 0;
432 else 421 else
@@ -435,22 +424,12 @@ static int uvc_parse_format(struct uvc_device *dev,
435 n = n ? n : 3; 424 n = n ? n : 3;
436 425
437 if (buflen < 26 + 4*n) { 426 if (buflen < 26 + 4*n) {
438 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 427 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
439 "interface %d FRAME error\n", dev->udev->devnum, 428 "interface %d FRAME error\n", dev->udev->devnum,
440 alts->desc.bInterfaceNumber); 429 alts->desc.bInterfaceNumber);
441 return -EINVAL; 430 return -EINVAL;
442 } 431 }
443 432
444 if (buffer[3] - 1 >= format->nframes) {
445 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
446 "interface %d frame index %u out of range\n",
447 dev->udev->devnum, alts->desc.bInterfaceNumber,
448 buffer[3]);
449 return -EINVAL;
450 }
451
452 frame = &format->frame[buffer[3] - 1];
453
454 frame->bFrameIndex = buffer[3]; 433 frame->bFrameIndex = buffer[3];
455 frame->bmCapabilities = buffer[4]; 434 frame->bmCapabilities = buffer[4];
456 frame->wWidth = get_unaligned_le16(&buffer[5]); 435 frame->wWidth = get_unaligned_le16(&buffer[5]);
@@ -507,6 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
507 10000000/frame->dwDefaultFrameInterval, 486 10000000/frame->dwDefaultFrameInterval,
508 (100000000/frame->dwDefaultFrameInterval)%10); 487 (100000000/frame->dwDefaultFrameInterval)%10);
509 488
489 format->nframes++;
510 buflen -= buffer[0]; 490 buflen -= buffer[0];
511 buffer += buffer[0]; 491 buffer += buffer[0];
512 } 492 }
@@ -518,7 +498,7 @@ static int uvc_parse_format(struct uvc_device *dev,
518 498
519 if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { 499 if (buflen > 2 && buffer[2] == VS_COLORFORMAT) {
520 if (buflen < 6) { 500 if (buflen < 6) {
521 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" 501 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
522 "interface %d COLORFORMAT error\n", 502 "interface %d COLORFORMAT error\n",
523 dev->udev->devnum, 503 dev->udev->devnum,
524 alts->desc.bInterfaceNumber); 504 alts->desc.bInterfaceNumber);
@@ -664,7 +644,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
664 _buflen = buflen; 644 _buflen = buflen;
665 645
666 /* Count the format and frame descriptors. */ 646 /* Count the format and frame descriptors. */
667 while (_buflen > 2) { 647 while (_buflen > 2 && _buffer[1] == CS_INTERFACE) {
668 switch (_buffer[2]) { 648 switch (_buffer[2]) {
669 case VS_FORMAT_UNCOMPRESSED: 649 case VS_FORMAT_UNCOMPRESSED:
670 case VS_FORMAT_MJPEG: 650 case VS_FORMAT_MJPEG:
@@ -729,7 +709,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
729 streaming->nformats = nformats; 709 streaming->nformats = nformats;
730 710
731 /* Parse the format descriptors. */ 711 /* Parse the format descriptors. */
732 while (buflen > 2) { 712 while (buflen > 2 && buffer[1] == CS_INTERFACE) {
733 switch (buffer[2]) { 713 switch (buffer[2]) {
734 case VS_FORMAT_UNCOMPRESSED: 714 case VS_FORMAT_UNCOMPRESSED:
735 case VS_FORMAT_MJPEG: 715 case VS_FORMAT_MJPEG:
@@ -1316,7 +1296,7 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
1316 continue; 1296 continue;
1317 1297
1318 if (forward->extension.bNrInPins != 1) { 1298 if (forward->extension.bNrInPins != 1) {
1319 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has" 1299 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has "
1320 "more than 1 input pin.\n", entity->id); 1300 "more than 1 input pin.\n", entity->id);
1321 return -1; 1301 return -1;
1322 } 1302 }
@@ -1614,6 +1594,7 @@ static int uvc_probe(struct usb_interface *intf,
1614 INIT_LIST_HEAD(&dev->entities); 1594 INIT_LIST_HEAD(&dev->entities);
1615 INIT_LIST_HEAD(&dev->streaming); 1595 INIT_LIST_HEAD(&dev->streaming);
1616 kref_init(&dev->kref); 1596 kref_init(&dev->kref);
1597 atomic_set(&dev->users, 0);
1617 1598
1618 dev->udev = usb_get_dev(udev); 1599 dev->udev = usb_get_dev(udev);
1619 dev->intf = usb_get_intf(intf); 1600 dev->intf = usb_get_intf(intf);
@@ -1927,7 +1908,7 @@ static struct usb_device_id uvc_ids[] = {
1927 .bInterfaceSubClass = 1, 1908 .bInterfaceSubClass = 1,
1928 .bInterfaceProtocol = 0, 1909 .bInterfaceProtocol = 0,
1929 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 1910 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1930 /* Lenovo Thinkpad SL500 */ 1911 /* Lenovo Thinkpad SL400/SL500 */
1931 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1912 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1932 | USB_DEVICE_ID_MATCH_INT_INFO, 1913 | USB_DEVICE_ID_MATCH_INT_INFO,
1933 .idVendor = 0x17ef, 1914 .idVendor = 0x17ef,
@@ -1936,6 +1917,15 @@ static struct usb_device_id uvc_ids[] = {
1936 .bInterfaceSubClass = 1, 1917 .bInterfaceSubClass = 1,
1937 .bInterfaceProtocol = 0, 1918 .bInterfaceProtocol = 0,
1938 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 1919 .driver_info = UVC_QUIRK_STREAM_NO_FID },
1920 /* Aveo Technology USB 2.0 Camera */
1921 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1922 | USB_DEVICE_ID_MATCH_INT_INFO,
1923 .idVendor = 0x1871,
1924 .idProduct = 0x0306,
1925 .bInterfaceClass = USB_CLASS_VIDEO,
1926 .bInterfaceSubClass = 1,
1927 .bInterfaceProtocol = 0,
1928 .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
1939 /* Ecamm Pico iMage */ 1929 /* Ecamm Pico iMage */
1940 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1930 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1941 | USB_DEVICE_ID_MATCH_INT_INFO, 1931 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1945,6 +1935,15 @@ static struct usb_device_id uvc_ids[] = {
1945 .bInterfaceSubClass = 1, 1935 .bInterfaceSubClass = 1,
1946 .bInterfaceProtocol = 0, 1936 .bInterfaceProtocol = 0,
1947 .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, 1937 .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
1938 /* FSC WebCam V30S */
1939 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1940 | USB_DEVICE_ID_MATCH_INT_INFO,
1941 .idVendor = 0x18ec,
1942 .idProduct = 0x3288,
1943 .bInterfaceClass = USB_CLASS_VIDEO,
1944 .bInterfaceSubClass = 1,
1945 .bInterfaceProtocol = 0,
1946 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1948 /* Bodelin ProScopeHR */ 1947 /* Bodelin ProScopeHR */
1949 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1948 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1950 | USB_DEVICE_ID_MATCH_DEV_HI 1949 | USB_DEVICE_ID_MATCH_DEV_HI
@@ -1965,8 +1964,7 @@ static struct usb_device_id uvc_ids[] = {
1965 .bInterfaceSubClass = 1, 1964 .bInterfaceSubClass = 1,
1966 .bInterfaceProtocol = 0, 1965 .bInterfaceProtocol = 0,
1967 .driver_info = UVC_QUIRK_PROBE_MINMAX 1966 .driver_info = UVC_QUIRK_PROBE_MINMAX
1968 | UVC_QUIRK_IGNORE_SELECTOR_UNIT 1967 | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
1969 | UVC_QUIRK_PRUNE_CONTROLS },
1970 /* Generic USB Video Class */ 1968 /* Generic USB Video Class */
1971 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, 1969 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
1972 {} 1970 {}
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 0155752e4a5a..f854698c4061 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -172,6 +172,20 @@ int uvc_free_buffers(struct uvc_video_queue *queue)
172 return 0; 172 return 0;
173} 173}
174 174
175/*
176 * Check if buffers have been allocated.
177 */
178int uvc_queue_allocated(struct uvc_video_queue *queue)
179{
180 int allocated;
181
182 mutex_lock(&queue->mutex);
183 allocated = queue->count != 0;
184 mutex_unlock(&queue->mutex);
185
186 return allocated;
187}
188
175static void __uvc_query_buffer(struct uvc_buffer *buf, 189static void __uvc_query_buffer(struct uvc_buffer *buf,
176 struct v4l2_buffer *v4l2_buf) 190 struct v4l2_buffer *v4l2_buf)
177{ 191{
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 21d87124986b..f152a9903862 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -194,7 +194,7 @@ int uvc_status_init(struct uvc_device *dev)
194 dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, 194 dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
195 dev, interval); 195 dev, interval);
196 196
197 return usb_submit_urb(dev->int_urb, GFP_KERNEL); 197 return 0;
198} 198}
199 199
200void uvc_status_cleanup(struct uvc_device *dev) 200void uvc_status_cleanup(struct uvc_device *dev)
@@ -205,15 +205,30 @@ void uvc_status_cleanup(struct uvc_device *dev)
205 uvc_input_cleanup(dev); 205 uvc_input_cleanup(dev);
206} 206}
207 207
208int uvc_status_suspend(struct uvc_device *dev) 208int uvc_status_start(struct uvc_device *dev)
209{
210 if (dev->int_urb == NULL)
211 return 0;
212
213 return usb_submit_urb(dev->int_urb, GFP_KERNEL);
214}
215
216void uvc_status_stop(struct uvc_device *dev)
209{ 217{
210 usb_kill_urb(dev->int_urb); 218 usb_kill_urb(dev->int_urb);
219}
220
221int uvc_status_suspend(struct uvc_device *dev)
222{
223 if (atomic_read(&dev->users))
224 usb_kill_urb(dev->int_urb);
225
211 return 0; 226 return 0;
212} 227}
213 228
214int uvc_status_resume(struct uvc_device *dev) 229int uvc_status_resume(struct uvc_device *dev)
215{ 230{
216 if (dev->int_urb == NULL) 231 if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
217 return 0; 232 return 0;
218 233
219 return usb_submit_urb(dev->int_urb, GFP_NOIO); 234 return usb_submit_urb(dev->int_urb, GFP_NOIO);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 2a80caa54fb4..5e77cad29690 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -46,6 +46,8 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
46 struct uvc_menu_info *menu_info; 46 struct uvc_menu_info *menu_info;
47 struct uvc_control_mapping *mapping; 47 struct uvc_control_mapping *mapping;
48 struct uvc_control *ctrl; 48 struct uvc_control *ctrl;
49 u32 index = query_menu->index;
50 u32 id = query_menu->id;
49 51
50 ctrl = uvc_find_control(video, query_menu->id, &mapping); 52 ctrl = uvc_find_control(video, query_menu->id, &mapping);
51 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) 53 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
@@ -54,6 +56,10 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
54 if (query_menu->index >= mapping->menu_count) 56 if (query_menu->index >= mapping->menu_count)
55 return -EINVAL; 57 return -EINVAL;
56 58
59 memset(query_menu, 0, sizeof(*query_menu));
60 query_menu->id = id;
61 query_menu->index = index;
62
57 menu_info = &mapping->menu_info[query_menu->index]; 63 menu_info = &mapping->menu_info[query_menu->index];
58 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); 64 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
59 return 0; 65 return 0;
@@ -245,7 +251,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
245 if (fmt->type != video->streaming->type) 251 if (fmt->type != video->streaming->type)
246 return -EINVAL; 252 return -EINVAL;
247 253
248 if (uvc_queue_streaming(&video->queue)) 254 if (uvc_queue_allocated(&video->queue))
249 return -EBUSY; 255 return -EBUSY;
250 256
251 ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); 257 ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame);
@@ -433,6 +439,15 @@ static int uvc_v4l2_open(struct file *file)
433 goto done; 439 goto done;
434 } 440 }
435 441
442 if (atomic_inc_return(&video->dev->users) == 1) {
443 if ((ret = uvc_status_start(video->dev)) < 0) {
444 usb_autopm_put_interface(video->dev->intf);
445 atomic_dec(&video->dev->users);
446 kfree(handle);
447 goto done;
448 }
449 }
450
436 handle->device = video; 451 handle->device = video;
437 handle->state = UVC_HANDLE_PASSIVE; 452 handle->state = UVC_HANDLE_PASSIVE;
438 file->private_data = handle; 453 file->private_data = handle;
@@ -467,6 +482,9 @@ static int uvc_v4l2_release(struct file *file)
467 kfree(handle); 482 kfree(handle);
468 file->private_data = NULL; 483 file->private_data = NULL;
469 484
485 if (atomic_dec_return(&video->dev->users) == 0)
486 uvc_status_stop(video->dev);
487
470 usb_autopm_put_interface(video->dev->intf); 488 usb_autopm_put_interface(video->dev->intf);
471 kref_put(&video->dev->kref, uvc_delete); 489 kref_put(&video->dev->kref, uvc_delete);
472 return 0; 490 return 0;
@@ -512,7 +530,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
512 memset(&xctrl, 0, sizeof xctrl); 530 memset(&xctrl, 0, sizeof xctrl);
513 xctrl.id = ctrl->id; 531 xctrl.id = ctrl->id;
514 532
515 uvc_ctrl_begin(video); 533 ret = uvc_ctrl_begin(video);
534 if (ret < 0)
535 return ret;
536
516 ret = uvc_ctrl_get(video, &xctrl); 537 ret = uvc_ctrl_get(video, &xctrl);
517 uvc_ctrl_rollback(video); 538 uvc_ctrl_rollback(video);
518 if (ret >= 0) 539 if (ret >= 0)
@@ -529,7 +550,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
529 xctrl.id = ctrl->id; 550 xctrl.id = ctrl->id;
530 xctrl.value = ctrl->value; 551 xctrl.value = ctrl->value;
531 552
532 uvc_ctrl_begin(video); 553 ret = uvc_ctrl_begin(video);
554 if (ret < 0)
555 return ret;
556
533 ret = uvc_ctrl_set(video, &xctrl); 557 ret = uvc_ctrl_set(video, &xctrl);
534 if (ret < 0) { 558 if (ret < 0) {
535 uvc_ctrl_rollback(video); 559 uvc_ctrl_rollback(video);
@@ -548,7 +572,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
548 struct v4l2_ext_control *ctrl = ctrls->controls; 572 struct v4l2_ext_control *ctrl = ctrls->controls;
549 unsigned int i; 573 unsigned int i;
550 574
551 uvc_ctrl_begin(video); 575 ret = uvc_ctrl_begin(video);
576 if (ret < 0)
577 return ret;
578
552 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 579 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
553 ret = uvc_ctrl_get(video, ctrl); 580 ret = uvc_ctrl_get(video, ctrl);
554 if (ret < 0) { 581 if (ret < 0) {
@@ -648,7 +675,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
648 675
649 case VIDIOC_S_INPUT: 676 case VIDIOC_S_INPUT:
650 { 677 {
651 u8 input = *(u32 *)arg + 1; 678 u32 input = *(u32 *)arg + 1;
652 679
653 if ((ret = uvc_acquire_privileges(handle)) < 0) 680 if ((ret = uvc_acquire_privileges(handle)) < 0)
654 return ret; 681 return ret;
@@ -660,7 +687,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
660 break; 687 break;
661 } 688 }
662 689
663 if (input > video->selector->selector.bNrInPins) 690 if (input == 0 || input > video->selector->selector.bNrInPins)
664 return -EINVAL; 691 return -EINVAL;
665 692
666 return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, 693 return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 6ce974d7362f..01b633c73480 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -65,7 +65,8 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
65 struct uvc_streaming_control *ctrl) 65 struct uvc_streaming_control *ctrl)
66{ 66{
67 struct uvc_format *format; 67 struct uvc_format *format;
68 struct uvc_frame *frame; 68 struct uvc_frame *frame = NULL;
69 unsigned int i;
69 70
70 if (ctrl->bFormatIndex <= 0 || 71 if (ctrl->bFormatIndex <= 0 ||
71 ctrl->bFormatIndex > video->streaming->nformats) 72 ctrl->bFormatIndex > video->streaming->nformats)
@@ -73,11 +74,15 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
73 74
74 format = &video->streaming->format[ctrl->bFormatIndex - 1]; 75 format = &video->streaming->format[ctrl->bFormatIndex - 1];
75 76
76 if (ctrl->bFrameIndex <= 0 || 77 for (i = 0; i < format->nframes; ++i) {
77 ctrl->bFrameIndex > format->nframes) 78 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
78 return; 79 frame = &format->frame[i];
80 break;
81 }
82 }
79 83
80 frame = &format->frame[ctrl->bFrameIndex - 1]; 84 if (frame == NULL)
85 return;
81 86
82 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || 87 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
83 (ctrl->dwMaxVideoFrameSize == 0 && 88 (ctrl->dwMaxVideoFrameSize == 0 &&
@@ -1089,7 +1094,7 @@ int uvc_video_init(struct uvc_video_device *video)
1089 /* Zero bFrameIndex might be correct. Stream-based formats (including 1094 /* Zero bFrameIndex might be correct. Stream-based formats (including
1090 * MPEG-2 TS and DV) do not support frames but have a dummy frame 1095 * MPEG-2 TS and DV) do not support frames but have a dummy frame
1091 * descriptor with bFrameIndex set to zero. If the default frame 1096 * descriptor with bFrameIndex set to zero. If the default frame
1092 * descriptor is not found, use the first avalable frame. 1097 * descriptor is not found, use the first available frame.
1093 */ 1098 */
1094 for (i = format->nframes; i > 0; --i) { 1099 for (i = format->nframes; i > 0; --i) {
1095 frame = &format->frame[i-1]; 1100 frame = &format->frame[i-1];
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index e5014e668f99..3c78d3c1e4c0 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -313,7 +313,6 @@ struct uvc_xu_control {
313#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 313#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008
314#define UVC_QUIRK_STREAM_NO_FID 0x00000010 314#define UVC_QUIRK_STREAM_NO_FID 0x00000010
315#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 315#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
316#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040
317#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 316#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
318 317
319/* Format flags */ 318/* Format flags */
@@ -634,6 +633,7 @@ struct uvc_device {
634 enum uvc_device_state state; 633 enum uvc_device_state state;
635 struct kref kref; 634 struct kref kref;
636 struct list_head list; 635 struct list_head list;
636 atomic_t users;
637 637
638 /* Video control interface */ 638 /* Video control interface */
639 __u16 uvc_version; 639 __u16 uvc_version;
@@ -747,6 +747,7 @@ extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
747 struct uvc_buffer *buf); 747 struct uvc_buffer *buf);
748extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, 748extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
749 struct file *file, poll_table *wait); 749 struct file *file, poll_table *wait);
750extern int uvc_queue_allocated(struct uvc_video_queue *queue);
750static inline int uvc_queue_streaming(struct uvc_video_queue *queue) 751static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
751{ 752{
752 return queue->flags & UVC_QUEUE_STREAMING; 753 return queue->flags & UVC_QUEUE_STREAMING;
@@ -770,6 +771,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
770/* Status */ 771/* Status */
771extern int uvc_status_init(struct uvc_device *dev); 772extern int uvc_status_init(struct uvc_device *dev);
772extern void uvc_status_cleanup(struct uvc_device *dev); 773extern void uvc_status_cleanup(struct uvc_device *dev);
774extern int uvc_status_start(struct uvc_device *dev);
775extern void uvc_status_stop(struct uvc_device *dev);
773extern int uvc_status_suspend(struct uvc_device *dev); 776extern int uvc_status_suspend(struct uvc_device *dev);
774extern int uvc_status_resume(struct uvc_device *dev); 777extern int uvc_status_resume(struct uvc_device *dev);
775 778
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f576ef66b807..f96475626da7 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -746,6 +746,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
746 const struct v4l2_subdev_ops *ops) 746 const struct v4l2_subdev_ops *ops)
747{ 747{
748 v4l2_subdev_init(sd, ops); 748 v4l2_subdev_init(sd, ops);
749 sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
749 /* the owner is the same as the i2c_client's driver owner */ 750 /* the owner is the same as the i2c_client's driver owner */
750 sd->owner = client->driver->driver.owner; 751 sd->owner = client->driver->driver.owner;
751 /* i2c_client and v4l2_subdev point to one another */ 752 /* i2c_client and v4l2_subdev point to one another */
@@ -897,8 +898,7 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
897 }; 898 };
898 static const unsigned short tv_addrs[] = { 899 static const unsigned short tv_addrs[] = {
899 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ 900 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
900 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 901 0x60, 0x61, 0x62, 0x63, 0x64,
901 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
902 I2C_CLIENT_END 902 I2C_CLIENT_END
903 }; 903 };
904 904
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 94aa485ade52..0d06e7cbd5b3 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -49,6 +49,22 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
49} 49}
50EXPORT_SYMBOL_GPL(v4l2_device_register); 50EXPORT_SYMBOL_GPL(v4l2_device_register);
51 51
52int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
53 atomic_t *instance)
54{
55 int num = atomic_inc_return(instance) - 1;
56 int len = strlen(basename);
57
58 if (basename[len - 1] >= '0' && basename[len - 1] <= '9')
59 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
60 "%s-%d", basename, num);
61 else
62 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
63 "%s%d", basename, num);
64 return num;
65}
66EXPORT_SYMBOL_GPL(v4l2_device_set_name);
67
52void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) 68void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
53{ 69{
54 if (v4l2_dev->dev) { 70 if (v4l2_dev->dev) {
@@ -67,8 +83,21 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
67 v4l2_device_disconnect(v4l2_dev); 83 v4l2_device_disconnect(v4l2_dev);
68 84
69 /* Unregister subdevs */ 85 /* Unregister subdevs */
70 list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) 86 list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
71 v4l2_device_unregister_subdev(sd); 87 v4l2_device_unregister_subdev(sd);
88#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
89 if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
90 struct i2c_client *client = v4l2_get_subdevdata(sd);
91
92 /* We need to unregister the i2c client explicitly.
93 We cannot rely on i2c_del_adapter to always
94 unregister clients for us, since if the i2c bus
95 is a platform bus, then it is never deleted. */
96 if (client)
97 i2c_unregister_device(client);
98 }
99#endif
100 }
72} 101}
73EXPORT_SYMBOL_GPL(v4l2_device_unregister); 102EXPORT_SYMBOL_GPL(v4l2_device_unregister);
74 103
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index b7b05842cf28..f1ccf98c0a6f 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -118,6 +118,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
118 void *priv, 118 void *priv,
119 struct videobuf_qtype_ops *int_ops) 119 struct videobuf_qtype_ops *int_ops)
120{ 120{
121 BUG_ON(!q);
121 memset(q, 0, sizeof(*q)); 122 memset(q, 0, sizeof(*q));
122 q->irqlock = irqlock; 123 q->irqlock = irqlock;
123 q->dev = dev; 124 q->dev = dev;
@@ -439,6 +440,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
439 } 440 }
440 441
441 req->count = retval; 442 req->count = retval;
443 retval = 0;
442 444
443 done: 445 done:
444 mutex_unlock(&q->vb_lock); 446 mutex_unlock(&q->vb_lock);
@@ -454,7 +456,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
454 dprintk(1, "querybuf: Wrong type.\n"); 456 dprintk(1, "querybuf: Wrong type.\n");
455 goto done; 457 goto done;
456 } 458 }
457 if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { 459 if (unlikely(b->index >= VIDEO_MAX_FRAME)) {
458 dprintk(1, "querybuf: index out of range.\n"); 460 dprintk(1, "querybuf: index out of range.\n");
459 goto done; 461 goto done;
460 } 462 }
@@ -495,7 +497,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
495 dprintk(1, "qbuf: Wrong type.\n"); 497 dprintk(1, "qbuf: Wrong type.\n");
496 goto done; 498 goto done;
497 } 499 }
498 if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) { 500 if (b->index >= VIDEO_MAX_FRAME) {
499 dprintk(1, "qbuf: index out of range.\n"); 501 dprintk(1, "qbuf: index out of range.\n");
500 goto done; 502 goto done;
501 } 503 }
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 0c29a019bc89..d09ce83a9429 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -259,19 +259,6 @@ static int __videobuf_iolock(struct videobuf_queue *q,
259 return 0; 259 return 0;
260} 260}
261 261
262static int __videobuf_sync(struct videobuf_queue *q,
263 struct videobuf_buffer *buf)
264{
265 struct videobuf_dma_contig_memory *mem = buf->priv;
266
267 BUG_ON(!mem);
268 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
269
270 dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
271 DMA_FROM_DEVICE);
272 return 0;
273}
274
275static int __videobuf_mmap_free(struct videobuf_queue *q) 262static int __videobuf_mmap_free(struct videobuf_queue *q)
276{ 263{
277 unsigned int i; 264 unsigned int i;
@@ -433,7 +420,6 @@ static struct videobuf_qtype_ops qops = {
433 420
434 .alloc = __videobuf_alloc, 421 .alloc = __videobuf_alloc,
435 .iolock = __videobuf_iolock, 422 .iolock = __videobuf_iolock,
436 .sync = __videobuf_sync,
437 .mmap_free = __videobuf_mmap_free, 423 .mmap_free = __videobuf_mmap_free,
438 .mmap_mapper = __videobuf_mmap_mapper, 424 .mmap_mapper = __videobuf_mmap_mapper,
439 .video_copy_to_user = __videobuf_copy_to_user, 425 .video_copy_to_user = __videobuf_copy_to_user,
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index da1790e57a86..a8dd22ace3fb 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -58,9 +58,10 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
58 struct page *pg; 58 struct page *pg;
59 int i; 59 int i;
60 60
61 sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL); 61 sglist = vmalloc(nr_pages * sizeof(*sglist));
62 if (NULL == sglist) 62 if (NULL == sglist)
63 return NULL; 63 return NULL;
64 memset(sglist, 0, nr_pages * sizeof(*sglist));
64 sg_init_table(sglist, nr_pages); 65 sg_init_table(sglist, nr_pages);
65 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { 66 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
66 pg = vmalloc_to_page(virt); 67 pg = vmalloc_to_page(virt);
@@ -72,7 +73,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
72 return sglist; 73 return sglist;
73 74
74 err: 75 err:
75 kfree(sglist); 76 vfree(sglist);
76 return NULL; 77 return NULL;
77} 78}
78 79
@@ -84,7 +85,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
84 85
85 if (NULL == pages[0]) 86 if (NULL == pages[0])
86 return NULL; 87 return NULL;
87 sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL); 88 sglist = vmalloc(nr_pages * sizeof(*sglist));
88 if (NULL == sglist) 89 if (NULL == sglist)
89 return NULL; 90 return NULL;
90 sg_init_table(sglist, nr_pages); 91 sg_init_table(sglist, nr_pages);
@@ -104,12 +105,12 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
104 105
105 nopage: 106 nopage:
106 dprintk(2,"sgl: oops - no page\n"); 107 dprintk(2,"sgl: oops - no page\n");
107 kfree(sglist); 108 vfree(sglist);
108 return NULL; 109 return NULL;
109 110
110 highmem: 111 highmem:
111 dprintk(2,"sgl: oops - highmem page\n"); 112 dprintk(2,"sgl: oops - highmem page\n");
112 kfree(sglist); 113 vfree(sglist);
113 return NULL; 114 return NULL;
114} 115}
115 116
@@ -230,7 +231,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
230 (dma->vmalloc,dma->nr_pages); 231 (dma->vmalloc,dma->nr_pages);
231 } 232 }
232 if (dma->bus_addr) { 233 if (dma->bus_addr) {
233 dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL); 234 dma->sglist = vmalloc(sizeof(*dma->sglist));
234 if (NULL != dma->sglist) { 235 if (NULL != dma->sglist) {
235 dma->sglen = 1; 236 dma->sglen = 1;
236 sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; 237 sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
@@ -248,10 +249,10 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
248 if (0 == dma->sglen) { 249 if (0 == dma->sglen) {
249 printk(KERN_WARNING 250 printk(KERN_WARNING
250 "%s: videobuf_map_sg failed\n",__func__); 251 "%s: videobuf_map_sg failed\n",__func__);
251 kfree(dma->sglist); 252 vfree(dma->sglist);
252 dma->sglist = NULL; 253 dma->sglist = NULL;
253 dma->sglen = 0; 254 dma->sglen = 0;
254 return -EIO; 255 return -ENOMEM;
255 } 256 }
256 } 257 }
257 return 0; 258 return 0;
@@ -274,7 +275,7 @@ int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
274 275
275 dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); 276 dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction);
276 277
277 kfree(dma->sglist); 278 vfree(dma->sglist);
278 dma->sglist = NULL; 279 dma->sglist = NULL;
279 dma->sglen = 0; 280 dma->sglen = 0;
280 return 0; 281 return 0;
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 43e0998adb53..97b082fe4473 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -868,9 +868,9 @@ static void vino_sync_buffer(struct vino_framebuffer *fb)
868 dprintk("vino_sync_buffer():\n"); 868 dprintk("vino_sync_buffer():\n");
869 869
870 for (i = 0; i < fb->desc_table.page_count; i++) 870 for (i = 0; i < fb->desc_table.page_count; i++)
871 dma_sync_single(NULL, 871 dma_sync_single_for_cpu(NULL,
872 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], 872 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
873 PAGE_SIZE, DMA_FROM_DEVICE); 873 PAGE_SIZE, DMA_FROM_DEVICE);
874} 874}
875 875
876/* Framebuffer fifo functions (need to be locked externally) */ 876/* Framebuffer fifo functions (need to be locked externally) */
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index ea6c577b0eb3..03dc2f3cf84a 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1022,7 +1022,7 @@ zr36057_init (struct zoran *zr)
1022 zr->vbuf_bytesperline = 0; 1022 zr->vbuf_bytesperline = 0;
1023 1023
1024 /* Avoid nonsense settings from user for default input/norm */ 1024 /* Avoid nonsense settings from user for default input/norm */
1025 if (default_norm < 0 && default_norm > 2) 1025 if (default_norm < 0 || default_norm > 2)
1026 default_norm = 0; 1026 default_norm = 0;
1027 if (default_norm == 0) { 1027 if (default_norm == 0) {
1028 zr->norm = V4L2_STD_PAL; 1028 zr->norm = V4L2_STD_PAL;
@@ -1477,7 +1477,7 @@ static struct pci_driver zoran_driver = {
1477 .name = "zr36067", 1477 .name = "zr36067",
1478 .id_table = zr36067_pci_tbl, 1478 .id_table = zr36067_pci_tbl,
1479 .probe = zoran_probe, 1479 .probe = zoran_probe,
1480 .remove = zoran_remove, 1480 .remove = __devexit_p(zoran_remove),
1481}; 1481};
1482 1482
1483static int __init zoran_init(void) 1483static int __init zoran_init(void)
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index ac169c9eb18d..fc976f42f432 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -882,9 +882,11 @@ static void zr364xx_disconnect(struct usb_interface *intf)
882 video_unregister_device(cam->vdev); 882 video_unregister_device(cam->vdev);
883 cam->vdev = NULL; 883 cam->vdev = NULL;
884 kfree(cam->buffer); 884 kfree(cam->buffer);
885 if (cam->framebuf) 885 cam->buffer = NULL;
886 vfree(cam->framebuf); 886 vfree(cam->framebuf);
887 cam->framebuf = NULL;
887 kfree(cam); 888 kfree(cam);
889 cam = NULL;
888} 890}
889 891
890 892