summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2008-11-12 13:10:49 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2008-11-12 13:10:49 +1100
commit832c5113900a1b1f8e295f9bef0ec373a4f65712 (patch)
tree14f23403f2258cb915feae57def803f59c3c1ac0
parent3033be5964c9b7cd02953ea52dc32274ae6e450d (diff)
parent236e8f9c338ebf66a85c2078207024d877378671 (diff)
Merge commit 'v4l-dvb/master'
-rw-r--r--Documentation/video4linux/CARDLIST.cx885
-rw-r--r--Documentation/video4linux/README.cx888
-rw-r--r--Documentation/video4linux/gspca.txt1
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/common/saa7146_video.c10
-rw-r--r--drivers/media/common/tuners/tda9887.c5
-rw-r--r--drivers/media/dvb/Kconfig13
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c75
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h134
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c71
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h1
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c19
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h76
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c13
-rw-r--r--drivers/media/dvb/frontends/Kconfig45
-rw-r--r--drivers/media/dvb/frontends/Makefile9
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c2
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c378
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.h45
-rw-r--r--drivers/media/dvb/frontends/s921_core.c216
-rw-r--r--drivers/media/dvb/frontends/s921_core.h114
-rw-r--r--drivers/media/dvb/frontends/s921_module.c190
-rw-r--r--drivers/media/dvb/frontends/s921_module.h49
-rw-r--r--drivers/media/dvb/frontends/si21xx.c1
-rw-r--r--drivers/media/dvb/frontends/stb0899_algo.c1519
-rw-r--r--drivers/media/dvb/frontends/stb0899_cfg.h287
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c1684
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.h162
-rw-r--r--drivers/media/dvb/frontends/stb0899_priv.h267
-rw-r--r--drivers/media/dvb/frontends/stb0899_reg.h2027
-rw-r--r--drivers/media/dvb/frontends/stb6100.c545
-rw-r--r--drivers/media/dvb/frontends/stb6100.h115
-rw-r--r--drivers/media/dvb/frontends/stb6100_cfg.h108
-rw-r--r--drivers/media/dvb/frontends/tda8261.c230
-rw-r--r--drivers/media/dvb/frontends/tda8261.h55
-rw-r--r--drivers/media/dvb/frontends/tda8261_cfg.h84
-rw-r--r--drivers/media/dvb/frontends/zl10353.c3
-rw-r--r--drivers/media/dvb/ttpci/Kconfig4
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c298
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c311
-rw-r--r--drivers/media/dvb/ttpci/budget.h1
-rw-r--r--drivers/media/radio/dsbr100.c71
-rw-r--r--drivers/media/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-cadet.c2
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-mr800.c43
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/video/Kconfig14
-rw-r--r--drivers/media/video/Makefile4
-rw-r--r--drivers/media/video/arv.c5
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c7
-rw-r--r--drivers/media/video/bt8xx/bttv.h2
-rw-r--r--drivers/media/video/bt8xx/bttvp.h2
-rw-r--r--drivers/media/video/bw-qcam.c5
-rw-r--r--drivers/media/video/c-qcam.c7
-rw-r--r--drivers/media/video/cpia.c9
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c15
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c41
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c100
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h3
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c22
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.h7
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c60
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c24
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c24
-rw-r--r--drivers/media/video/cx18/cx18-io.c24
-rw-r--r--drivers/media/video/cx18/cx18-io.h8
-rw-r--r--drivers/media/video/cx25840/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c86
-rw-r--r--drivers/media/video/cx88/cx88-core.c3
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c64
-rw-r--r--drivers/media/video/cx88/cx88.h14
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c11
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c2
-rw-r--r--drivers/media/video/gspca/finepix.c3
-rw-r--r--drivers/media/video/gspca/gspca.c16
-rw-r--r--drivers/media/video/gspca/gspca.h11
-rw-r--r--drivers/media/video/gspca/ov519.c155
-rw-r--r--drivers/media/video/gspca/pac207.c1
-rw-r--r--drivers/media/video/gspca/sonixb.c21
-rw-r--r--drivers/media/video/gspca/sonixj.c60
-rw-r--r--drivers/media/video/gspca/tv8532.c140
-rw-r--r--drivers/media/video/gspca/zc3xx.c278
-rw-r--r--drivers/media/video/ir-kbd-i2c.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c16
-rw-r--r--drivers/media/video/ov511.c5
-rw-r--r--drivers/media/video/ov772x.c964
-rw-r--r--drivers/media/video/pms.c9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c13
-rw-r--r--drivers/media/video/pwc/pwc-if.c2
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c3
-rw-r--r--drivers/media/video/pwc/pwc.h3
-rw-r--r--drivers/media/video/saa5246a.c7
-rw-r--r--drivers/media/video/saa5249.c7
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
-rw-r--r--drivers/media/video/se401.c5
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c6
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h4
-rw-r--r--drivers/media/video/soc_camera.c5
-rw-r--r--drivers/media/video/stv680.c5
-rw-r--r--drivers/media/video/tvp5150.c15
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c5
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c6
-rw-r--r--drivers/media/video/uvc/uvc_driver.c169
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c17
-rw-r--r--drivers/media/video/uvc/uvc_video.c63
-rw-r--r--drivers/media/video/uvc/uvcvideo.h14
-rw-r--r--drivers/media/video/v4l2-common.c2
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c (renamed from drivers/media/video/compat_ioctl32.c)92
-rw-r--r--drivers/media/video/v4l2-dev.c4
-rw-r--r--drivers/media/video/v4l2-ioctl.c10
-rw-r--r--drivers/media/video/vino.c5
-rw-r--r--drivers/media/video/w9966.c5
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c8
-rw-r--r--firmware/Makefile16
-rw-r--r--include/linux/videodev2.h1
-rw-r--r--include/media/ov772x.h21
-rw-r--r--include/media/saa7146_vv.h3
-rw-r--r--include/media/soc_camera.h4
-rw-r--r--include/media/v4l2-chip-ident.h1
-rw-r--r--include/media/v4l2-ioctl.h6
-rw-r--r--sound/i2c/other/tea575x-tuner.c22
134 files changed, 11209 insertions, 923 deletions
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index a5227e308f4a..0d08f1edcf6d 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -2,7 +2,7 @@
1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401]
2 -> GDI Black Gold [14c7:0106,14c7:0107]
3 -> PixelView [1554:4811]
- 4 -> ATI TV Wonder Pro [1002:00f8]
+ 4 -> ATI TV Wonder Pro [1002:00f8,1002:00f9]
5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613]
6 -> AverTV Studio 303 (M126) [1461:000b]
7 -> MSI TV-@nywhere Master [1462:8606]
@@ -74,3 +74,6 @@
73 -> TeVii S420 DVB-S [d420:9022]
74 -> Prolink Pixelview Global Extreme [1554:4976]
75 -> PROF 7300 DVB-S/S2 [B033:3033]
+ 76 -> SATTRADE ST4200 DVB-S/S2 [b200:4200]
+ 77 -> TBS 8910 DVB-S [8910:8888]
+ 78 -> Prof 6200 DVB-S [b022:3022]
diff --git a/Documentation/video4linux/README.cx88 b/Documentation/video4linux/README.cx88
index 166d5960b1a9..35fae23f883b 100644
--- a/Documentation/video4linux/README.cx88
+++ b/Documentation/video4linux/README.cx88
@@ -1,4 +1,3 @@
-
cx8800 release notes
====================
@@ -10,21 +9,20 @@ current status
video
- Basically works.
- - Some minor image quality glitches.
- - For now only capture, overlay support isn't completed yet.
+ - For now, only capture and read(). Overlay isn't supported.
audio
- The chip specs for the on-chip TV sound decoder are next
to useless :-/
- Neverless the builtin TV sound decoder starts working now,
- at least for PAL-BG. Other TV norms need other code ...
+ at least for some standards.
FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE
USING.
- Most tuner chips do provide mono sound, which may or may not
be useable depending on the board design. With the Hauppauge
cards it works, so there is mono sound available as fallback.
- audio data dma (i.e. recording without loopback cable to the
- sound card) should be possible, but there is no code yet ...
+ sound card) is supported via cx88-alsa.
vbi
- Code present. Works for NTSC closed caption. PAL and other
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 004818fab040..2a23fe31e0ef 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -263,6 +263,7 @@ etoms 102c:6251 Qcam xxxxxx VGA
zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
spca561 10fd:7e50 FlyCam Usb 100
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
+pac207 145f:013a Trust WB-1300N
spca501 1776:501c Arowana 300K CMOS Camera
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 349ded22acc8..d220138901b5 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1266,6 +1266,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 127b0526a727..7d844af88384 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -313,7 +313,7 @@ static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
/*
DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
*/
- return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl);
+ return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl);
}
static int fops_mmap(struct file *file, struct vm_area_struct * vma)
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index fe0bd55977e3..101b01dbb8ea 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -834,7 +834,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
* copying is done already, arg is a kernel pointer.
*/
-static int __saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
@@ -1216,17 +1216,11 @@ static int __saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *a
#endif
default:
return v4l_compat_translate_ioctl(file, cmd, arg,
- __saa7146_video_do_ioctl);
+ saa7146_video_do_ioctl);
}
return 0;
}
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
-{
- return __saa7146_video_do_ioctl(file, cmd, arg);
-}
-
/*********************************************************************************/
/* buffer handling functions */
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index ff1788cc5d48..544cdbe88a6c 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -180,11 +180,10 @@ static struct tvnorm tvnorms[] = {
},{
.std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
.name = "SECAM-BGH",
- .b = ( cPositiveAmTV |
+ .b = ( cNegativeFmTV |
cQSS ),
.c = ( cTopDefault),
- .e = ( cGating_36 |
- cAudioIF_5_5 |
+ .e = ( cAudioIF_5_5 |
cVideoIF_38_90 ),
},{
.std = V4L2_STD_SECAM_L,
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 0bcd852576d6..40ebde53b3ce 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -2,6 +2,19 @@
# DVB device configuration
#
+config DVB_DYNAMIC_MINORS
+ bool "Dynamic DVB minor allocation"
+ depends on DVB_CORE
+ default n
+ help
+ If you say Y here, the DVB subsystem will use dynamic minor
+ allocation for any device that uses the DVB major number.
+ This means that you can have more than 4 of a single type
+ of device (like demuxes and frontends) per adapter, but udev
+ will be required to manage the device nodes.
+
+ If you are unsure about this, say N here.
+
menuconfig DVB_CAPTURE_DRIVERS
bool "DVB/ATSC adapters"
depends on DVB_CORE
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 14e627ef6465..f9d93532fdd8 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -19,7 +19,6 @@
*
*/
-#include <linux/version.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -368,7 +367,7 @@ static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb)
{
dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr);
- return pci_dma_mapping_error(dm1105dvb->pdev, dm1105dvb->dma_addr);
+ return !dm1105dvb->ts_buf;
}
static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb)
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 8557bf12cfb4..22f4366e0cb4 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -128,6 +128,7 @@ struct dvb_frontend_private {
unsigned int step_size;
int quality;
unsigned int check_wrapped;
+ enum dvbfe_search algo_status;
};
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -516,6 +517,8 @@ static int dvb_frontend_thread(void *data)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
unsigned long timeout;
fe_status_t s;
+ enum dvbfe_algo algo;
+
struct dvb_frontend_parameters *params;
dprintk("%s\n", __func__);
@@ -562,23 +565,80 @@ restart:
/* do an iteration of the tuning loop */
if (fe->ops.get_frontend_algo) {
- if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) {
- /* have we been asked to retune? */
- params = NULL;
+ algo = fe->ops.get_frontend_algo(fe);
+ switch (algo) {
+ case DVBFE_ALGO_HW:
+ dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
+ params = NULL; /* have we been asked to RETUNE ? */
+
if (fepriv->state & FESTATE_RETUNE) {
+ dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
params = &fepriv->parameters;
fepriv->state = FESTATE_TUNED;
}
- fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
+ if (fe->ops.tune)
+ fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
+
if (s != fepriv->status) {
+ dprintk("%s: state changed, adding current state\n", __func__);
dvb_frontend_add_event(fe, s);
fepriv->status = s;
}
- } else
+ break;
+ case DVBFE_ALGO_SW:
+ dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
dvb_frontend_swzigzag(fe);
- } else
+ break;
+ case DVBFE_ALGO_CUSTOM:
+ params = NULL; /* have we been asked to RETUNE ? */
+ dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
+ if (fepriv->state & FESTATE_RETUNE) {
+ dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
+ params = &fepriv->parameters;
+ fepriv->state = FESTATE_TUNED;
+ }
+ /* Case where we are going to search for a carrier
+ * User asked us to retune again for some reason, possibly
+ * requesting a search with a new set of parameters
+ */
+ if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
+ if (fe->ops.search) {
+ fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters);
+ /* We did do a search as was requested, the flags are
+ * now unset as well and has the flags wrt to search.
+ */
+ } else {
+ fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN;
+ }
+ }
+ /* Track the carrier if the search was successful */
+ if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
+ if (fe->ops.track)
+ fe->ops.track(fe, &fepriv->parameters);
+ } else {
+ fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
+ fepriv->delay = HZ / 2;
+ }
+ fe->ops.read_status(fe, &s);
+ if (s != fepriv->status) {
+ dvb_frontend_add_event(fe, s); /* update event list */
+ fepriv->status = s;
+ if (!(s & FE_HAS_LOCK)) {
+ fepriv->delay = HZ / 10;
+ fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
+ } else {
+ fepriv->delay = 60 * HZ;
+ }
+ }
+ break;
+ default:
+ dprintk("%s: UNDEFINED ALGO !\n", __func__);
+ break;
+ }
+ } else {
dvb_frontend_swzigzag(fe);
+ }
}
if (dvb_powerdown_on_sleep) {
@@ -1223,6 +1283,9 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
dprintk("%s() Finalised property cache\n", __func__);
dtv_property_cache_submit(fe);
+ /* Request the search algorithm to search */
+ fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
+
r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
&fepriv->parameters);
break;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index db4a63b0a32e..e176da472d7a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -69,6 +69,125 @@ struct analog_parameters {
u64 std;
};
+enum dvbfe_modcod {
+ DVBFE_MODCOD_DUMMY_PLFRAME = 0,
+ DVBFE_MODCOD_QPSK_1_4,
+ DVBFE_MODCOD_QPSK_1_3,
+ DVBFE_MODCOD_QPSK_2_5,
+ DVBFE_MODCOD_QPSK_1_2,
+ DVBFE_MODCOD_QPSK_3_5,
+ DVBFE_MODCOD_QPSK_2_3,
+ DVBFE_MODCOD_QPSK_3_4,
+ DVBFE_MODCOD_QPSK_4_5,
+ DVBFE_MODCOD_QPSK_5_6,
+ DVBFE_MODCOD_QPSK_8_9,
+ DVBFE_MODCOD_QPSK_9_10,
+ DVBFE_MODCOD_8PSK_3_5,
+ DVBFE_MODCOD_8PSK_2_3,
+ DVBFE_MODCOD_8PSK_3_4,
+ DVBFE_MODCOD_8PSK_5_6,
+ DVBFE_MODCOD_8PSK_8_9,
+ DVBFE_MODCOD_8PSK_9_10,
+ DVBFE_MODCOD_16APSK_2_3,
+ DVBFE_MODCOD_16APSK_3_4,
+ DVBFE_MODCOD_16APSK_4_5,
+ DVBFE_MODCOD_16APSK_5_6,
+ DVBFE_MODCOD_16APSK_8_9,
+ DVBFE_MODCOD_16APSK_9_10,
+ DVBFE_MODCOD_32APSK_3_4,
+ DVBFE_MODCOD_32APSK_4_5,
+ DVBFE_MODCOD_32APSK_5_6,
+ DVBFE_MODCOD_32APSK_8_9,
+ DVBFE_MODCOD_32APSK_9_10,
+ DVBFE_MODCOD_RESERVED_1,
+ DVBFE_MODCOD_BPSK_1_3,
+ DVBFE_MODCOD_BPSK_1_4,
+ DVBFE_MODCOD_RESERVED_2
+};
+
+enum tuner_param {
+ DVBFE_TUNER_FREQUENCY = (1 << 0),
+ DVBFE_TUNER_TUNERSTEP = (1 << 1),
+ DVBFE_TUNER_IFFREQ = (1 << 2),
+ DVBFE_TUNER_BANDWIDTH = (1 << 3),
+ DVBFE_TUNER_REFCLOCK = (1 << 4),
+ DVBFE_TUNER_IQSENSE = (1 << 5),
+ DVBFE_TUNER_DUMMY = (1 << 31)
+};
+
+/*
+ * ALGO_HW: (Hardware Algorithm)
+ * ----------------------------------------------------------------
+ * Devices that support this algorithm do everything in hardware
+ * and no software support is needed to handle them.
+ * Requesting these devices to LOCK is the only thing required,
+ * device is supposed to do everything in the hardware.
+ *
+ * ALGO_SW: (Software Algorithm)
+ * ----------------------------------------------------------------
+ * These are dumb devices, that require software to do everything
+ *
+ * ALGO_CUSTOM: (Customizable Agorithm)
+ * ----------------------------------------------------------------
+ * Devices having this algorithm can be customized to have specific
+ * algorithms in the frontend driver, rather than simply doing a
+ * software zig-zag. In this case the zigzag maybe hardware assisted
+ * or it maybe completely done in hardware. In all cases, usage of
+ * this algorithm, in conjunction with the search and track
+ * callbacks, utilizes the driver specific algorithm.
+ *
+ * ALGO_RECOVERY: (Recovery Algorithm)
+ * ----------------------------------------------------------------
+ * These devices have AUTO recovery capabilities from LOCK failure
+ */
+enum dvbfe_algo {
+ DVBFE_ALGO_HW = (1 << 0),
+ DVBFE_ALGO_SW = (1 << 1),
+ DVBFE_ALGO_CUSTOM = (1 << 2),
+ DVBFE_ALGO_RECOVERY = (1 << 31)
+};
+
+struct tuner_state {
+ u32 frequency;
+ u32 tunerstep;
+ u32 ifreq;
+ u32 bandwidth;
+ u32 iqsense;
+ u32 refclock;
+};
+
+/*
+ * search callback possible return status
+ *
+ * DVBFE_ALGO_SEARCH_SUCCESS
+ * The frontend search algorithm completed and returned succesfully
+ *
+ * DVBFE_ALGO_SEARCH_ASLEEP
+ * The frontend search algorithm is sleeping
+ *
+ * DVBFE_ALGO_SEARCH_FAILED
+ * The frontend search for a signal failed
+ *
+ * DVBFE_ALGO_SEARCH_INVALID
+ * The frontend search algorith was probably supplied with invalid
+ * parameters and the search is an invalid one
+ *
+ * DVBFE_ALGO_SEARCH_ERROR
+ * The frontend search algorithm failed due to some error
+ *
+ * DVBFE_ALGO_SEARCH_AGAIN
+ * The frontend search algorithm was requested to search again
+ */
+enum dvbfe_search {
+ DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
+ DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1),
+ DVBFE_ALGO_SEARCH_FAILED = (1 << 2),
+ DVBFE_ALGO_SEARCH_INVALID = (1 << 3),
+ DVBFE_ALGO_SEARCH_AGAIN = (1 << 4),
+ DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
+};
+
+
struct dvb_tuner_ops {
struct dvb_tuner_info info;
@@ -99,6 +218,13 @@ struct dvb_tuner_ops {
* tuners which require sophisticated tuning loops, controlling each parameter seperately. */
int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+
+ /*
+ * These are provided seperately from set_params in order to facilitate silicon
+ * tuners which require sophisticated tuning loops, controlling each parameter seperately.
+ */
+ int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
+ int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
};
struct analog_demod_info {
@@ -142,7 +268,7 @@ struct dvb_frontend_ops {
unsigned int *delay,
fe_status_t *status);
/* get frontend tuning algorithm from the module */
- int (*get_frontend_algo)(struct dvb_frontend *fe);
+ enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
/* these two are only used for the swzigzag code */
int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
@@ -167,6 +293,12 @@ struct dvb_frontend_ops {
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
+ /* These callbacks are for devices that implement their own
+ * tuning algorithms, rather than a simple swzigzag
+ */
+ enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
+ int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
+
struct dvb_tuner_ops tuner_ops;
struct analog_demod_ops analog_ops;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index a113744a56cc..6c571d9f011c 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -50,33 +50,27 @@ static const char * const dnames[] = {
"net", "osd"
};
+#ifdef CONFIG_DVB_DYNAMIC_MINORS
+#define MAX_DVB_MINORS 256
+#define DVB_MAX_IDS MAX_DVB_MINORS
+#else
#define DVB_MAX_IDS 4
#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
+#endif
static struct class *dvb_class;
-static struct dvb_device* dvbdev_find_device (int minor)
-{
- struct dvb_adapter *adap;
-
- list_for_each_entry(adap, &dvb_adapter_list, list_head) {
- struct dvb_device *dev;
- list_for_each_entry(dev, &adap->device_list, list_head)
- if (nums2minor(adap->num, dev->type, dev->id) == minor)
- return dev;
- }
-
- return NULL;
-}
-
+static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
+static DECLARE_RWSEM(minor_rwsem);
static int dvb_device_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev;
lock_kernel();
- dvbdev = dvbdev_find_device (iminor(inode));
+ down_read(&minor_rwsem);
+ dvbdev = dvb_minors[iminor(inode)];
if (dvbdev && dvbdev->fops) {
int err = 0;
@@ -92,9 +86,11 @@ static int dvb_device_open(struct inode *inode, struct file *file)
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
+ up_read(&minor_rwsem);
unlock_kernel();
return err;
}
+ up_read(&minor_rwsem);
unlock_kernel();
return -ENODEV;
}
@@ -192,6 +188,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
struct device *clsdev;
+ int minor;
int id;
mutex_lock(&dvbdev_register_lock);
@@ -231,11 +228,31 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
list_add_tail (&dvbdev->list_head, &adap->device_list);
+ down_write(&minor_rwsem);
+#ifdef CONFIG_DVB_DYNAMIC_MINORS
+ for (minor = 0; minor < MAX_DVB_MINORS; minor++)
+ if (dvb_minors[minor] == NULL)
+ break;
+
+ if (minor == MAX_DVB_MINORS) {
+ kfree(dvbdevfops);
+ kfree(dvbdev);
+ mutex_unlock(&dvbdev_register_lock);
+ return -EINVAL;
+ }
+#else
+ minor = nums2minor(adap->num, type, id);
+#endif
+
+ dvbdev->minor = minor;
+ dvb_minors[minor] = dvbdev;
+ up_write(&minor_rwsem);
+
mutex_unlock(&dvbdev_register_lock);
clsdev = device_create(dvb_class, adap->device,
- MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
- NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
+ MKDEV(DVB_MAJOR, minor),
+ dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
if (IS_ERR(clsdev)) {
printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
@@ -243,8 +260,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
}
dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
- adap->num, dnames[type], id, nums2minor(adap->num, type, id),
- nums2minor(adap->num, type, id));
+ adap->num, dnames[type], id, minor, minor);
return 0;
}
@@ -256,8 +272,11 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
if (!dvbdev)
return;
- device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
- dvbdev->type, dvbdev->id)));
+ down_write(&minor_rwsem);
+ dvb_minors[dvbdev->minor] = NULL;
+ up_write(&minor_rwsem);
+
+ device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
list_del (&dvbdev->list_head);
kfree (dvbdev->fops);
@@ -413,6 +432,15 @@ out:
return err;
}
+static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+ add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
+ add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
+ return 0;
+}
+
static int __init init_dvbdev(void)
{
int retval;
@@ -434,6 +462,7 @@ static int __init init_dvbdev(void)
retval = PTR_ERR(dvb_class);
goto error;
}
+ dvb_class->dev_uevent = dvb_uevent;
return 0;
error:
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 574e336bac35..dca49cf962e8 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -74,6 +74,7 @@ struct dvb_device {
struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
+ int minor;
u32 id;
/* in theory, 'users' can vanish now,
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 847d8fdd9ec4..4b2af32330ed 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -806,6 +806,16 @@ static int af9015_read_config(struct usb_device *udev)
ARRAY_SIZE(af9015_ir_table_msi);
}
break;
+ case USB_VID_AVERMEDIA:
+ af9015_properties[i].rc_key_map =
+ af9015_rc_keys_avermedia;
+ af9015_properties[i].rc_key_map_size =
+ ARRAY_SIZE(af9015_rc_keys_avermedia);
+ af9015_config.ir_table =
+ af9015_ir_table_avermedia;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_avermedia);
+ break;
}
}
}
@@ -1197,6 +1207,7 @@ static struct usb_device_id af9015_usb_table[] = {
{USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1347,7 +1358,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 6,
+ .num_device_descs = 7,
.devices = {
{
.name = "Xtensions XD-380",
@@ -1379,6 +1390,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.cold_ids = {&af9015_usb_table[15], NULL},
.warm_ids = {NULL},
},
+ {
+ .name = "KWorld USB DVB-T TV Stick II " \
+ "(VS-DVB-T 395U)",
+ .cold_ids = {&af9015_usb_table[16], NULL},
+ .warm_ids = {NULL},
+ },
}
}
};
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 6c3c97293316..1ab86cc6c015 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -520,4 +520,80 @@ static u8 af9015_ir_table_kworld[] = {
0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00,
};
+/* AverMedia Volar X */
+static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = {
+ { 0x05, 0x3d, KEY_PROG1 }, /* SOURCE */
+ { 0x05, 0x12, KEY_POWER }, /* POWER */
+ { 0x05, 0x1e, KEY_1 }, /* 1 */
+ { 0x05, 0x1f, KEY_2 }, /* 2 */
+ { 0x05, 0x20, KEY_3 }, /* 3 */
+ { 0x05, 0x21, KEY_4 }, /* 4 */
+ { 0x05, 0x22, KEY_5 }, /* 5 */
+ { 0x05, 0x23, KEY_6 }, /* 6 */
+ { 0x05, 0x24, KEY_7 }, /* 7 */
+ { 0x05, 0x25, KEY_8 }, /* 8 */
+ { 0x05, 0x26, KEY_9 }, /* 9 */
+ { 0x05, 0x3f, KEY_LEFT }, /* L / DISPLAY */
+ { 0x05, 0x27, KEY_0 }, /* 0 */
+ { 0x05, 0x0f, KEY_RIGHT }, /* R / CH RTN */
+ { 0x05, 0x18, KEY_PROG2 }, /* SNAP SHOT */
+ { 0x05, 0x1c, KEY_PROG3 }, /* 16-CH PREV */
+ { 0x05, 0x2d, KEY_VOLUMEDOWN }, /* VOL DOWN */
+ { 0x05, 0x3e, KEY_ZOOM }, /* FULL SCREEN */
+ { 0x05, 0x2e, KEY_VOLUMEUP }, /* VOL UP */
+ { 0x05, 0x10, KEY_MUTE }, /* MUTE */
+ { 0x05, 0x04, KEY_AUDIO }, /* AUDIO */
+ { 0x05, 0x15, KEY_RECORD }, /* RECORD */
+ { 0x05, 0x11, KEY_PLAY }, /* PLAY */
+ { 0x05, 0x16, KEY_STOP }, /* STOP */
+ { 0x05, 0x0c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
+ { 0x05, 0x05, KEY_BACK }, /* << / RED */
+ { 0x05, 0x09, KEY_FORWARD }, /* >> / YELLOW */
+ { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */
+ { 0x05, 0x0a, KEY_EPG }, /* EPG */
+ { 0x05, 0x13, KEY_MENU }, /* MENU */
+
+ { 0x05, 0x0e, KEY_CHANNELUP }, /* CH UP */
+ { 0x05, 0x0d, KEY_CHANNELDOWN }, /* CH DOWN */
+ { 0x05, 0x19, KEY_FIRST }, /* |<< / GREEN */
+ { 0x05, 0x08, KEY_LAST }, /* >>| / BLUE */
+};
+
+static u8 af9015_ir_table_avermedia[] = {
+ 0x02, 0xfd, 0x00, 0xff, 0x12, 0x05, 0x00,
+ 0x02, 0xfd, 0x01, 0xfe, 0x3d, 0x05, 0x00,
+ 0x02, 0xfd, 0x03, 0xfc, 0x17, 0x05, 0x00,
+ 0x02, 0xfd, 0x04, 0xfb, 0x0a, 0x05, 0x00,
+ 0x02, 0xfd, 0x05, 0xfa, 0x1e, 0x05, 0x00,
+ 0x02, 0xfd, 0x06, 0xf9, 0x1f, 0x05, 0x00,
+ 0x02, 0xfd, 0x07, 0xf8, 0x20, 0x05, 0x00,
+ 0x02, 0xfd, 0x09, 0xf6, 0x21, 0x05, 0x00,
+ 0x02, 0xfd, 0x0a, 0xf5, 0x22, 0x05, 0x00,
+ 0x02, 0xfd, 0x0b, 0xf4, 0x23, 0x05, 0x00,
+ 0x02, 0xfd, 0x0d, 0xf2, 0x24, 0x05, 0x00,
+ 0x02, 0xfd, 0x0e, 0xf1, 0x25, 0x05, 0x00,
+ 0x02, 0xfd, 0x0f, 0xf0, 0x26, 0x05, 0x00,
+ 0x02, 0xfd, 0x11, 0xee, 0x27, 0x05, 0x00,
+ 0x02, 0xfd, 0x08, 0xf7, 0x04, 0x05, 0x00,
+ 0x02, 0xfd, 0x0c, 0xf3, 0x3e, 0x05, 0x00,
+ 0x02, 0xfd, 0x10, 0xef, 0x1c, 0x05, 0x00,
+ 0x02, 0xfd, 0x12, 0xed, 0x3f, 0x05, 0x00,
+ 0x02, 0xfd, 0x13, 0xec, 0x0f, 0x05, 0x00,
+ 0x02, 0xfd, 0x14, 0xeb, 0x10, 0x05, 0x00,
+ 0x02, 0xfd, 0x15, 0xea, 0x13, 0x05, 0x00,
+ 0x02, 0xfd, 0x17, 0xe8, 0x18, 0x05, 0x00,
+ 0x02, 0xfd, 0x18, 0xe7, 0x11, 0x05, 0x00,
+ 0x02, 0xfd, 0x19, 0xe6, 0x15, 0x05, 0x00,
+ 0x02, 0xfd, 0x1a, 0xe5, 0x0c, 0x05, 0x00,
+ 0x02, 0xfd, 0x1b, 0xe4, 0x16, 0x05, 0x00,
+ 0x02, 0xfd, 0x1c, 0xe3, 0x09, 0x05, 0x00,
+ 0x02, 0xfd, 0x1d, 0xe2, 0x05, 0x05, 0x00,
+ 0x02, 0xfd, 0x1e, 0xe1, 0x2d, 0x05, 0x00,
+ 0x02, 0xfd, 0x1f, 0xe0, 0x2e, 0x05, 0x00,
+ 0x03, 0xfc, 0x00, 0xff, 0x08, 0x05, 0x00,
+ 0x03, 0xfc, 0x01, 0xfe, 0x19, 0x05, 0x00,
+ 0x03, 0xfc, 0x02, 0xfd, 0x0d, 0x05, 0x00,
+ 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
+};
+
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 7380b94b3b36..a4fca3fca5ee 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -96,6 +96,7 @@
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
#define USB_PID_KWORLD_399U 0xe399
+#define USB_PID_KWORLD_395U 0xe396
#define USB_PID_KWORLD_PC160_2T 0xc160
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 6286fbbe7fb5..bc5e47a2b917 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -9,7 +9,6 @@
*
* see Documentation/dvb/README.dvb-usb for more information
*/
-#include <linux/version.h>
#include "dw2102.h"
#include "si21xx.h"
#include "stv0299.h"
@@ -27,6 +26,10 @@
#define USB_PID_DW2104 0x2104
#endif
+#ifndef USB_PID_CINERGY_S
+#define USB_PID_CINERGY_S 0x0064
+#endif
+
#define DW210X_READ_MSG 0
#define DW210X_WRITE_MSG 1
@@ -578,6 +581,7 @@ static struct usb_device_id dw2102_table[] = {
{USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
{USB_DEVICE(USB_VID_CYPRESS, 0x2104)},
{USB_DEVICE(0x9022, 0xd650)},
+ {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
{ }
};
@@ -647,6 +651,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
DW210X_WRITE_MSG);
break;
+ case USB_PID_CINERGY_S:
case USB_PID_DW2102:
dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
DW210X_WRITE_MSG);
@@ -726,7 +731,7 @@ static struct dvb_usb_device_properties dw2102_properties = {
},
}
},
- .num_device_descs = 2,
+ .num_device_descs = 3,
.devices = {
{"DVBWorld DVB-S 2102 USB2.0",
{&dw2102_table[0], NULL},
@@ -736,6 +741,10 @@ static struct dvb_usb_device_properties dw2102_properties = {
{&dw2102_table[1], NULL},
{NULL},
},
+ {"TerraTec Cinergy S USB",
+ {&dw2102_table[4], NULL},
+ {NULL},
+ },
}
};
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 96b93e21a84b..2470d88e901a 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -12,6 +12,25 @@ config DVB_FE_CUSTOMISE
If unsure say N.
+comment "Multistandard (satellite) frontends"
+ depends on DVB_CORE
+
+config DVB_STB0899
+ tristate "STB0899 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
+ to support this demodulator based frontends
+
+config DVB_STB6100
+ tristate "STB6100 based tuners"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A Silicon tuner from ST used in conjunction with the STB0899
+ demodulator. Say Y when you want to support this tuner.
+
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
@@ -78,6 +97,13 @@ config DVB_TDA10086
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_TDA8261
+ tristate "Philips TDA8261 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
config DVB_VES1X93
tristate "VLSI VES1893 or VES1993 based"
depends on DVB_CORE && I2C
@@ -345,6 +371,14 @@ config DVB_LGDT330X
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+config DVB_LGDT3304
+ tristate "LG Electronics LGDT3304"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
+
config DVB_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
@@ -369,6 +403,17 @@ config DVB_S5H1411
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+comment "ISDB-T (terrestrial) frontends"
+ depends on DVB_CORE
+
+config DVB_S921
+ tristate "Sharp S921 tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
+ Say Y when you want to support this frontend.
+
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index aba79f4a63a7..7a19c0c7b7a0 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -5,8 +5,13 @@
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
EXTRA_CFLAGS += -Idrivers/media/common/tuners/
+s921-objs := s921_module.o s921_core.o
+stb0899-objs = stb0899_drv.o stb0899_algo.o
+
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
+obj-$(CONFIG_DVB_STB0899) += stb0899.o
+obj-$(CONFIG_DVB_STB6100) += stb6100.o
obj-$(CONFIG_DVB_SP8870) += sp8870.o
obj-$(CONFIG_DVB_CX22700) += cx22700.o
obj-$(CONFIG_DVB_CX24110) += cx24110.o
@@ -35,12 +40,14 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o
obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
+obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
+obj-$(CONFIG_DVB_TDA8261) += tda8261.o
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
@@ -55,3 +62,5 @@ obj-$(CONFIG_DVB_CX24116) += cx24116.o
obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o
+obj-$(CONFIG_DVB_S921) += s921.o
+
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index ea058153ebfa..9f6349964cda 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -311,7 +311,7 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
.count = 4,
.entries = {
{ 1250000, 500, 0xc4, 0x00},
- { 1550000, 500, 0xc4, 0x40},
+ { 1450000, 500, 0xc4, 0x40},
{ 2050000, 500, 0xc4, 0x80},
{ 2150000, 500, 0xc4, 0xc0},
},
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
new file mode 100644
index 000000000000..469ace5692c6
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -0,0 +1,378 @@
+/*
+ * Driver for LG ATSC lgdt3304 driver
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "lgdt3304.h"
+
+static unsigned int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)");
+
+#define dprintk(fmt, args...) if (debug) do {\
+ printk("lgdt3304 debug: " fmt, ##args); } while (0)
+
+struct lgdt3304_state
+{
+ struct dvb_frontend frontend;
+ fe_modulation_t current_modulation;
+ __u32 snr;
+ __u32 current_frequency;
+ __u8 addr;
+ struct i2c_adapter *i2c;
+};
+
+static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len)
+{
+ struct lgdt3304_state *state = fe->demodulator_priv;
+ struct i2c_msg i2cmsgs = {
+ .addr = state->addr,
+ .flags = 0,
+ .len = 3,
+ .buf = buf
+ };
+ int i;
+ int err;
+
+ for (i=0; i<len-1; i+=3){
+ if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
+ printk("%s i2c_transfer error %d\n", __FUNCTION__, err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+ i2cmsgs.buf += 3;
+ }
+ return 0;
+}
+
+static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg)
+{
+ struct lgdt3304_state *state = fe->demodulator_priv;
+ struct i2c_msg i2cmsgs[2];
+ int ret;
+ __u8 buf;
+
+ __u8 regbuf[2] = { reg>>8, reg&0xff };
+
+ i2cmsgs[0].addr = state->addr;
+ i2cmsgs[0].flags = 0;
+ i2cmsgs[0].len = 2;
+ i2cmsgs[0].buf = regbuf;
+
+ i2cmsgs[1].addr = state->addr;
+ i2cmsgs[1].flags = I2C_M_RD;
+ i2cmsgs[1].len = 1;
+ i2cmsgs[1].buf = &buf;
+
+ if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) {
+ printk("%s i2c_transfer error %d\n", __FUNCTION__, ret);
+ return ret;
+ }
+
+ return buf;
+}
+
+static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val)
+{
+ struct lgdt3304_state *state = fe->demodulator_priv;
+ char buffer[3] = { reg>>8, reg&0xff, val };
+ int ret;
+
+ struct i2c_msg i2cmsgs = {
+ .addr = state->addr,
+ .flags = 0,
+ .len = 3,
+ .buf=buffer
+ };
+ ret = i2c_transfer(state->i2c, &i2cmsgs, 1);
+ if (ret != 1) {
+ printk("%s i2c_transfer error %d\n", __FUNCTION__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+
+static int lgdt3304_soft_Reset(struct dvb_frontend *fe)
+{
+ lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a);
+ lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b);
+ mdelay(200);
+ return 0;
+}
+
+static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
+ int err = 0;
+
+ static __u8 lgdt3304_vsb8_data[] = {
+ /* 16bit , 8bit */
+ /* regs , val */
+ 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x13,
+ 0x00, 0x0d, 0x02,
+ 0x00, 0x0e, 0x02,
+ 0x00, 0x12, 0x32,
+ 0x00, 0x13, 0xc4,
+ 0x01, 0x12, 0x17,
+ 0x01, 0x13, 0x15,
+ 0x01, 0x14, 0x18,
+ 0x01, 0x15, 0xff,
+ 0x01, 0x16, 0x2c,
+ 0x02, 0x14, 0x67,
+ 0x02, 0x24, 0x8d,
+ 0x04, 0x27, 0x12,
+ 0x04, 0x28, 0x4f,
+ 0x03, 0x08, 0x80,
+ 0x03, 0x09, 0x00,
+ 0x03, 0x0d, 0x00,
+ 0x03, 0x0e, 0x1c,
+ 0x03, 0x14, 0xe1,
+ 0x05, 0x0e, 0x5b,
+ };
+
+ /* not yet tested .. */
+ static __u8 lgdt3304_qam64_data[] = {
+ /* 16bit , 8bit */
+ /* regs , val */
+ 0x00, 0x00, 0x18,
+ 0x00, 0x0d, 0x02,
+ //0x00, 0x0e, 0x02,
+ 0x00, 0x12, 0x2a,
+ 0x00, 0x13, 0x00,
+ 0x03, 0x14, 0xe3,
+ 0x03, 0x0e, 0x1c,
+ 0x03, 0x08, 0x66,
+ 0x03, 0x09, 0x66,
+ 0x03, 0x0a, 0x08,
+ 0x03, 0x0b, 0x9b,
+ 0x05, 0x0e, 0x5b,
+ };
+
+
+ /* tested with KWorld a340 */
+ static __u8 lgdt3304_qam256_data[] = {
+ /* 16bit , 8bit */
+ /* regs , val */
+ 0x00, 0x00, 0x01, //0x19,
+ 0x00, 0x12, 0x2a,
+ 0x00, 0x13, 0x80,
+ 0x00, 0x0d, 0x02,
+ 0x03, 0x14, 0xe3,
+
+ 0x03, 0x0e, 0x1c,
+ 0x03, 0x08, 0x66,
+ 0x03, 0x09, 0x66,
+ 0x03, 0x0a, 0x08,
+ 0x03, 0x0b, 0x9b,
+
+ 0x03, 0x0d, 0x14,
+ //0x05, 0x0e, 0x5b,
+ 0x01, 0x06, 0x4a,
+ 0x01, 0x07, 0x3d,
+ 0x01, 0x08, 0x70,
+ 0x01, 0x09, 0xa3,
+
+ 0x05, 0x04, 0xfd,
+
+ 0x00, 0x0d, 0x82,
+
+ 0x05, 0x0e, 0x5b,
+
+ 0x05, 0x0e, 0x5b,
+
+ 0x00, 0x02, 0x9a,
+
+ 0x00, 0x02, 0x9b,
+
+ 0x00, 0x00, 0x01,
+ 0x00, 0x12, 0x2a,
+ 0x00, 0x13, 0x80,
+ 0x00, 0x0d, 0x02,
+ 0x03, 0x14, 0xe3,
+
+ 0x03, 0x0e, 0x1c,
+ 0x03, 0x08, 0x66,
+ 0x03, 0x09, 0x66,
+ 0x03, 0x0a, 0x08,
+ 0x03, 0x0b, 0x9b,
+
+ 0x03, 0x0d, 0x14,
+ 0x01, 0x06, 0x4a,
+ 0x01, 0x07, 0x3d,
+ 0x01, 0x08, 0x70,
+ 0x01, 0x09, 0xa3,
+
+ 0x05, 0x04, 0xfd,
+
+ 0x00, 0x0d, 0x82,
+
+ 0x05, 0x0e, 0x5b,
+ };
+
+ struct lgdt3304_state *state = fe->demodulator_priv;
+ if (state->current_modulation != param->u.vsb.modulation) {
+ switch(param->u.vsb.modulation) {
+ case VSB_8:
+ err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data,
+ sizeof(lgdt3304_vsb8_data));
+ break;
+ case QAM_64:
+ err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data,
+ sizeof(lgdt3304_qam64_data));
+ break;
+ case QAM_256:
+ err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data,
+ sizeof(lgdt3304_qam256_data));
+ break;
+ default:
+ break;
+ }
+
+ if (err) {
+ printk("%s error setting modulation\n", __FUNCTION__);
+ } else {
+ state->current_modulation = param->u.vsb.modulation;
+ }
+ }
+ state->current_frequency = param->frequency;
+
+ lgdt3304_soft_Reset(fe);
+
+
+ if (fe->ops.tuner_ops.set_params)
+ fe->ops.tuner_ops.set_params(fe, param);
+
+ return 0;
+}
+
+static int lgdt3304_init(struct dvb_frontend *fe) {
+ return 0;
+}
+
+static int lgdt3304_sleep(struct dvb_frontend *fe) {
+ return 0;
+}
+
+
+static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct lgdt3304_state *state = fe->demodulator_priv;
+ int r011d;
+ int qam_lck;
+
+ *status = 0;
+ dprintk("lgdt read status\n");
+
+ r011d = lgdt3304_i2c_read_reg(fe, 0x011d);
+
+ dprintk("%02x\n", r011d);
+
+ switch(state->current_modulation) {
+ case VSB_8:
+ if (r011d & 0x80) {
+ dprintk("VSB Locked\n");
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_SIGNAL;
+ }
+ break;
+ case QAM_64:
+ case QAM_256:
+ qam_lck = r011d & 0x7;
+ switch(qam_lck) {
+ case 0x0: dprintk("Unlock\n");
+ break;
+ case 0x4: dprintk("1st Lock in acquisition state\n");
+ break;
+ case 0x6: dprintk("2nd Lock in acquisition state\n");
+ break;
+ case 0x7: dprintk("Final Lock in good reception state\n");
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_SIGNAL;
+ break;
+ }
+ break;
+ default:
+ printk("%s unhandled modulation\n", __FUNCTION__);
+ }
+
+
+ return 0;
+}
+
+static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
+{
+ dprintk("read ber\n");
+ return 0;
+}
+
+static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
+{
+ dprintk("read snr\n");
+ return 0;
+}
+
+static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
+{
+ dprintk("read ucblocks\n");
+ return 0;
+}
+
+static void lgdt3304_release(struct dvb_frontend *fe)
+{
+ struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops demod_lgdt3304={
+ .info = {
+ .name = "LG 3304",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 62500,
+ .symbol_rate_min = 5056941,
+ .symbol_rate_max = 10762000,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+ .init = lgdt3304_init,
+ .sleep = lgdt3304_sleep,
+ .set_frontend = lgdt3304_set_parameters,
+ .read_snr = lgdt3304_read_snr,
+ .read_ber = lgdt3304_read_ber,
+ .read_status = lgdt3304_read_status,
+ .read_ucblocks = lgdt3304_read_ucblocks,
+ .release = lgdt3304_release,
+};
+
+struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
+ struct i2c_adapter *i2c)
+{
+
+ struct lgdt3304_state *state;
+ state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
+ memset(state, 0x0, sizeof(struct lgdt3304_state));
+ state->addr = config->i2c_address;
+ state->i2c = i2c;
+
+ memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+}
+
+EXPORT_SYMBOL_GPL(lgdt3304_attach);
+MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
+MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgdt3304.h b/drivers/media/dvb/frontends/lgdt3304.h
new file mode 100644
index 000000000000..fc409fe59acb
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3304.h
@@ -0,0 +1,45 @@
+/*
+ * Driver for DVB-T lgdt3304 demodulator
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef LGDT3304_H
+#define LGDT3304_H
+
+#include <linux/dvb/frontend.h>
+
+struct lgdt3304_config
+{
+ /* demodulator's I2C address */
+ u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE))
+extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_LGDT */
+
+#endif /* LGDT3304_H */
diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c
new file mode 100644
index 000000000000..974b52be9aea
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_core.c
@@ -0,0 +1,216 @@
+/*
+ * Driver for Sharp s921 driver
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include "s921_core.h"
+
+static int s921_isdb_init(struct s921_isdb_t *dev);
+static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
+static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
+static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
+
+static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
+ 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
+ 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
+ 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
+ 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
+ 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
+ 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
+ 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
+ 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
+ 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
+ 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
+ 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
+ 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
+ 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
+ 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
+ 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
+ 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
+ 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
+ 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
+ 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
+ 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
+ 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
+ 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
+ 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
+ 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
+ 0xf8, 0xd7 };
+
+static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
+ 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
+ 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
+ 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
+ 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
+ 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
+ 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
+ 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
+ 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
+ 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
+ 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
+ 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
+ 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
+ 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
+ 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
+ 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
+ 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
+
+int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
+ switch(cmd) {
+ case ISDB_T_CMD_INIT:
+ s921_isdb_init(dev);
+ break;
+ case ISDB_T_CMD_SET_PARAM:
+ s921_isdb_set_parameters(dev, data);
+ break;
+ case ISDB_T_CMD_TUNE:
+ s921_isdb_tune(dev, data);
+ break;
+ case ISDB_T_CMD_GET_STATUS:
+ s921_isdb_get_status(dev, data);
+ break;
+ default:
+ printk("unhandled command\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int s921_isdb_init(struct s921_isdb_t *dev) {
+ unsigned int i;
+ unsigned int ret;
+ printk("isdb_init\n");
+ for (i = 0; i < sizeof(init_table); i+=2) {
+ ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
+ if (ret != 0) {
+ printk("i2c write failed\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
+
+ int ret;
+ /* auto is sufficient for now, lateron this should be reflected in an extra interface */
+
+
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
+ ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
+
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
+ if (ret < 0)
+ return -EINVAL;
+
+ return E_OK;
+}
+
+static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
+
+ int ret;
+ int index;
+
+ index = (params->frequency - 473143000)/6000000;
+
+ if (index > 48) {
+ return -EINVAL;
+ }
+
+ dev->i2c_write(dev->priv_dev, 0x47, 0x60);
+
+ ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
+ if (ret < 0)
+ return -EINVAL;
+
+ ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
+ if (ret < 0)
+ return -EINVAL;
+
+ dev->i2c_write(dev->priv_dev, 0x01, 0x40);
+ return 0;
+}
+
+static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
+ unsigned int *ret = (unsigned int*)data;
+ u8 ifagc_dt;
+ u8 rfagc_dt;
+
+ mdelay(10);
+ ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
+ rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
+ if (rfagc_dt == 0x40) {
+ *ret = 1;
+ }
+ return 0;
+}
diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h
new file mode 100644
index 000000000000..de2f10a44e72
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_core.h
@@ -0,0 +1,114 @@
+#ifndef _S921_CORE_H
+#define _S921_CORE_H
+//#define u8 unsigned int
+//#define u32 unsigned int
+
+
+
+//#define EINVAL -1
+#define E_OK 0
+
+struct s921_isdb_t {
+ void *priv_dev;
+ int (*i2c_write)(void *dev, u8 reg, u8 val);
+ int (*i2c_read)(void *dev, u8 reg);
+};
+
+#define ISDB_T_CMD_INIT 0
+#define ISDB_T_CMD_SET_PARAM 1
+#define ISDB_T_CMD_TUNE 2
+#define ISDB_T_CMD_GET_STATUS 3
+
+struct s921_isdb_t_tune_params {
+ u32 frequency;
+};
+
+struct s921_isdb_t_status {
+};
+
+struct s921_isdb_t_transmission_mode_params {
+ u8 mode;
+ u8 layer_a_mode;
+#define ISDB_T_LA_MODE_1 0
+#define ISDB_T_LA_MODE_2 1
+#define ISDB_T_LA_MODE_3 2
+ u8 layer_a_carrier_modulation;
+#define ISDB_T_LA_CM_DQPSK 0
+#define ISDB_T_LA_CM_QPSK 1
+#define ISDB_T_LA_CM_16QAM 2
+#define ISDB_T_LA_CM_64QAM 3
+#define ISDB_T_LA_CM_NOLAYER 4
+ u8 layer_a_code_rate;
+#define ISDB_T_LA_CR_1_2 0
+#define ISDB_T_LA_CR_2_3 1
+#define ISDB_T_LA_CR_3_4 2
+#define ISDB_T_LA_CR_5_6 4
+#define ISDB_T_LA_CR_7_8 8
+#define ISDB_T_LA_CR_NOLAYER 16
+ u8 layer_a_time_interleave;
+#define ISDB_T_LA_TI_0 0
+#define ISDB_T_LA_TI_1 1
+#define ISDB_T_LA_TI_2 2
+#define ISDB_T_LA_TI_4 4
+#define ISDB_T_LA_TI_8 8
+#define ISDB_T_LA_TI_16 16
+#define ISDB_T_LA_TI_32 32
+ u8 layer_a_nseg;
+
+ u8 layer_b_mode;
+#define ISDB_T_LB_MODE_1 0
+#define ISDB_T_LB_MODE_2 1
+#define ISDB_T_LB_MODE_3 2
+ u8 layer_b_carrier_modulation;
+#define ISDB_T_LB_CM_DQPSK 0
+#define ISDB_T_LB_CM_QPSK 1
+#define ISDB_T_LB_CM_16QAM 2
+#define ISDB_T_LB_CM_64QAM 3
+#define ISDB_T_LB_CM_NOLAYER 4
+ u8 layer_b_code_rate;
+#define ISDB_T_LB_CR_1_2 0
+#define ISDB_T_LB_CR_2_3 1
+#define ISDB_T_LB_CR_3_4 2
+#define ISDB_T_LB_CR_5_6 4
+#define ISDB_T_LB_CR_7_8 8
+#define ISDB_T_LB_CR_NOLAYER 16
+ u8 layer_b_time_interleave;
+#define ISDB_T_LB_TI_0 0
+#define ISDB_T_LB_TI_1 1
+#define ISDB_T_LB_TI_2 2
+#define ISDB_T_LB_TI_4 4
+#define ISDB_T_LB_TI_8 8
+#define ISDB_T_LB_TI_16 16
+#define ISDB_T_LB_TI_32 32
+ u8 layer_b_nseg;
+
+ u8 layer_c_mode;
+#define ISDB_T_LC_MODE_1 0
+#define ISDB_T_LC_MODE_2 1
+#define ISDB_T_LC_MODE_3 2
+ u8 layer_c_carrier_modulation;
+#define ISDB_T_LC_CM_DQPSK 0
+#define ISDB_T_LC_CM_QPSK 1
+#define ISDB_T_LC_CM_16QAM 2
+#define ISDB_T_LC_CM_64QAM 3
+#define ISDB_T_LC_CM_NOLAYER 4
+ u8 layer_c_code_rate;
+#define ISDB_T_LC_CR_1_2 0
+#define ISDB_T_LC_CR_2_3 1
+#define ISDB_T_LC_CR_3_4 2
+#define ISDB_T_LC_CR_5_6 4
+#define ISDB_T_LC_CR_7_8 8
+#define ISDB_T_LC_CR_NOLAYER 16
+ u8 layer_c_time_interleave;
+#define ISDB_T_LC_TI_0 0
+#define ISDB_T_LC_TI_1 1
+#define ISDB_T_LC_TI_2 2
+#define ISDB_T_LC_TI_4 4
+#define ISDB_T_LC_TI_8 8
+#define ISDB_T_LC_TI_16 16
+#define ISDB_T_LC_TI_32 32
+ u8 layer_c_nseg;
+};
+
+int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
+#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
new file mode 100644
index 000000000000..3cbb9cb2cf47
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -0,0 +1,190 @@
+/*
+ * Driver for Sharp s921 driver
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ * All rights reserved.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "s921_module.h"
+#include "s921_core.h"
+
+static unsigned int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"s921 debugging (default off)");
+
+#define dprintk(fmt, args...) if (debug) do {\
+ printk("s921 debug: " fmt, ##args); } while (0)
+
+struct s921_state
+{
+ struct dvb_frontend frontend;
+ fe_modulation_t current_modulation;
+ __u32 snr;
+ __u32 current_frequency;
+ __u8 addr;
+ struct s921_isdb_t dev;
+ struct i2c_adapter *i2c;
+};
+
+static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
+ struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
+ struct s921_isdb_t_transmission_mode_params params;
+ struct s921_isdb_t_tune_params tune_params;
+
+ tune_params.frequency = param->frequency;
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, &params);
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
+ mdelay(100);
+ return 0;
+}
+
+static int s921_init(struct dvb_frontend *fe) {
+ printk("s921 init\n");
+ return 0;
+}
+
+static int s921_sleep(struct dvb_frontend *fe) {
+ printk("s921 sleep\n");
+ return 0;
+}
+
+static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
+ unsigned int ret;
+ mdelay(5);
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
+ *status = 0;
+
+ printk("status: %02x\n", ret);
+ if (ret == 1) {
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_SIGNAL;
+ }
+
+ return 0;
+}
+
+static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
+{
+ dprintk("read ber\n");
+ return 0;
+}
+
+static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
+{
+ dprintk("read snr\n");
+ return 0;
+}
+
+static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
+{
+ dprintk("read ucblocks\n");
+ return 0;
+}
+
+static void s921_release(struct dvb_frontend *fe)
+{
+ struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops demod_s921={
+ .info = {
+ .name = "SHARP S921",
+ .type = FE_OFDM,
+ .frequency_min = 473143000,
+ .frequency_max = 767143000,
+ .frequency_stepsize = 6000000,
+ .frequency_tolerance = 0,
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
+ FE_CAN_MUTE_TS
+ },
+ .init = s921_init,
+ .sleep = s921_sleep,
+ .set_frontend = s921_set_parameters,
+ .read_snr = s921_read_snr,
+ .read_ber = s921_read_ber,
+ .read_status = s921_read_status,
+ .read_ucblocks = s921_read_ucblocks,
+ .release = s921_release,
+};
+
+static int s921_write(void *dev, u8 reg, u8 val) {
+ struct s921_state *state = dev;
+ char buf[2]={reg,val};
+ int err;
+ struct i2c_msg i2cmsgs = {
+ .addr = state->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buf
+ };
+
+ if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
+ printk("%s i2c_transfer error %d\n", __FUNCTION__, err);
+ if (err < 0)
+ return err;
+ else
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int s921_read(void *dev, u8 reg) {
+ struct s921_state *state = dev;
+ u8 b1;
+ int ret;
+ struct i2c_msg msg[2] = { { .addr = state->addr,
+ .flags = 0,
+ .buf = &reg, .len = 1 },
+ { .addr = state->addr,
+ .flags = I2C_M_RD,
+ .buf = &b1, .len = 1 } };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2)
+ return ret;
+ return b1;
+}
+
+struct dvb_frontend* s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c)
+{
+
+ struct s921_state *state;
+ state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
+ memset(state, 0x0, sizeof(struct s921_state));
+
+ state->addr = config->i2c_address;
+ state->i2c = i2c;
+ state->dev.i2c_write = &s921_write;
+ state->dev.i2c_read = &s921_read;
+ state->dev.priv_dev = state;
+
+ s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
+
+ memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+}
+
+EXPORT_SYMBOL_GPL(s921_attach);
+MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
+MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h
new file mode 100644
index 000000000000..78660424ba95
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921_module.h
@@ -0,0 +1,49 @@
+/*
+ * Driver for DVB-T s921 demodulator
+ *
+ * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef S921_MODULE_H
+#define S921_MODULE_H
+
+#include <linux/dvb/frontend.h>
+#include "s921_core.h"
+
+int s921_isdb_init(struct s921_isdb_t *dev);
+int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
+
+struct s921_config
+{
+ /* demodulator's I2C address */
+ u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
+extern struct dvb_frontend* s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_S921 */
+
+#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
index 3ddbe69c45ce..0bd16af8a6cd 100644
--- a/drivers/media/dvb/frontends/si21xx.c
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -8,7 +8,6 @@
* (at your option) any later version.
*
*/
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
new file mode 100644
index 000000000000..ced9b7ae7d50
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -0,0 +1,1519 @@
+/*
+ STB0899 Multistandard Frontend driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "stb0899_drv.h"
+#include "stb0899_priv.h"
+#include "stb0899_reg.h"
+
+inline u32 stb0899_do_div(u64 n, u32 d)
+{
+ /* wrap do_div() for ease of use */
+
+ do_div(n, d);
+ return n;
+}
+
+/*
+ * stb0899_calc_srate
+ * Compute symbol rate
+ */
+static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
+{
+ u64 tmp;
+
+ /* srate = (SFR * master_clk) >> 20 */
+
+ /* sfr is of size 20 bit, stored with an offset of 4 bit */
+ tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2];
+ tmp &= ~0xf;
+ tmp *= master_clk;
+ tmp >>= 24;
+
+ return tmp;
+}
+
+/*
+ * stb0899_get_srate
+ * Get the current symbol rate
+ */
+u32 stb0899_get_srate(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ u8 sfr[3];
+
+ stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
+
+ return stb0899_calc_srate(internal->master_clk, sfr);
+}
+
+/*
+ * stb0899_set_srate
+ * Set symbol frequency
+ * MasterClock: master clock frequency (hz)
+ * SymbolRate: symbol rate (bauds)
+ * return symbol frequency
+ */
+static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
+{
+ u32 tmp;
+ u8 sfr[3];
+
+ dprintk(state->verbose, FE_DEBUG, 1, "-->");
+ /*
+ * in order to have the maximum precision, the symbol rate entered into
+ * the chip is computed as the closest value of the "true value".
+ * In this purpose, the symbol rate value is rounded (1 is added on the bit
+ * below the LSB )
+ *
+ * srate = (SFR * master_clk) >> 20
+ * <=>
+ * SFR = srate << 20 / master_clk
+ *
+ * rounded:
+ * SFR = (srate << 21 + master_clk) / (2 * master_clk)
+ *
+ * stored as 20 bit number with an offset of 4 bit:
+ * sfr = SFR << 4;
+ */
+
+ tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk);
+ tmp <<= 4;
+
+ sfr[0] = tmp >> 16;
+ sfr[1] = tmp >> 8;
+ sfr[2] = tmp;
+
+ stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
+
+ return srate;
+}
+
+/*
+ * stb0899_calc_derot_time
+ * Compute the amount of time needed by the derotator to lock
+ * SymbolRate: Symbol rate
+ * return: derotator time constant (ms)
+ */
+static long stb0899_calc_derot_time(long srate)
+{
+ if (srate > 0)
+ return (100000 / (srate / 1000));
+ else
+ return 0;
+}
+
+/*
+ * stb0899_carr_width
+ * Compute the width of the carrier
+ * return: width of carrier (kHz or Mhz)
+ */
+long stb0899_carr_width(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+
+ return (internal->srate + (internal->srate * internal->rolloff) / 100);
+}
+
+/*
+ * stb0899_first_subrange
+ * Compute the first subrange of the search
+ */
+static void stb0899_first_subrange(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_params *params = &state->params;
+ struct stb0899_config *config = state->config;
+
+ int range = 0;
+ u32 bandwidth = 0;
+
+ if (config->tuner_get_bandwidth) {
+ stb0899_i2c_gate_ctrl(&state->frontend, 1);
+ config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+ stb0899_i2c_gate_ctrl(&state->frontend, 0);
+ range = bandwidth - stb0899_carr_width(state) / 2;
+ }
+
+ if (range > 0)
+ internal->sub_range = MIN(internal->srch_range, range);
+ else
+ internal->sub_range = 0;
+
+ internal->freq = params->freq;
+ internal->tuner_offst = 0L;
+ internal->sub_dir = 1;
+}
+
+/*
+ * stb0899_check_tmg
+ * check for timing lock
+ * internal.Ttiming: time to wait for loop lock
+ */
+static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ int lock;
+ u8 reg;
+ s8 timing;
+
+ msleep(internal->t_derot);
+
+ stb0899_write_reg(state, STB0899_RTF, 0xf2);
+ reg = stb0899_read_reg(state, STB0899_TLIR);
+ lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
+ timing = stb0899_read_reg(state, STB0899_RTF);
+
+ if (lock >= 42) {
+ if ((lock > 48) && (ABS(timing) >= 110)) {
+ internal->status = ANALOGCARRIER;
+ dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
+ } else {
+ internal->status = TIMINGOK;
+ dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
+ }
+ } else {
+ internal->status = NOTIMING;
+ dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
+ }
+ return internal->status;
+}
+
+/*
+ * stb0899_search_tmg
+ * perform a fs/2 zig-zag to find timing
+ */
+static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_params *params = &state->params;
+
+ short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
+ int index = 0;
+ u8 cfr[2];
+
+ internal->status = NOTIMING;
+
+ /* timing loop computation & symbol rate optimisation */
+ derot_limit = (internal->sub_range / 2L) / internal->mclk;
+ derot_step = (params->srate / 2L) / internal->mclk;
+
+ while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
+ index++;
+ derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
+
+ if (ABS(derot_freq) > derot_limit)
+ next_loop--;
+
+ if (next_loop) {
+ STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+ stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
+ }
+ internal->direction = -internal->direction; /* Change zigzag direction */
+ }
+
+ if (internal->status == TIMINGOK) {
+ stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
+ internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+ dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
+ }
+
+ return internal->status;
+}
+
+/*
+ * stb0899_check_carrier
+ * Check for carrier found
+ */
+static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ u8 reg;
+
+ msleep(internal->t_derot); /* wait for derotator ok */
+
+ reg = stb0899_read_reg(state, STB0899_CFD);
+ STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_CFD, reg);
+
+ reg = stb0899_read_reg(state, STB0899_DSTATUS);
+ dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
+ if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
+ internal->status = CARRIEROK;
+ dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
+ } else {
+ internal->status = NOCARRIER;
+ dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
+ }
+
+ return internal->status;
+}
+
+/*
+ * stb0899_search_carrier
+ * Search for a QPSK carrier with the derotator
+ */
+static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+
+ short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
+ int index = 0;
+ u8 cfr[2];
+ u8 reg;
+
+ internal->status = NOCARRIER;
+ derot_limit = (internal->sub_range / 2L) / internal->mclk;
+ derot_freq = internal->derot_freq;
+
+ reg = stb0899_read_reg(state, STB0899_CFD);
+ STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_CFD, reg);
+
+ do {
+ dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
+ if (stb0899_check_carrier(state) == NOCARRIER) {
+ index++;
+ last_derot_freq = derot_freq;
+ derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
+
+ if(ABS(derot_freq) > derot_limit)
+ next_loop--;
+
+ if (next_loop) {
+ reg = stb0899_read_reg(state, STB0899_CFD);
+ STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_CFD, reg);
+
+ STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+ stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
+ }
+ }
+
+ internal->direction = -internal->direction; /* Change zigzag direction */
+ } while ((internal->status != CARRIEROK) && next_loop);
+
+ if (internal->status == CARRIEROK) {
+ stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
+ internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+ dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
+ } else {
+ internal->derot_freq = last_derot_freq;
+ }
+
+ return internal->status;
+}
+
+/*
+ * stb0899_check_data
+ * Check for data found
+ */
+static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_params *params = &state->params;
+
+ int lock = 0, index = 0, dataTime = 500, loop;
+ u8 reg;
+
+ internal->status = NODATA;
+
+ /* RESET FEC */
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESACS, reg, 1);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+ msleep(1);
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESACS, reg, 0);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ if (params->srate <= 2000000)
+ dataTime = 2000;
+ else if (params->srate <= 5000000)
+ dataTime = 1500;
+ else if (params->srate <= 15000000)
+ dataTime = 1000;
+ else
+ dataTime = 500;
+
+ stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */
+ while (1) {
+ /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */
+ reg = stb0899_read_reg(state, STB0899_VSTATUS);
+ lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
+ loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
+
+ if (lock || loop || (index > dataTime))
+ break;
+ index++;
+ }
+
+ if (lock) { /* DATA LOCK indicator */
+ internal->status = DATAOK;
+ dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
+ }
+
+ return internal->status;
+}
+
+/*
+ * stb0899_search_data
+ * Search for a QPSK carrier with the derotator
+ */
+static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
+{
+ short int derot_freq, derot_step, derot_limit, next_loop = 3;
+ u8 cfr[2];
+ u8 reg;
+ int index = 1;
+
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_params *params = &state->params;
+
+ derot_step = (params->srate / 4L) / internal->mclk;
+ derot_limit = (internal->sub_range / 2L) / internal->mclk;
+ derot_freq = internal->derot_freq;
+
+ do {
+ if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
+
+ derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
+ if (ABS(derot_freq) > derot_limit)
+ next_loop--;
+
+ if (next_loop) {
+ dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
+ reg = stb0899_read_reg(state, STB0899_CFD);
+ STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_CFD, reg);
+
+ STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+ stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
+
+ stb0899_check_carrier(state);
+ index++;
+ }
+ }
+ internal->direction = -internal->direction; /* change zig zag direction */
+ } while ((internal->status != DATAOK) && next_loop);
+
+ if (internal->status == DATAOK) {
+ stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
+ internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+ dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
+ }
+
+ return internal->status;
+}
+
+/*
+ * stb0899_check_range
+ * check if the found frequency is in the correct range
+ */
+static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_params *params = &state->params;
+
+ int range_offst, tp_freq;
+
+ range_offst = internal->srch_range / 2000;
+ tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
+
+ if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
+ internal->status = RANGEOK;
+ dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
+ } else {
+ internal->status = OUTOFRANGE;
+ dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
+ }
+
+ return internal->status;
+}
+
+/*
+ * NextSubRange
+ * Compute the next subrange of the search
+ */
+static void next_sub_range(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_params *params = &state->params;
+
+ long old_sub_range;
+
+ if (internal->sub_dir > 0) {
+ old_sub_range = internal->sub_range;
+ internal->sub_range = MIN((internal->srch_range / 2) -
+ (internal->tuner_offst + internal->sub_range / 2),
+ internal->sub_range);
+
+ if (internal->sub_range < 0)
+ internal->sub_range = 0;
+
+ internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
+ }
+
+ internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
+ internal->sub_dir = -internal->sub_dir;
+}
+
+/*
+ * stb0899_dvbs_algo
+ * Search for a signal, timing, carrier and data for a
+ * given frequency in a given range
+ */
+enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
+{
+ struct stb0899_params *params = &state->params;
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+
+ u8 bclc, reg;
+ u8 cfr[2];
+ u8 eq_const[10];
+ s32 clnI = 3;
+ u32 bandwidth = 0;
+
+ /* BETA values rated @ 99MHz */
+ s32 betaTab[5][4] = {
+ /* 5 10 20 30MBps */
+ { 37, 34, 32, 31 }, /* QPSK 1/2 */
+ { 37, 35, 33, 31 }, /* QPSK 2/3 */
+ { 37, 35, 33, 31 }, /* QPSK 3/4 */
+ { 37, 36, 33, 32 }, /* QPSK 5/6 */
+ { 37, 36, 33, 32 } /* QPSK 7/8 */
+ };
+
+ internal->direction = 1;
+
+ stb0899_set_srate(state, internal->master_clk, params->srate);
+ /* Carrier loop optimization versus symbol rate for acquisition*/
+ if (params->srate <= 5000000) {
+ stb0899_write_reg(state, STB0899_ACLC, 0x89);
+ bclc = stb0899_read_reg(state, STB0899_BCLC);
+ STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
+ stb0899_write_reg(state, STB0899_BCLC, bclc);
+ clnI = 0;
+ } else if (params->srate <= 15000000) {
+ stb0899_write_reg(state, STB0899_ACLC, 0xc9);
+ bclc = stb0899_read_reg(state, STB0899_BCLC);
+ STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
+ stb0899_write_reg(state, STB0899_BCLC, bclc);
+ clnI = 1;
+ } else if(params->srate <= 25000000) {
+ stb0899_write_reg(state, STB0899_ACLC, 0x89);
+ bclc = stb0899_read_reg(state, STB0899_BCLC);
+ STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
+ stb0899_write_reg(state, STB0899_BCLC, bclc);
+ clnI = 2;
+ } else {
+ stb0899_write_reg(state, STB0899_ACLC, 0xc8);
+ bclc = stb0899_read_reg(state, STB0899_BCLC);
+ STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
+ stb0899_write_reg(state, STB0899_BCLC, bclc);
+ clnI = 3;
+ }
+
+ dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
+ /* Set the timing loop to acquisition */
+ stb0899_write_reg(state, STB0899_RTC, 0x46);
+ stb0899_write_reg(state, STB0899_CFD, 0xee);
+
+ /* !! WARNING !!
+ * Do not read any status variables while acquisition,
+ * If any needed, read before the acquisition starts
+ * querying status while acquiring causes the
+ * acquisition to go bad and hence no locks.
+ */
+ dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
+ internal->derot_percent, params->srate, internal->mclk);
+
+ /* Initial calculations */
+ internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol */
+ internal->t_derot = stb0899_calc_derot_time(params->srate);
+ internal->t_data = 500;
+
+ dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
+ /* RESET Stream merger */
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESRS, reg, 1);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ /*
+ * Set KDIVIDER to an intermediate value between
+ * 1/2 and 7/8 for acquisition
+ */
+ reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
+ STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
+ stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
+
+ stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */
+ stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
+
+ stb0899_first_subrange(state);
+ do {
+ /* Initialisations */
+ cfr[0] = cfr[1] = 0;
+ stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency */
+
+ stb0899_write_reg(state, STB0899_RTF, 0);
+ reg = stb0899_read_reg(state, STB0899_CFD);
+ STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_CFD, reg);
+
+ internal->derot_freq = 0;
+ internal->status = NOAGC1;
+
+ /* enable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+ /* Move tuner to frequency */
+ dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
+ if (state->config->tuner_set_frequency)
+ state->config->tuner_set_frequency(&state->frontend, internal->freq);
+
+ if (state->config->tuner_get_frequency)
+ state->config->tuner_get_frequency(&state->frontend, &internal->freq);
+
+ msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop */
+ dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
+ internal->status = AGC1OK;
+
+ /* There is signal in the band */
+ if (config->tuner_get_bandwidth)
+ config->tuner_get_bandwidth(&state->frontend, &bandwidth);
+
+ /* disable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+ if (params->srate <= bandwidth / 2)
+ stb0899_search_tmg(state); /* For low rates (SCPC) */
+ else
+ stb0899_check_tmg(state); /* For high rates (MCPC) */
+
+ if (internal->status == TIMINGOK) {
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "TIMING OK ! Derot freq=%d, mclk=%d",
+ internal->derot_freq, internal->mclk);
+
+ if (stb0899_search_carrier(state) == CARRIEROK) { /* Search for carrier */
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "CARRIER OK ! Derot freq=%d, mclk=%d",
+ internal->derot_freq, internal->mclk);
+
+ if (stb0899_search_data(state) == DATAOK) { /* Check for data */
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "DATA OK ! Derot freq=%d, mclk=%d",
+ internal->derot_freq, internal->mclk);
+
+ if (stb0899_check_range(state) == RANGEOK) {
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "RANGE OK ! derot freq=%d, mclk=%d",
+ internal->derot_freq, internal->mclk);
+
+ internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
+ reg = stb0899_read_reg(state, STB0899_PLPARM);
+ internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "freq=%d, internal resultant freq=%d",
+ params->freq, internal->freq);
+
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "internal puncture rate=%d",
+ internal->fecrate);
+ }
+ }
+ }
+ }
+ if (internal->status != RANGEOK)
+ next_sub_range(state);
+
+ } while (internal->sub_range && internal->status != RANGEOK);
+
+ /* Set the timing loop to tracking */
+ stb0899_write_reg(state, STB0899_RTC, 0x33);
+ stb0899_write_reg(state, STB0899_CFD, 0xf7);
+ /* if locked and range ok, set Kdiv */
+ if (internal->status == RANGEOK) {
+ dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
+ stb0899_write_reg(state, STB0899_EQON, 0x41); /* Equalizer OFF while acquiring */
+ stb0899_write_reg(state, STB0899_VITSYNC, 0x39); /* SN to b'11 for acquisition */
+
+ /*
+ * Carrier loop optimization versus
+ * symbol Rate/Puncture Rate for Tracking
+ */
+ reg = stb0899_read_reg(state, STB0899_BCLC);
+ switch (internal->fecrate) {
+ case STB0899_FEC_1_2: /* 13 */
+ stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a);
+ STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
+ stb0899_write_reg(state, STB0899_BCLC, reg);
+ break;
+ case STB0899_FEC_2_3: /* 18 */
+ stb0899_write_reg(state, STB0899_DEMAPVIT, 44);
+ STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
+ stb0899_write_reg(state, STB0899_BCLC, reg);
+ break;
+ case STB0899_FEC_3_4: /* 21 */
+ stb0899_write_reg(state, STB0899_DEMAPVIT, 60);
+ STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
+ stb0899_write_reg(state, STB0899_BCLC, reg);
+ break;
+ case STB0899_FEC_5_6: /* 24 */
+ stb0899_write_reg(state, STB0899_DEMAPVIT, 75);
+ STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
+ stb0899_write_reg(state, STB0899_BCLC, reg);
+ break;
+ case STB0899_FEC_6_7: /* 25 */
+ stb0899_write_reg(state, STB0899_DEMAPVIT, 88);
+ stb0899_write_reg(state, STB0899_ACLC, 0x88);
+ stb0899_write_reg(state, STB0899_BCLC, 0x9a);
+ break;
+ case STB0899_FEC_7_8: /* 26 */
+ stb0899_write_reg(state, STB0899_DEMAPVIT, 94);
+ STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
+ stb0899_write_reg(state, STB0899_BCLC, reg);
+ break;
+ default:
+ dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
+ break;
+ }
+ /* release stream merger RESET */
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESRS, reg, 0);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ /* disable carrier detector */
+ reg = stb0899_read_reg(state, STB0899_CFD);
+ STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
+ stb0899_write_reg(state, STB0899_CFD, reg);
+
+ stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
+ }
+
+ return internal->status;
+}
+
+/*
+ * stb0899_dvbs2_config_uwp
+ * Configure UWP state machine
+ */
+static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+ u32 uwp1, uwp2, uwp3, reg;
+
+ uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
+ uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
+ uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
+
+ STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
+ STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
+ STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
+
+ STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
+ STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
+ STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
+
+ STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
+ STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
+
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
+ STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
+}
+
+/*
+ * stb0899_dvbs2_config_csm_auto
+ * Set CSM to AUTO mode
+ */
+static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
+{
+ u32 reg;
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+ STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
+}
+
+long Log2Int(int number)
+{
+ int i;
+
+ i = 0;
+ while ((1 << i) <= ABS(number))
+ i++;
+
+ if (number == 0)
+ i = 1;
+
+ return i - 1;
+}
+
+/*
+ * stb0899_dvbs2_calc_srate
+ * compute BTR_NOM_FREQ for the symbol rate
+ */
+static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+
+ u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
+ u32 master_clk, srate;
+
+ dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+ dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+ dec_rate = Log2Int(dec_ratio);
+ decim = 1 << dec_rate;
+ master_clk = internal->master_clk / 1000;
+ srate = internal->srate / 1000;
+
+ if (decim <= 4) {
+ intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
+ remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
+ } else {
+ intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
+ remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
+ }
+ btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
+
+ return btr_nom_freq;
+}
+
+/*
+ * stb0899_dvbs2_calc_dev
+ * compute the correction to be applied to symbol rate
+ */
+static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ u32 dec_ratio, correction, master_clk, srate;
+
+ dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+ dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+
+ master_clk = internal->master_clk / 1000; /* for integer Caculation*/
+ srate = internal->srate / 1000; /* for integer Caculation*/
+ correction = (512 * master_clk) / (2 * dec_ratio * srate);
+
+ return correction;
+}
+
+/*
+ * stb0899_dvbs2_set_srate
+ * Set DVBS2 symbol rate
+ */
+static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+
+ u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
+ u32 correction, freq_adj, band_lim, decim_cntrl, reg;
+ u8 anti_alias;
+
+ /*set decimation to 1*/
+ dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+ dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+ dec_rate = Log2Int(dec_ratio);
+
+ win_sel = 0;
+ if (dec_rate >= 5)
+ win_sel = dec_rate - 4;
+
+ decim = (1 << dec_rate);
+ /* (FSamp/Fsymbol *100) for integer Caculation */
+ f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
+
+ if (f_sym <= 2250) /* don't band limit signal going into btr block*/
+ band_lim = 1;
+ else
+ band_lim = 0; /* band limit signal going into btr block*/
+
+ decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
+
+ if (f_sym <= 3450)
+ anti_alias = 0;
+ else if (f_sym <= 4250)
+ anti_alias = 1;
+ else
+ anti_alias = 2;
+
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
+ btr_nom_freq = stb0899_dvbs2_calc_srate(state);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
+
+ correction = stb0899_dvbs2_calc_dev(state);
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
+ STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
+
+ /* scale UWP+CSM frequency to sample rate*/
+ freq_adj = internal->srate / (internal->master_clk / 4096);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
+}
+
+/*
+ * stb0899_dvbs2_set_btr_loopbw
+ * set bit timing loop bandwidth as a percentage of the symbol rate
+ */
+static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+
+ u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
+ s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
+ s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
+ u32 decim, K, wn, k_direct, k_indirect;
+ u32 reg;
+
+ dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
+ dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
+ dec_rate = Log2Int(dec_ratio);
+ decim = (1 << dec_rate);
+
+ sym_peak *= 576000;
+ K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
+ K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
+
+ if (K != 0) {
+ K = sym_peak / K;
+ wn = (4 * zeta * zeta) + 1000000;
+ wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/
+
+ k_indirect = (wn * wn) / K;
+ k_indirect = k_indirect; /*kindirect = kindirect 10^-6*/
+ k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/
+ k_direct *= 100;
+
+ k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
+ k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
+ k_btr1 = k_direct / (1 << k_direct_shift);
+ k_btr1 /= 10000;
+
+ k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
+ k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
+ k_btr0 = k_indirect * (1 << (-k_indirect_shift));
+ k_btr0 /= 1000000;
+
+ k_btr2_rshft = 0;
+ if (k_btr0_rshft > 15) {
+ k_btr2_rshft = k_btr0_rshft - 15;
+ k_btr0_rshft = 15;
+ }
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
+ STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
+ STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
+ STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
+ STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
+ STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
+ } else
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
+}
+
+/*
+ * stb0899_dvbs2_set_carr_freq
+ * set nominal frequency for carrier search
+ */
+static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
+{
+ struct stb0899_config *config = state->config;
+ s32 crl_nom_freq;
+ u32 reg;
+
+ crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
+ crl_nom_freq *= carr_freq;
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+ STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+}
+
+/*
+ * stb0899_dvbs2_init_calc
+ * Initialize DVBS2 UWP, CSM, carrier and timing loops
+ */
+static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ s32 steps, step_size;
+ u32 range, reg;
+
+ /* config uwp and csm */
+ stb0899_dvbs2_config_uwp(state);
+ stb0899_dvbs2_config_csm_auto(state);
+
+ /* initialize BTR */
+ stb0899_dvbs2_set_srate(state);
+ stb0899_dvbs2_set_btr_loopbw(state);
+
+ if (internal->srate / 1000000 >= 15)
+ step_size = (1 << 17) / 5;
+ else if (internal->srate / 1000000 >= 10)
+ step_size = (1 << 17) / 7;
+ else if (internal->srate / 1000000 >= 5)
+ step_size = (1 << 17) / 10;
+ else
+ step_size = (1 << 17) / 4;
+
+ range = internal->srch_range / 1000000;
+ steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
+ steps = (steps + 6) / 10;
+ steps = (steps == 0) ? 1 : steps;
+ if (steps % 2 == 0)
+ stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
+ (internal->step_size * (internal->srate / 20000000)),
+ (internal->master_clk) / 1000000);
+ else
+ stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
+
+ /*Set Carrier Search params (zigzag, num steps and freq step size*/
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
+ STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
+ STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
+ STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
+}
+
+/*
+ * stb0899_dvbs2_btr_init
+ * initialize the timing loop
+ */
+static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
+{
+ u32 reg;
+
+ /* set enable BTR loopback */
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
+ STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
+ STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
+
+ /* fix btr freq accum at 0 */
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
+
+ /* fix btr freq accum at 0 */
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
+}
+
+/*
+ * stb0899_dvbs2_reacquire
+ * trigger a DVB-S2 acquisition
+ */
+static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
+{
+ u32 reg = 0;
+
+ /* demod soft reset */
+ STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
+
+ /*Reset Timing Loop */
+ stb0899_dvbs2_btr_init(state);
+
+ /* reset Carrier loop */
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
+
+ /*release demod soft reset */
+ reg = 0;
+ STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
+
+ /* start acquisition process */
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
+
+ /* equalizer Init */
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
+
+ /*Start equilizer */
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+ STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
+ STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
+ STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
+ STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+
+ /* RESET Packet delineator */
+ stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
+}
+
+/*
+ * stb0899_dvbs2_get_dmd_status
+ * get DVB-S2 Demod LOCK status
+ */
+static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
+{
+ int time = -10, lock = 0, uwp, csm;
+ u32 reg;
+
+ do {
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
+ dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
+ if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
+ dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
+ dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
+ uwp = STB0899_GETFIELD(UWP_LOCK, reg);
+ csm = STB0899_GETFIELD(CSM_LOCK, reg);
+ if (uwp && csm)
+ lock = 1;
+
+ time += 10;
+ msleep(10);
+
+ } while ((!lock) && (time <= timeout));
+
+ if (lock) {
+ dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
+ return DVBS2_DEMOD_LOCK;
+ } else {
+ return DVBS2_DEMOD_NOLOCK;
+ }
+}
+
+/*
+ * stb0899_dvbs2_get_data_lock
+ * get FEC status
+ */
+static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
+{
+ int time = 0, lock = 0;
+ u8 reg;
+
+ while ((!lock) && (time < timeout)) {
+ reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
+ dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
+ lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
+ time++;
+ }
+
+ return lock;
+}
+
+/*
+ * stb0899_dvbs2_get_fec_status
+ * get DVB-S2 FEC LOCK status
+ */
+static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
+{
+ int time = 0, Locked;
+
+ do {
+ Locked = stb0899_dvbs2_get_data_lock(state, 1);
+ time++;
+ msleep(1);
+
+ } while ((!Locked) && (time < timeout));
+
+ if (Locked) {
+ dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
+ return DVBS2_FEC_LOCK;
+ } else {
+ return DVBS2_FEC_NOLOCK;
+ }
+}
+
+
+/*
+ * stb0899_dvbs2_init_csm
+ * set parameters for manual mode
+ */
+static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
+{
+ struct stb0899_internal *internal = &state->internal;
+
+ s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
+ s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
+ u32 csm1, csm2, csm3, csm4;
+
+ if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
+ switch (modcod) {
+ case STB0899_QPSK_12:
+ gamma_acq = 25;
+ gamma_rho_acq = 2700;
+ gamma_trk = 12;
+ gamma_rho_trk = 180;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_35:
+ gamma_acq = 38;
+ gamma_rho_acq = 7182;
+ gamma_trk = 14;
+ gamma_rho_trk = 308;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_23:
+ gamma_acq = 42;
+ gamma_rho_acq = 9408;
+ gamma_trk = 17;
+ gamma_rho_trk = 476;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_34:
+ gamma_acq = 53;
+ gamma_rho_acq = 16642;
+ gamma_trk = 19;
+ gamma_rho_trk = 646;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_45:
+ gamma_acq = 53;
+ gamma_rho_acq = 17119;
+ gamma_trk = 22;
+ gamma_rho_trk = 880;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_56:
+ gamma_acq = 55;
+ gamma_rho_acq = 19250;
+ gamma_trk = 23;
+ gamma_rho_trk = 989;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_89:
+ gamma_acq = 60;
+ gamma_rho_acq = 24240;
+ gamma_trk = 24;
+ gamma_rho_trk = 1176;
+ lock_count_thr = 8;
+ break;
+ case STB0899_QPSK_910:
+ gamma_acq = 66;
+ gamma_rho_acq = 29634;
+ gamma_trk = 24;
+ gamma_rho_trk = 1176;
+ lock_count_thr = 8;
+ break;
+ default:
+ gamma_acq = 66;
+ gamma_rho_acq = 29634;
+ gamma_trk = 24;
+ gamma_rho_trk = 1176;
+ lock_count_thr = 8;
+ break;
+ }
+
+ csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+ STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+ csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+ csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
+ csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
+ csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
+
+ STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
+ STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
+ STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
+ STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
+ STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
+ STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
+ STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
+ STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
+ STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
+ STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
+ STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
+
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
+ }
+}
+
+/*
+ * stb0899_dvbs2_get_srate
+ * get DVB-S2 Symbol Rate
+ */
+static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+
+ u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
+ int div1, div2, rem1, rem2;
+
+ div1 = config->btr_nco_bits / 2;
+ div2 = config->btr_nco_bits - div1 - 1;
+
+ bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
+ decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
+ decimRate = (1 << decimRate);
+
+ intval1 = internal->master_clk / (1 << div1);
+ intval2 = bTrNomFreq / (1 << div2);
+
+ rem1 = internal->master_clk % (1 << div1);
+ rem2 = bTrNomFreq % (1 << div2);
+ /* only for integer calculation */
+ srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
+ srate /= decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
+
+ return srate;
+}
+
+/*
+ * stb0899_dvbs2_algo
+ * Search for signal, timing, carrier and data for a given
+ * frequency in a given range
+ */
+enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ enum stb0899_modcod modcod;
+
+ s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
+ int i = 0;
+ u32 reg, csm1;
+
+ if (internal->srate <= 2000000) {
+ searchTime = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs */
+ FecLockTime = 350; /* 350 ms max time to lock FEC, SYMB <= 2Mbs */
+ } else if (internal->srate <= 5000000) {
+ searchTime = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs */
+ FecLockTime = 170; /* 170 ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs */
+ } else if (internal->srate <= 10000000) {
+ searchTime = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs */
+ FecLockTime = 80; /* 80 ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs */
+ } else if (internal->srate <= 15000000) {
+ searchTime = 500; /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs */
+ FecLockTime = 50; /* 50 ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs */
+ } else if (internal->srate <= 20000000) {
+ searchTime = 300; /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs */
+ FecLockTime = 30; /* 50 ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs */
+ } else if (internal->srate <= 25000000) {
+ searchTime = 250; /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs */
+ FecLockTime = 25; /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
+ } else {
+ searchTime = 150; /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs */
+ FecLockTime = 20; /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
+ }
+
+ /* Maintain Stream Merger in reset during acquisition */
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESRS, reg, 1);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ /* enable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+ /* Move tuner to frequency */
+ if (state->config->tuner_set_frequency)
+ state->config->tuner_set_frequency(&state->frontend, internal->freq);
+ if (state->config->tuner_get_frequency)
+ state->config->tuner_get_frequency(&state->frontend, &internal->freq);
+
+ /* disable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+ /* Set IF AGC to acquisition */
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+ STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 4);
+ STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
+ STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
+
+ /* Initialisation */
+ stb0899_dvbs2_init_calc(state);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+ switch (internal->inversion) {
+ case IQ_SWAP_OFF:
+ STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
+ break;
+ case IQ_SWAP_ON:
+ STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
+ break;
+ case IQ_SWAP_AUTO: /* use last successful search first */
+ STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
+ break;
+ }
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+ stb0899_dvbs2_reacquire(state);
+
+ /* Wait for demod lock (UWP and CSM) */
+ internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+
+ if (internal->status == DVBS2_DEMOD_LOCK) {
+ dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
+ i = 0;
+ /* Demod Locked, check FEC status */
+ internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+
+ /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
+ while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+ /* Read the frequency offset*/
+ offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+ /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+ STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+ stb0899_dvbs2_reacquire(state);
+ internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+ i++;
+ }
+ }
+
+ if (internal->status != DVBS2_FEC_LOCK) {
+ if (internal->inversion == IQ_SWAP_AUTO) {
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+ iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
+ /* IQ Spectrum Inversion */
+ STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+ /* start acquistion process */
+ stb0899_dvbs2_reacquire(state);
+
+ /* Wait for demod lock (UWP and CSM) */
+ internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+ if (internal->status == DVBS2_DEMOD_LOCK) {
+ i = 0;
+ /* Demod Locked, check FEC */
+ internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+ /*try thrice for false locks, (UWP and CSM Locked but no FEC) */
+ while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+ /* Read the frequency offset*/
+ offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+ /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+ STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+
+ stb0899_dvbs2_reacquire(state);
+ internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+ i++;
+ }
+ }
+/*
+ if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
+ pParams->IQLocked = !iqSpectrum;
+*/
+ }
+ }
+ if (internal->status == DVBS2_FEC_LOCK) {
+ dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+ modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
+ pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
+
+ if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
+ (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
+ (pilots == 1)) {
+
+ stb0899_dvbs2_init_csm(state, pilots, modcod);
+ /* Wait for UWP,CSM and data LOCK 20ms max */
+ internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+
+ i = 0;
+ while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+ csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+ STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+ csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
+ STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
+
+ internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+ i++;
+ }
+ }
+
+ if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
+ (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
+ (pilots == 1)) {
+
+ /* Equalizer Disable update */
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+ STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+ }
+
+ /* slow down the Equalizer once locked */
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
+ STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
+
+ /* Store signal parameters */
+ offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+
+ offsetfreq = offsetfreq / ((1 << 30) / 1000);
+ offsetfreq *= (internal->master_clk / 1000000);
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+ if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
+ offsetfreq *= -1;
+
+ internal->freq = internal->freq - offsetfreq;
+ internal->srate = stb0899_dvbs2_get_srate(state);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+ internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
+ internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
+ internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
+
+ /* Set IF AGC to tracking */
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+ STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 3);
+
+ /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
+ if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
+ STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
+
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
+ STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
+ }
+
+ /* Release Stream Merger Reset */
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESRS, reg, 0);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ return internal->status;
+}
diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb/frontends/stb0899_cfg.h
new file mode 100644
index 000000000000..0867906d3ff3
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_cfg.h
@@ -0,0 +1,287 @@
+/*
+ STB0899 Multistandard Frontend driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_CFG_H
+#define __STB0899_CFG_H
+
+static const struct stb0899_s2_reg stb0899_s2_init_2[] = {
+
+ { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */
+ { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */
+ { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */
+ { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */
+ { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */
+ { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */
+ { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */
+
+ { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */
+ { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */
+
+ { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */
+ { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */
+ { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */
+ { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */
+ { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */
+ { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */
+ { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */
+ { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */
+ { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */
+ { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */
+ { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */
+ { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */
+ { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */
+ { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */
+ { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */
+ { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */
+ { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */
+ { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */
+ { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */
+ { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */
+ { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */
+ { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */
+ { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */
+ { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */
+ { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */
+ { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */
+ { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */
+ { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */
+ { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */
+ { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */
+ { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */
+ { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */
+ { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */
+ { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */
+ { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */
+ { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */
+ { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */
+ { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */
+ { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */
+ { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */
+ { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */
+ { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */
+ { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */
+ { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */
+ { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */
+ { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */
+ { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */
+ { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */
+ { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */
+ { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */
+ { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */
+ { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */
+ { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */
+ { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */
+ { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */
+ { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */
+ { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */
+ { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */
+ { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */
+ { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */
+ { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */
+ { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */
+ { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */
+ { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */
+ { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */
+ { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */
+ { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */
+ { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */
+ { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */
+ { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */
+ { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */
+ { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */
+ { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */
+ { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */
+ { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */
+ { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */
+ { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */
+ { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */
+ { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */
+ { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */
+ { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */
+ { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */
+ { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */
+ { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */
+ { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */
+ { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */
+ { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */
+ { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */
+ { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */
+ { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */
+ { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */
+ { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */
+ { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */
+ { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */
+ { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */
+ { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */
+ { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */
+ { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */
+ { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */
+ { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */
+ { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */
+ { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */
+ { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */
+ { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */
+ { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */
+ { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */
+ { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */
+ { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */
+ { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */
+ { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */
+ { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */
+ { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */
+ { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */
+ { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */
+ { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */
+ { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */
+ { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */
+ { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */
+ { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */
+ { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/
+ { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/
+ { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/
+ { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */
+ { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
+ { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
+ { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
+ { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
+ { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
+ { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
+ { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
+ { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
+ { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
+ { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
+ { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
+ { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
+ { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
+ { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
+ { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
+ { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
+ { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
+ { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
+ { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
+ { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
+ { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
+ { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
+ { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
+ { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
+ { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
+ { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
+ { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
+ { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
+ { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
+ { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
+ { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
+ { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
+ { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/
+ { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
+ { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
+ { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
+ { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
+ { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
+ { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
+ { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
+ { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
+ { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
+ { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
+ { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
+ { 0xffff , 0xffffffff , 0xffffffff },
+};
+static const struct stb0899_s2_reg stb0899_s2_init_4[] = {
+ { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */
+ { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */
+ { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */
+ { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */
+ { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */
+ { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */
+ { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */
+ { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */
+ { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */
+ { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */
+ { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */
+ { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */
+ { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */
+ { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */
+ { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */
+ { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */
+ { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */
+ { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */
+ { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */
+ { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */
+ { 0xffff , 0xffffffff , 0xffffffff },
+};
+
+static const struct stb0899_s1_reg stb0899_s1_init_5[] = {
+ { STB0899_TSTCK , 0x00 },
+ { STB0899_TSTRES , 0x00 },
+ { STB0899_TSTOUT , 0x00 },
+ { STB0899_TSTIN , 0x00 },
+ { STB0899_TSTSYS , 0x00 },
+ { STB0899_TSTCHIP , 0x00 },
+ { STB0899_TSTFREE , 0x00 },
+ { STB0899_TSTI2C , 0x00 },
+ { STB0899_BITSPEEDM , 0x00 },
+ { STB0899_BITSPEEDL , 0x00 },
+ { STB0899_TBUSBIT , 0x00 },
+ { STB0899_TSTDIS , 0x00 },
+ { STB0899_TSTDISRX , 0x00 },
+ { STB0899_TSTJETON , 0x00 },
+ { STB0899_TSTDCADJ , 0x00 },
+ { STB0899_TSTAGC1 , 0x00 },
+ { STB0899_TSTAGC1N , 0x00 },
+ { STB0899_TSTPOLYPH , 0x00 },
+ { STB0899_TSTR , 0x00 },
+ { STB0899_TSTAGC2 , 0x00 },
+ { STB0899_TSTCTL1 , 0x00 },
+ { STB0899_TSTCTL2 , 0x00 },
+ { STB0899_TSTCTL3 , 0x00 },
+ { STB0899_TSTDEMAP , 0x00 },
+ { STB0899_TSTDEMAP2 , 0x00 },
+ { STB0899_TSTDEMMON , 0x00 },
+ { STB0899_TSTRATE , 0x00 },
+ { STB0899_TSTSELOUT , 0x00 },
+ { STB0899_TSYNC , 0x00 },
+ { STB0899_TSTERR , 0x00 },
+ { STB0899_TSTRAM1 , 0x00 },
+ { STB0899_TSTVSELOUT , 0x00 },
+ { STB0899_TSTFORCEIN , 0x00 },
+ { STB0899_TSTRS1 , 0x00 },
+ { STB0899_TSTRS2 , 0x00 },
+ { STB0899_TSTRS3 , 0x00 },
+ { STB0899_GHOSTREG , 0x81 },
+ { 0xffff , 0xff },
+};
+
+#define STB0899_DVBS2_ESNO_AVE 3
+#define STB0899_DVBS2_ESNO_QUANT 32
+#define STB0899_DVBS2_AVFRAMES_COARSE 10
+#define STB0899_DVBS2_AVFRAMES_FINE 20
+#define STB0899_DVBS2_MISS_THRESHOLD 6
+#define STB0899_DVBS2_UWP_THRESHOLD_ACQ 1125
+#define STB0899_DVBS2_UWP_THRESHOLD_TRACK 758
+#define STB0899_DVBS2_UWP_THRESHOLD_SOF 1350
+#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT 1664100
+
+#define STB0899_DVBS2_BTR_NCO_BITS 28
+#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET 15
+#define STB0899_DVBS2_CRL_NCO_BITS 30
+#define STB0899_DVBS2_LDPC_MAX_ITER 70
+
+#endif //__STB0899_CFG_H
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
new file mode 100644
index 000000000000..528820170228
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -0,0 +1,1684 @@
+/*
+ STB0899 Multistandard Frontend driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#include "stb0899_drv.h"
+#include "stb0899_priv.h"
+#include "stb0899_reg.h"
+
+static unsigned int verbose = 0;//1;
+module_param(verbose, int, 0644);
+
+/* C/N in dB/10, NIRM/NIRL */
+static const struct stb0899_tab stb0899_cn_tab[] = {
+ { 200, 2600 },
+ { 190, 2700 },
+ { 180, 2860 },
+ { 170, 3020 },
+ { 160, 3210 },
+ { 150, 3440 },
+ { 140, 3710 },
+ { 130, 4010 },
+ { 120, 4360 },
+ { 110, 4740 },
+ { 100, 5190 },
+ { 90, 5670 },
+ { 80, 6200 },
+ { 70, 6770 },
+ { 60, 7360 },
+ { 50, 7970 },
+ { 40, 8250 },
+ { 30, 9000 },
+ { 20, 9450 },
+ { 15, 9600 },
+};
+
+/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10.
+ * As measured, connected to a modulator.
+ * -8.0 to -50.0 dBm directly connected,
+ * -52.0 to -74.8 with extra attenuation.
+ * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm.
+ * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
+ */
+static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
+ { -950, -128 },
+ { -748, -94 },
+ { -745, -92 },
+ { -735, -90 },
+ { -720, -87 },
+ { -670, -77 },
+ { -640, -70 },
+ { -610, -62 },
+ { -600, -60 },
+ { -590, -56 },
+ { -560, -41 },
+ { -540, -25 },
+ { -530, -17 },
+ { -520, -11 },
+ { -500, 1 },
+ { -490, 6 },
+ { -480, 10 },
+ { -440, 22 },
+ { -420, 27 },
+ { -400, 31 },
+ { -380, 34 },
+ { -340, 40 },
+ { -320, 43 },
+ { -280, 48 },
+ { -250, 52 },
+ { -230, 55 },
+ { -180, 61 },
+ { -140, 66 },
+ { -90, 73 },
+ { -80, 74 },
+ { 500, 127 }
+};
+
+/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10.
+ * As measured, connected to a modulator.
+ * -8.0 to -50.1 dBm directly connected,
+ * -53.0 to -76.6 with extra attenuation.
+ * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm.
+ * Crude linear extrapolation below -76.6dBm and above -8.0dBm.
+ */
+static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
+ { 700, 0 },
+ { -80, 3217 },
+ { -150, 3893 },
+ { -190, 4217 },
+ { -240, 4621 },
+ { -280, 4945 },
+ { -320, 5273 },
+ { -350, 5545 },
+ { -370, 5741 },
+ { -410, 6147 },
+ { -450, 6671 },
+ { -490, 7413 },
+ { -501, 7665 },
+ { -530, 8767 },
+ { -560, 10219 },
+ { -580, 10939 },
+ { -590, 11518 },
+ { -600, 11723 },
+ { -650, 12659 },
+ { -690, 13219 },
+ { -730, 13645 },
+ { -750, 13909 },
+ { -766, 14153 },
+ { -999, 16383 }
+};
+
+/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
+struct stb0899_tab stb0899_quant_tab[] = {
+ { 0, 0 },
+ { 0, 100 },
+ { 600, 200 },
+ { 950, 299 },
+ { 1200, 398 },
+ { 1400, 501 },
+ { 1560, 603 },
+ { 1690, 700 },
+ { 1810, 804 },
+ { 1910, 902 },
+ { 2000, 1000 },
+ { 2080, 1096 },
+ { 2160, 1202 },
+ { 2230, 1303 },
+ { 2350, 1496 },
+ { 2410, 1603 },
+ { 2460, 1698 },
+ { 2510, 1799 },
+ { 2600, 1995 },
+ { 2650, 2113 },
+ { 2690, 2213 },
+ { 2720, 2291 },
+ { 2760, 2399 },
+ { 2800, 2512 },
+ { 2860, 2692 },
+ { 2930, 2917 },
+ { 2960, 3020 },
+ { 3010, 3199 },
+ { 3040, 3311 },
+ { 3060, 3388 },
+ { 3120, 3631 },
+ { 3190, 3936 },
+ { 3400, 5012 },
+ { 3610, 6383 },
+ { 3800, 7943 },
+ { 4210, 12735 },
+ { 4500, 17783 },
+ { 4690, 22131 },
+ { 4810, 25410 }
+};
+
+/* DVB-S2 Es/N0 estimate in dB/100 vs read value */
+struct stb0899_tab stb0899_est_tab[] = {
+ { 0, 0 },
+ { 0, 1 },
+ { 301, 2 },
+ { 1204, 16 },
+ { 1806, 64 },
+ { 2408, 256 },
+ { 2709, 512 },
+ { 3010, 1023 },
+ { 3311, 2046 },
+ { 3612, 4093 },
+ { 3823, 6653 },
+ { 3913, 8185 },
+ { 4010, 10233 },
+ { 4107, 12794 },
+ { 4214, 16368 },
+ { 4266, 18450 },
+ { 4311, 20464 },
+ { 4353, 22542 },
+ { 4391, 24604 },
+ { 4425, 26607 },
+ { 4457, 28642 },
+ { 4487, 30690 },
+ { 4515, 32734 },
+ { 4612, 40926 },
+ { 4692, 49204 },
+ { 4816, 65464 },
+ { 4913, 81846 },
+ { 4993, 98401 },
+ { 5060, 114815 },
+ { 5118, 131220 },
+ { 5200, 158489 },
+ { 5300, 199526 },
+ { 5400, 251189 },
+ { 5500, 316228 },
+ { 5600, 398107 },
+ { 5720, 524807 },
+ { 5721, 526017 },
+};
+
+int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
+{
+ int ret;
+
+ u8 b0[] = { reg >> 8, reg & 0xff };
+ u8 buf;
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = b0,
+ .len = 2
+ },{
+ .addr = state->config->demod_address,
+ .flags = I2C_M_RD,
+ .buf = &buf,
+ .len = 1
+ }
+ };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2) {
+ if (ret != -ERESTARTSYS)
+ dprintk(state->verbose, FE_ERROR, 1,
+ "Read error, Reg=[0x%02x], Status=%d",
+ reg, ret);
+
+ return ret < 0 ? ret : -EREMOTEIO;
+ }
+ if (unlikely(*state->verbose >= FE_DEBUGREG))
+ dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
+ reg, buf);
+
+ return (unsigned int)buf;
+}
+
+int stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
+{
+ int result;
+
+ result = _stb0899_read_reg(state, reg);
+ /*
+ * Bug ID 9:
+ * access to 0xf2xx/0xf6xx
+ * must be followed by read from 0xf2ff/0xf6ff.
+ */
+ if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
+ (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+ _stb0899_read_reg(state, (reg | 0x00ff));
+
+ return result;
+}
+
+u32 _stb0899_read_s2reg(struct stb0899_state *state,
+ u32 stb0899_i2cdev,
+ u32 stb0899_base_addr,
+ u16 stb0899_reg_offset)
+{
+ int status;
+ u32 data;
+ u8 buf[7] = { 0 };
+ u16 tmpaddr;
+
+ u8 buf_0[] = {
+ GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */
+ GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */
+ GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */
+ GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */
+ GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */
+ GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */
+ };
+ u8 buf_1[] = {
+ 0x00, /* 0xf3 Reg Offset */
+ 0x00, /* 0x44 Reg Offset */
+ };
+
+ struct i2c_msg msg_0 = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf_0,
+ .len = 6
+ };
+
+ struct i2c_msg msg_1 = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf_1,
+ .len = 2
+ };
+
+ struct i2c_msg msg_r = {
+ .addr = state->config->demod_address,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = 4
+ };
+
+ tmpaddr = stb0899_reg_offset & 0xff00;
+ if (!(stb0899_reg_offset & 0x8))
+ tmpaddr = stb0899_reg_offset | 0x20;
+
+ buf_1[0] = GETBYTE(tmpaddr, BYTE1);
+ buf_1[1] = GETBYTE(tmpaddr, BYTE0);
+
+ status = i2c_transfer(state->i2c, &msg_0, 1);
+ if (status < 1) {
+ if (status != -ERESTARTSYS)
+ printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+
+ goto err;
+ }
+
+ /* Dummy */
+ status = i2c_transfer(state->i2c, &msg_1, 1);
+ if (status < 1)
+ goto err;
+
+ status = i2c_transfer(state->i2c, &msg_r, 1);
+ if (status < 1)
+ goto err;
+
+ buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
+ buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
+
+ /* Actual */
+ status = i2c_transfer(state->i2c, &msg_1, 1);
+ if (status < 1) {
+ if (status != -ERESTARTSYS)
+ printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+ goto err;
+ }
+
+ status = i2c_transfer(state->i2c, &msg_r, 1);
+ if (status < 1) {
+ if (status != -ERESTARTSYS)
+ printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
+ return status < 0 ? status : -EREMOTEIO;
+ }
+
+ data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]);
+ if (unlikely(*state->verbose >= FE_DEBUGREG))
+ printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data);
+
+ return data;
+
+err:
+ return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_write_s2reg(struct stb0899_state *state,
+ u32 stb0899_i2cdev,
+ u32 stb0899_base_addr,
+ u16 stb0899_reg_offset,
+ u32 stb0899_data)
+{
+ int status;
+
+ /* Base Address Setup */
+ u8 buf_0[] = {
+ GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */
+ GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */
+ GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */
+ GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */
+ GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */
+ GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */
+ };
+ u8 buf_1[] = {
+ 0x00, /* 0xf3 Reg Offset */
+ 0x00, /* 0x44 Reg Offset */
+ 0x00, /* data */
+ 0x00, /* data */
+ 0x00, /* data */
+ 0x00, /* data */
+ };
+
+ struct i2c_msg msg_0 = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf_0,
+ .len = 6
+ };
+
+ struct i2c_msg msg_1 = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf_1,
+ .len = 6
+ };
+
+ buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
+ buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
+ buf_1[2] = GETBYTE(stb0899_data, BYTE0);
+ buf_1[3] = GETBYTE(stb0899_data, BYTE1);
+ buf_1[4] = GETBYTE(stb0899_data, BYTE2);
+ buf_1[5] = GETBYTE(stb0899_data, BYTE3);
+
+ if (unlikely(*state->verbose >= FE_DEBUGREG))
+ printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data);
+
+ status = i2c_transfer(state->i2c, &msg_0, 1);
+ if (unlikely(status < 1)) {
+ if (status != -ERESTARTSYS)
+ printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
+ goto err;
+ }
+ status = i2c_transfer(state->i2c, &msg_1, 1);
+ if (unlikely(status < 1)) {
+ if (status != -ERESTARTSYS)
+ printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
+ __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
+
+ return status < 0 ? status : -EREMOTEIO;
+ }
+
+ return 0;
+
+err:
+ return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count)
+{
+ int status;
+
+ u8 b0[] = { reg >> 8, reg & 0xff };
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = b0,
+ .len = 2
+ },{
+ .addr = state->config->demod_address,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = count
+ }
+ };
+
+ status = i2c_transfer(state->i2c, msg, 2);
+ if (status != 2) {
+ if (status != -ERESTARTSYS)
+ printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n",
+ __func__, reg, count, status);
+ goto err;
+ }
+ /*
+ * Bug ID 9:
+ * access to 0xf2xx/0xf6xx
+ * must be followed by read from 0xf2ff/0xf6ff.
+ */
+ if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
+ (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+ _stb0899_read_reg(state, (reg | 0x00ff));
+
+ if (unlikely(*state->verbose >= FE_DEBUGREG)) {
+ int i;
+
+ printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+ for (i = 0; i < count; i++) {
+ printk(" %02x", buf[i]);
+ }
+ printk("\n");
+ }
+
+ return 0;
+err:
+ return status < 0 ? status : -EREMOTEIO;
+}
+
+int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count)
+{
+ int ret;
+ u8 buf[2 + count];
+ struct i2c_msg i2c_msg = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf,
+ .len = 2 + count
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ memcpy(&buf[2], data, count);
+
+ if (unlikely(*state->verbose >= FE_DEBUGREG)) {
+ int i;
+
+ printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
+ for (i = 0; i < count; i++)
+ printk(" %02x", data[i]);
+ printk("\n");
+ }
+ ret = i2c_transfer(state->i2c, &i2c_msg, 1);
+
+ /*
+ * Bug ID 9:
+ * access to 0xf2xx/0xf6xx
+ * must be followed by read from 0xf2ff/0xf6ff.
+ */
+ if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
+ stb0899_read_reg(state, (reg | 0x00ff));
+
+ if (ret != 1) {
+ if (ret != -ERESTARTSYS)
+ dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
+ reg, data[0], count, ret);
+ return ret < 0 ? ret : -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
+{
+ return stb0899_write_regs(state, reg, &data, 1);
+}
+
+/*
+ * stb0899_get_mclk
+ * Get STB0899 master clock frequency
+ * ExtClk: external clock frequency (Hz)
+ */
+static u32 stb0899_get_mclk(struct stb0899_state *state)
+{
+ u32 mclk = 0, div = 0;
+
+ div = stb0899_read_reg(state, STB0899_NCOARSE);
+ mclk = (div + 1) * state->config->xtal_freq / 6;
+ dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk);
+
+ return mclk;
+}
+
+/*
+ * stb0899_set_mclk
+ * Set STB0899 master Clock frequency
+ * Mclk: demodulator master clock
+ * ExtClk: external clock frequency (Hz)
+ */
+static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk)
+{
+ struct stb0899_internal *internal = &state->internal;
+ u8 mdiv = 0;
+
+ dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config);
+ mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1;
+ dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv);
+
+ stb0899_write_reg(state, STB0899_NCOARSE, mdiv);
+ internal->master_clk = stb0899_get_mclk(state);
+
+ dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk);
+}
+
+static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable)
+{
+ struct stb0899_config *config = state->config;
+ const struct stb0899_postproc *postproc = config->postproc;
+
+ /* post process event */
+ if (postproc) {
+ if (enable) {
+ if (postproc[ctl].level == STB0899_GPIOPULLUP)
+ stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
+ else
+ stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
+ } else {
+ if (postproc[ctl].level == STB0899_GPIOPULLUP)
+ stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
+ else
+ stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
+ }
+ }
+ return 0;
+}
+
+static void stb0899_release(struct dvb_frontend *fe)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+
+ dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
+ /* post process event */
+ stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
+ kfree(state);
+}
+
+/*
+ * stb0899_get_alpha
+ * return: rolloff
+ */
+static int stb0899_get_alpha(struct stb0899_state *state)
+{
+ u8 mode_coeff;
+
+ mode_coeff = stb0899_read_reg(state, STB0899_DEMOD);
+
+ if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1)
+ return 20;
+ else
+ return 35;
+}
+
+/*
+ * stb0899_init_calc
+ */
+static void stb0899_init_calc(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ int master_clk;
+ u8 agc[2];
+ u8 agc1cn;
+ u32 reg;
+
+ /* Read registers (in burst mode) */
+ agc1cn = stb0899_read_reg(state, STB0899_AGC1CN);
+ stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */
+
+ /* Initial calculations */
+ master_clk = stb0899_get_mclk(state);
+ internal->t_agc1 = 0;
+ internal->t_agc2 = 0;
+ internal->master_clk = master_clk;
+ internal->mclk = master_clk / 65536L;
+ internal->rolloff = stb0899_get_alpha(state);
+
+ /* DVBS2 Initial calculations */
+ /* Set AGC value to the middle */
+ internal->agc_gain = 8154;
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
+ STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA);
+ internal->rrc_alpha = STB0899_GETFIELD(RRC_ALPHA, reg);
+
+ internal->center_freq = 0;
+ internal->av_frame_coarse = 10;
+ internal->av_frame_fine = 20;
+ internal->step_size = 2;
+/*
+ if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO))
+ pParams->IQLocked = 0;
+ else
+ pParams->IQLocked = 1;
+*/
+}
+
+static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout)
+{
+ u8 reg = 0;
+ unsigned long start = jiffies;
+
+ while (1) {
+ reg = stb0899_read_reg(state, STB0899_DISSTATUS);
+ if (!STB0899_GETFIELD(FIFOFULL, reg))
+ break;
+ if ((jiffies - start) > timeout) {
+ dprintk(state->verbose, FE_ERROR, 1, "timed out !!");
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ u8 reg, i;
+
+ if (cmd->msg_len > 8)
+ return -EINVAL;
+
+ /* enable FIFO precharge */
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+ STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1);
+ stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+ for (i = 0; i < cmd->msg_len; i++) {
+ /* wait for FIFO empty */
+ if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0)
+ return -ETIMEDOUT;
+
+ stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]);
+ }
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+ STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
+ stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+ return 0;
+}
+
+static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout)
+{
+ u8 reg = 0;
+ unsigned long start = jiffies;
+
+ while (!STB0899_GETFIELD(RXEND, reg)) {
+ reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
+ if (jiffies - start > timeout) {
+ dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
+ return -ETIMEDOUT;
+ }
+ msleep(10);
+ }
+
+ return 0;
+}
+
+static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ u8 reg, length = 0, i;
+ int result;
+
+ if (stb0899_wait_diseqc_rxidle(state, 100) < 0)
+ return -ETIMEDOUT;
+
+ reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
+ if (STB0899_GETFIELD(RXEND, reg)) {
+
+ reg = stb0899_read_reg(state, STB0899_DISRX_ST1);
+ length = STB0899_GETFIELD(FIFOBYTENBR, reg);
+
+ if (length > sizeof (reply->msg)) {
+ result = -EOVERFLOW;
+ goto exit;
+ }
+ reply->msg_len = length;
+
+ /* extract data */
+ for (i = 0; i < length; i++)
+ reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO);
+ }
+
+ return 0;
+exit:
+
+ return result;
+}
+
+static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout)
+{
+ u8 reg = 0;
+ unsigned long start = jiffies;
+
+ while (!STB0899_GETFIELD(TXIDLE, reg)) {
+ reg = stb0899_read_reg(state, STB0899_DISSTATUS);
+ if (jiffies - start > timeout) {
+ dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
+ return -ETIMEDOUT;
+ }
+ msleep(10);
+ }
+ return 0;
+}
+
+static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ u8 reg, old_state;
+
+ /* wait for diseqc idle */
+ if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+ return -ETIMEDOUT;
+
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+ old_state = reg;
+ /* set to burst mode */
+ STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02);
+ STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
+ stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+ switch (burst) {
+ case SEC_MINI_A:
+ /* unmodulated */
+ stb0899_write_reg(state, STB0899_DISFIFO, 0x00);
+ break;
+ case SEC_MINI_B:
+ /* modulated */
+ stb0899_write_reg(state, STB0899_DISFIFO, 0xff);
+ break;
+ }
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+ STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00);
+ stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+ /* wait for diseqc idle */
+ if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+ return -ETIMEDOUT;
+
+ /* restore state */
+ stb0899_write_reg(state, STB0899_DISCNTRL1, old_state);
+
+ return 0;
+}
+
+static int stb0899_diseqc_init(struct stb0899_state *state)
+{
+ struct dvb_diseqc_master_cmd tx_data;
+/*
+ struct dvb_diseqc_slave_reply rx_data;
+*/
+ u8 f22_tx, f22_rx, reg;
+
+ u32 mclk, tx_freq = 22000;/* count = 0, i; */
+ tx_data.msg[0] = 0xe2;
+ tx_data.msg_len = 3;
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
+ STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
+ stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
+
+ /* disable Tx spy */
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+ STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1);
+ stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+ reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
+ STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0);
+ stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
+
+ mclk = stb0899_get_mclk(state);
+ f22_tx = mclk / (tx_freq * 32);
+ stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */
+ state->rx_freq = 20000;
+ f22_rx = mclk / (state->rx_freq * 32);
+
+ return 0;
+}
+
+static int stb0899_sleep(struct dvb_frontend *fe)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+/*
+ u8 reg;
+*/
+ dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))");
+ /* post process event */
+ stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
+
+ return 0;
+}
+
+static int stb0899_wakeup(struct dvb_frontend *fe)
+{
+ int rc;
+ struct stb0899_state *state = fe->demodulator_priv;
+
+ if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
+ return rc;
+ /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
+ if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
+ return rc;
+ if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
+ return rc;
+
+ /* post process event */
+ stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1);
+
+ return 0;
+}
+
+static int stb0899_init(struct dvb_frontend *fe)
+{
+ int i;
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_config *config = state->config;
+
+ dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
+
+ /* init device */
+ dprintk(state->verbose, FE_DEBUG, 1, "init device");
+ for (i = 0; config->init_dev[i].address != 0xffff; i++)
+ stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data);
+
+ dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod");
+ /* init S2 demod */
+ for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++)
+ stb0899_write_s2reg(state, STB0899_S2DEMOD,
+ config->init_s2_demod[i].base_address,
+ config->init_s2_demod[i].offset,
+ config->init_s2_demod[i].data);
+
+ dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod");
+ /* init S1 demod */
+ for (i = 0; config->init_s1_demod[i].address != 0xffff; i++)
+ stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data);
+
+ dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC");
+ /* init S2 fec */
+ for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++)
+ stb0899_write_s2reg(state, STB0899_S2FEC,
+ config->init_s2_fec[i].base_address,
+ config->init_s2_fec[i].offset,
+ config->init_s2_fec[i].data);
+
+ dprintk(state->verbose, FE_DEBUG, 1, "init TST");
+ /* init test */
+ for (i = 0; config->init_tst[i].address != 0xffff; i++)
+ stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
+
+ stb0899_init_calc(state);
+ stb0899_diseqc_init(state);
+
+ return 0;
+}
+
+static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val)
+{
+ int res = 0;
+ int min = 0, med;
+
+ if (val < tab[min].read)
+ res = tab[min].real;
+ else if (val >= tab[max].read)
+ res = tab[max].real;
+ else {
+ while ((max - min) > 1) {
+ med = (max + min) / 2;
+ if (val >= tab[min].read && val < tab[med].read)
+ max = med;
+ else
+ min = med;
+ }
+ res = ((val - tab[min].read) *
+ (tab[max].real - tab[min].real) /
+ (tab[max].read - tab[min].read)) +
+ tab[min].real;
+ }
+
+ return res;
+}
+
+static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_internal *internal = &state->internal;
+
+ int val;
+ u32 reg;
+ switch (state->delsys) {
+ case SYS_DVBS:
+ case SYS_DSS:
+ if (internal->lock) {
+ reg = stb0899_read_reg(state, STB0899_VSTATUS);
+ if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+
+ reg = stb0899_read_reg(state, STB0899_AGCIQIN);
+ val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg);
+
+ *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
+ *strength += 750;
+ dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
+ val & 0xff, *strength);
+ }
+ }
+ break;
+ case SYS_DVBS2:
+ if (internal->lock) {
+ reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN);
+ val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
+
+ *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
+ *strength += 750;
+ dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
+ val & 0x3fff, *strength);
+ }
+ break;
+ default:
+ dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_internal *internal = &state->internal;
+
+ unsigned int val, quant, quantn = -1, est, estn = -1;
+ u8 buf[2];
+ u32 reg;
+
+ reg = stb0899_read_reg(state, STB0899_VSTATUS);
+ switch (state->delsys) {
+ case SYS_DVBS:
+ case SYS_DSS:
+ if (internal->lock) {
+ if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+
+ stb0899_read_regs(state, STB0899_NIRM, buf, 2);
+ val = MAKEWORD16(buf[0], buf[1]);
+
+ *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
+ dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
+ buf[0], buf[1], val, *snr);
+ }
+ }
+ break;
+ case SYS_DVBS2:
+ if (internal->lock) {
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
+ quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg);
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
+ est = STB0899_GETFIELD(ESN0_EST, reg);
+ if (est == 1)
+ val = 301; /* C/N = 30.1 dB */
+ else if (est == 2)
+ val = 270; /* C/N = 27.0 dB */
+ else {
+ /* quantn = 100 * log(quant^2) */
+ quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100);
+ /* estn = 100 * log(est) */
+ estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est);
+ /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */
+ val = (quantn - estn) / 10;
+ }
+ *snr = val;
+ dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
+ quant, quantn, est, estn, val);
+ }
+ break;
+ default:
+ dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_internal *internal = &state->internal;
+ u8 reg;
+ *status = 0;
+
+ switch (state->delsys) {
+ case SYS_DVBS:
+ case SYS_DSS:
+ dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS");
+ if (internal->lock) {
+ reg = stb0899_read_reg(state, STB0899_VSTATUS);
+ if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
+ dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
+ *status |= FE_HAS_CARRIER | FE_HAS_LOCK;
+
+ reg = stb0899_read_reg(state, STB0899_PLPARM);
+ if (STB0899_GETFIELD(VITCURPUN, reg)) {
+ dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC");
+ *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
+ /* post process event */
+ stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
+ }
+ }
+ }
+ break;
+ case SYS_DVBS2:
+ dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2");
+ if (internal->lock) {
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
+ if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) {
+ *status |= FE_HAS_CARRIER;
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER");
+
+ reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
+ if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) {
+ *status |= FE_HAS_LOCK;
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK");
+
+ }
+ if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) {
+ *status |= FE_HAS_VITERBI;
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI");
+ }
+ if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) {
+ *status |= FE_HAS_SYNC;
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC");
+ /* post process event */
+ stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
+ }
+ }
+ }
+ break;
+ default:
+ dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * stb0899_get_error
+ * viterbi error for DVB-S/DSS
+ * packet error for DVB-S2
+ * Bit Error Rate or Packet Error Rate * 10 ^ 7
+ */
+static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_internal *internal = &state->internal;
+
+ u8 lsb, msb;
+ u32 i;
+
+ *ber = 0;
+
+ switch (state->delsys) {
+ case SYS_DVBS:
+ case SYS_DSS:
+ if (internal->lock) {
+ /* average 5 BER values */
+ for (i = 0; i < 5; i++) {
+ msleep(100);
+ lsb = stb0899_read_reg(state, STB0899_ECNT1L);
+ msb = stb0899_read_reg(state, STB0899_ECNT1M);
+ *ber += MAKEWORD16(msb, lsb);
+ }
+ *ber /= 5;
+ /* Viterbi Check */
+ if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
+ /* Error Rate */
+ *ber *= 9766;
+ /* ber = ber * 10 ^ 7 */
+ *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
+ *ber /= 8;
+ }
+ }
+ break;
+ case SYS_DVBS2:
+ if (internal->lock) {
+ /* Average 5 PER values */
+ for (i = 0; i < 5; i++) {
+ msleep(100);
+ lsb = stb0899_read_reg(state, STB0899_ECNT1L);
+ msb = stb0899_read_reg(state, STB0899_ECNT1M);
+ *ber += MAKEWORD16(msb, lsb);
+ }
+ /* ber = ber * 10 ^ 7 */
+ *ber *= 10000000;
+ *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
+ }
+ break;
+ default:
+ dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+
+ switch (voltage) {
+ case SEC_VOLTAGE_13:
+ stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
+ stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
+ stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00);
+ break;
+ case SEC_VOLTAGE_18:
+ stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02);
+ stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
+ stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
+ break;
+ case SEC_VOLTAGE_OFF:
+ stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
+ stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82);
+ stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_internal *internal = &state->internal;
+
+ u8 div, reg;
+
+ /* wait for diseqc idle */
+ if (stb0899_wait_diseqc_txidle(state, 100) < 0)
+ return -ETIMEDOUT;
+
+ switch (tone) {
+ case SEC_TONE_ON:
+ div = (internal->master_clk / 100) / 5632;
+ div = (div + 5) / 10;
+ stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
+ reg = stb0899_read_reg(state, STB0899_ACRPRESC);
+ STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03);
+ stb0899_write_reg(state, STB0899_ACRPRESC, reg);
+ stb0899_write_reg(state, STB0899_ACRDIV1, div);
+ break;
+ case SEC_TONE_OFF:
+ stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ int i2c_stat;
+ struct stb0899_state *state = fe->demodulator_priv;
+
+ i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT);
+ if (i2c_stat < 0)
+ goto err;
+
+ if (enable) {
+ dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ...");
+ i2c_stat |= STB0899_I2CTON;
+ if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
+ goto err;
+ } else {
+ dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ...");
+ i2c_stat &= ~STB0899_I2CTON;
+ if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed");
+ return -EREMOTEIO;
+}
+
+
+static inline void CONVERT32(u32 x, char *str)
+{
+ *str++ = (x >> 24) & 0xff;
+ *str++ = (x >> 16) & 0xff;
+ *str++ = (x >> 8) & 0xff;
+ *str++ = (x >> 0) & 0xff;
+ *str = '\0';
+}
+
+int stb0899_get_dev_id(struct stb0899_state *state)
+{
+ u8 chip_id, release;
+ u16 id;
+ u32 demod_ver = 0, fec_ver = 0;
+ char demod_str[5] = { 0 };
+ char fec_str[5] = { 0 };
+
+ id = stb0899_read_reg(state, STB0899_DEV_ID);
+ dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id);
+ chip_id = STB0899_GETFIELD(CHIP_ID, id);
+ release = STB0899_GETFIELD(CHIP_REL, id);
+
+ dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]",
+ chip_id, release);
+
+ CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str);
+
+ demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID);
+ dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver);
+ CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str);
+ fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG);
+ if (! (chip_id > 0)) {
+ dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899");
+
+ return -ENODEV;
+ }
+ dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver);
+
+ return 0;
+}
+
+static void stb0899_set_delivery(struct stb0899_state *state)
+{
+ u8 reg;
+ u8 stop_clk[2];
+
+ stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1);
+ stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2);
+
+ switch (state->delsys) {
+ case SYS_DVBS:
+ dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S");
+ /* FECM/Viterbi ON */
+ reg = stb0899_read_reg(state, STB0899_FECM);
+ STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
+ STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_FECM, reg);
+
+ stb0899_write_reg(state, STB0899_RSULC, 0xb1);
+ stb0899_write_reg(state, STB0899_TSULC, 0x40);
+ stb0899_write_reg(state, STB0899_RSLLC, 0x42);
+ stb0899_write_reg(state, STB0899_TSLPL, 0x12);
+
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+ STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
+ STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
+
+ STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
+ STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
+
+ STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1);
+ STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+ STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
+ break;
+ case SYS_DVBS2:
+ /* FECM/Viterbi OFF */
+ reg = stb0899_read_reg(state, STB0899_FECM);
+ STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
+ STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0);
+ stb0899_write_reg(state, STB0899_FECM, reg);
+
+ stb0899_write_reg(state, STB0899_RSULC, 0xb1);
+ stb0899_write_reg(state, STB0899_TSULC, 0x42);
+ stb0899_write_reg(state, STB0899_RSLLC, 0x40);
+ stb0899_write_reg(state, STB0899_TSLPL, 0x02);
+
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESLDPC, reg, 0);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+ STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0);
+ STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0);
+
+ STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0);
+ STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0);
+
+ STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0);
+ STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+ STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0);
+ break;
+ case SYS_DSS:
+ /* FECM/Viterbi ON */
+ reg = stb0899_read_reg(state, STB0899_FECM);
+ STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1);
+ STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
+ stb0899_write_reg(state, STB0899_FECM, reg);
+
+ stb0899_write_reg(state, STB0899_RSULC, 0xa1);
+ stb0899_write_reg(state, STB0899_TSULC, 0x61);
+ stb0899_write_reg(state, STB0899_RSLLC, 0x42);
+
+ reg = stb0899_read_reg(state, STB0899_TSTRES);
+ STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
+ stb0899_write_reg(state, STB0899_TSTRES, reg);
+
+ STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
+ STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
+ STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
+
+ STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
+ STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
+
+ STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
+
+ STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
+ break;
+ default:
+ dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
+ break;
+ }
+ STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0);
+ stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2);
+}
+
+/*
+ * stb0899_set_iterations
+ * set the LDPC iteration scale function
+ */
+static void stb0899_set_iterations(struct stb0899_state *state)
+{
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+
+ s32 iter_scale;
+ u32 reg;
+
+ iter_scale = 17 * (internal->master_clk / 1000);
+ iter_scale += 410000;
+ iter_scale /= (internal->srate / 1000000);
+ iter_scale /= 1000;
+
+ if (iter_scale > config->ldpc_max_iter)
+ iter_scale = config->ldpc_max_iter;
+
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER);
+ STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg);
+}
+
+static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_params *i_params = &state->params;
+ struct stb0899_internal *internal = &state->internal;
+ struct stb0899_config *config = state->config;
+ struct dtv_frontend_properties *props = &fe->dtv_property_cache;
+
+ u32 SearchRange, gain;
+
+ i_params->freq = p->frequency;
+ i_params->srate = p->u.qpsk.symbol_rate;
+ state->delsys = props->delivery_system;
+ dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
+
+ SearchRange = 10000000;
+ dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
+ /* checking Search Range is meaningless for a fixed 3 Mhz */
+ if (INRANGE(i_params->srate, 1000000, 45000000)) {
+ dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE");
+ stb0899_set_delivery(state);
+
+ if (state->config->tuner_set_rfsiggain) {
+ if (internal->srate > 15000000)
+ gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */
+ else if (internal->srate > 5000000)
+ gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */
+ else
+ gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */
+ state->config->tuner_set_rfsiggain(fe, gain);
+ }
+
+ if (i_params->srate <= 5000000)
+ stb0899_set_mclk(state, config->lo_clk);
+ else
+ stb0899_set_mclk(state, config->hi_clk);
+
+ switch (state->delsys) {
+ case SYS_DVBS:
+ case SYS_DSS:
+ dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system");
+ internal->freq = i_params->freq;
+ internal->srate = i_params->srate;
+ /*
+ * search = user search range +
+ * 500Khz +
+ * 2 * Tuner_step_size +
+ * 10% of the symbol rate
+ */
+ internal->srch_range = SearchRange + 1500000 + (i_params->srate / 5);
+ internal->derot_percent = 30;
+
+ /* What to do for tuners having no bandwidth setup ? */
+ /* enable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+ if (state->config->tuner_set_bandwidth)
+ state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10);
+ if (state->config->tuner_get_bandwidth)
+ state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+
+ /* disable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+ /* Set DVB-S1 AGC */
+ stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
+
+ /* Run the search algorithm */
+ dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo ..");
+ if (stb0899_dvbs_algo(state) == RANGEOK) {
+ internal->lock = 1;
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "-------------------------------------> DVB-S LOCK !");
+
+// stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */
+// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
+// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
+// dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status);
+// dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl);
+
+ return DVBFE_ALGO_SEARCH_SUCCESS;
+ } else {
+ internal->lock = 0;
+
+ return DVBFE_ALGO_SEARCH_FAILED;
+ }
+ break;
+ case SYS_DVBS2:
+ internal->freq = i_params->freq;
+ internal->srate = i_params->srate;
+ internal->srch_range = SearchRange;
+
+ /* enable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 1);
+
+ if (state->config->tuner_set_bandwidth)
+ state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange));
+ if (state->config->tuner_get_bandwidth)
+ state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
+
+ /* disable tuner I/O */
+ stb0899_i2c_gate_ctrl(&state->frontend, 0);
+
+// pParams->SpectralInv = pSearch->IQ_Inversion;
+
+ /* Set DVB-S2 AGC */
+ stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c);
+
+ /* Set IterScale =f(MCLK,SYMB) */
+ stb0899_set_iterations(state);
+
+ /* Run the search algorithm */
+ dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo ..");
+ if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) {
+ internal->lock = 1;
+ dprintk(state->verbose, FE_DEBUG, 1,
+ "-------------------------------------> DVB-S2 LOCK !");
+
+// stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */
+// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
+// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
+
+ return DVBFE_ALGO_SEARCH_SUCCESS;
+ } else {
+ internal->lock = 0;
+
+ return DVBFE_ALGO_SEARCH_FAILED;
+ }
+ break;
+ default:
+ dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
+ return DVBFE_ALGO_SEARCH_INVALID;
+ }
+ }
+
+ return DVBFE_ALGO_SEARCH_ERROR;
+}
+/*
+ * stb0899_track
+ * periodically check the signal level against a specified
+ * threshold level and perform derotator centering.
+ * called once we have a lock from a succesful search
+ * event.
+ *
+ * Will be called periodically called to maintain the
+ * lock.
+ *
+ * Will be used to get parameters as well as info from
+ * the decoded baseband header
+ *
+ * Once a new lock has established, the internal state
+ * frequency (internal->freq) is updated
+ */
+static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+ return 0;
+}
+
+static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+ struct stb0899_state *state = fe->demodulator_priv;
+ struct stb0899_internal *internal = &state->internal;
+
+ dprintk(state->verbose, FE_DEBUG, 1, "Get params");
+ p->u.qpsk.symbol_rate = internal->srate;
+
+ return 0;
+}
+
+static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_CUSTOM;
+}
+
+static struct dvb_frontend_ops stb0899_ops = {
+
+ .info = {
+ .name = "STB0899 Multistandard",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 0,
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 5000000,
+ .symbol_rate_max = 45000000,
+
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK
+ },
+
+ .release = stb0899_release,
+ .init = stb0899_init,
+ .sleep = stb0899_sleep,
+// .wakeup = stb0899_wakeup,
+
+ .i2c_gate_ctrl = stb0899_i2c_gate_ctrl,
+
+ .get_frontend_algo = stb0899_frontend_algo,
+ .search = stb0899_search,
+ .track = stb0899_track,
+ .get_frontend = stb0899_get_frontend,
+
+
+ .read_status = stb0899_read_status,
+ .read_snr = stb0899_read_snr,
+ .read_signal_strength = stb0899_read_signal_strength,
+ .read_ber = stb0899_read_ber,
+
+ .set_voltage = stb0899_set_voltage,
+ .set_tone = stb0899_set_tone,
+
+ .diseqc_send_master_cmd = stb0899_send_diseqc_msg,
+ .diseqc_recv_slave_reply = stb0899_recv_slave_reply,
+ .diseqc_send_burst = stb0899_send_diseqc_burst,
+};
+
+struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
+{
+ struct stb0899_state *state = NULL;
+ enum stb0899_inversion inversion;
+
+ state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ inversion = config->inversion;
+ state->verbose = &verbose;
+ state->config = config;
+ state->i2c = i2c;
+ state->frontend.ops = stb0899_ops;
+ state->frontend.demodulator_priv = state;
+ state->internal.inversion = inversion;
+
+ stb0899_wakeup(&state->frontend);
+ if (stb0899_get_dev_id(state) == -ENODEV) {
+ printk("%s: Exiting .. !\n", __func__);
+ goto error;
+ }
+
+ printk("%s: Attaching STB0899 \n", __func__);
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(stb0899_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h
new file mode 100644
index 000000000000..98b200ce0c34
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.h
@@ -0,0 +1,162 @@
+/*
+ STB0899 Multistandard Frontend driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_DRV_H
+#define __STB0899_DRV_H
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "dvb_frontend.h"
+
+#define STB0899_TSMODE_SERIAL 1
+#define STB0899_CLKPOL_FALLING 2
+#define STB0899_CLKNULL_PARITY 3
+#define STB0899_SYNC_FORCED 4
+#define STB0899_FECMODE_DSS 5
+
+struct stb0899_s1_reg {
+ u16 address;
+ u8 data;
+};
+
+struct stb0899_s2_reg {
+ u16 offset;
+ u32 base_address;
+ u32 data;
+};
+
+enum stb0899_inversion {
+ IQ_SWAP_OFF = 0,
+ IQ_SWAP_ON,
+ IQ_SWAP_AUTO
+};
+
+#define STB0899_GPIO00 0xf140
+#define STB0899_GPIO01 0xf141
+#define STB0899_GPIO02 0xf142
+#define STB0899_GPIO03 0xf143
+#define STB0899_GPIO04 0xf144
+#define STB0899_GPIO05 0xf145
+#define STB0899_GPIO06 0xf146
+#define STB0899_GPIO07 0xf147
+#define STB0899_GPIO08 0xf148
+#define STB0899_GPIO09 0xf149
+#define STB0899_GPIO10 0xf14a
+#define STB0899_GPIO11 0xf14b
+#define STB0899_GPIO12 0xf14c
+#define STB0899_GPIO13 0xf14d
+#define STB0899_GPIO14 0xf14e
+#define STB0899_GPIO15 0xf14f
+#define STB0899_GPIO16 0xf150
+#define STB0899_GPIO17 0xf151
+#define STB0899_GPIO18 0xf152
+#define STB0899_GPIO19 0xf153
+#define STB0899_GPIO20 0xf154
+
+#define STB0899_GPIOPULLUP 0x01 /* Output device is connected to Vdd */
+#define STB0899_GPIOPULLDN 0x00 /* Output device is connected to Vss */
+
+#define STB0899_POSTPROC_GPIO_POWER 0x00
+#define STB0899_POSTPROC_GPIO_LOCK 0x01
+
+/*
+ * Post process output configuration control
+ * 1. POWER ON/OFF (index 0)
+ * 2. FE_HAS_LOCK/LOCK_LOSS (index 1)
+ *
+ * @gpio = one of the above listed GPIO's
+ * @level = output state: pulled up or low
+ */
+struct stb0899_postproc {
+ u16 gpio;
+ u8 level;
+};
+
+struct stb0899_config {
+ const struct stb0899_s1_reg *init_dev;
+ const struct stb0899_s2_reg *init_s2_demod;
+ const struct stb0899_s1_reg *init_s1_demod;
+ const struct stb0899_s2_reg *init_s2_fec;
+ const struct stb0899_s1_reg *init_tst;
+
+ const struct stb0899_postproc *postproc;
+
+ enum stb0899_inversion inversion;
+
+ u32 xtal_freq;
+
+ u8 demod_address;
+ u8 ts_output_mode;
+ u8 block_sync_mode;
+ u8 ts_pfbit_toggle;
+
+ u8 clock_polarity;
+ u8 data_clk_parity;
+ u8 fec_mode;
+ u8 data_output_ctl;
+ u8 data_fifo_mode;
+ u8 out_rate_comp;
+ u8 i2c_repeater;
+// int inversion;
+ int lo_clk;
+ int hi_clk;
+
+ u32 esno_ave;
+ u32 esno_quant;
+ u32 avframes_coarse;
+ u32 avframes_fine;
+ u32 miss_threshold;
+ u32 uwp_threshold_acq;
+ u32 uwp_threshold_track;
+ u32 uwp_threshold_sof;
+ u32 sof_search_timeout;
+
+ u32 btr_nco_bits;
+ u32 btr_gain_shift_offset;
+ u32 crl_nco_bits;
+ u32 ldpc_max_iter;
+
+ int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
+ int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
+ int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+ int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+ int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain);
+};
+
+#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
+ struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+#endif //CONFIG_DVB_STB0899
+
+
+#endif
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
new file mode 100644
index 000000000000..24619e3689db
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_priv.h
@@ -0,0 +1,267 @@
+/*
+ STB0899 Multistandard Frontend driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_PRIV_H
+#define __STB0899_PRIV_H
+
+#include "dvb_frontend.h"
+#include "stb0899_drv.h"
+
+#define FE_ERROR 0
+#define FE_NOTICE 1
+#define FE_INFO 2
+#define FE_DEBUG 3
+#define FE_DEBUGREG 4
+
+#define dprintk(x, y, z, format, arg...) do { \
+ if (z) { \
+ if ((*x > FE_ERROR) && (*x > y)) \
+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
+ else if ((*x > FE_NOTICE) && (*x > y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
+ else if ((*x > FE_INFO) && (*x > y)) \
+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+ else if ((*x > FE_DEBUG) && (*x > y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
+ } else { \
+ if (*x > y) \
+ printk(format, ##arg); \
+ } \
+} while(0)
+
+#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \
+ ((y <= val) && (val <= x)) ? 1 : 0)
+
+#define BYTE0 0
+#define BYTE1 8
+#define BYTE2 16
+#define BYTE3 24
+
+#define GETBYTE(x, y) (((x) >> (y)) & 0xff)
+#define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+#define MAKEWORD16(a, b) (((a) << 8) | (b))
+
+#define MIN(x, y) ((x) <= (y) ? (x) : (y))
+#define MAX(x, y) ((x) >= (y) ? (x) : (y))
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+
+#define LSB(x) ((x & 0xff))
+#define MSB(y) ((y >> 8) & 0xff)
+
+
+#define STB0899_GETFIELD(bitf, val) ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1))
+
+
+#define STB0899_SETFIELD(mask, val, width, offset) (mask & (~(((1 << width) - 1) << \
+ offset))) | ((val & \
+ ((1 << width) - 1)) << offset)
+
+#define STB0899_SETFIELD_VAL(bitf, mask, val) (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\
+ STB0899_OFFST_##bitf))) | \
+ (val << STB0899_OFFST_##bitf))
+
+
+enum stb0899_status {
+ NOAGC1 = 0,
+ AGC1OK,
+ NOTIMING,
+ ANALOGCARRIER,
+ TIMINGOK,
+ NOAGC2,
+ AGC2OK,
+ NOCARRIER,
+ CARRIEROK,
+ NODATA,
+ FALSELOCK,
+ DATAOK,
+ OUTOFRANGE,
+ RANGEOK,
+ DVBS2_DEMOD_LOCK,
+ DVBS2_DEMOD_NOLOCK,
+ DVBS2_FEC_LOCK,
+ DVBS2_FEC_NOLOCK
+};
+
+enum stb0899_modcod {
+ STB0899_DUMMY_PLF,
+ STB0899_QPSK_14,
+ STB0899_QPSK_13,
+ STB0899_QPSK_25,
+ STB0899_QPSK_12,
+ STB0899_QPSK_35,
+ STB0899_QPSK_23,
+ STB0899_QPSK_34,
+ STB0899_QPSK_45,
+ STB0899_QPSK_56,
+ STB0899_QPSK_89,
+ STB0899_QPSK_910,
+ STB0899_8PSK_35,
+ STB0899_8PSK_23,
+ STB0899_8PSK_34,
+ STB0899_8PSK_56,
+ STB0899_8PSK_89,
+ STB0899_8PSK_910,
+ STB0899_16APSK_23,
+ STB0899_16APSK_34,
+ STB0899_16APSK_45,
+ STB0899_16APSK_56,
+ STB0899_16APSK_89,
+ STB0899_16APSK_910,
+ STB0899_32APSK_34,
+ STB0899_32APSK_45,
+ STB0899_32APSK_56,
+ STB0899_32APSK_89,
+ STB0899_32APSK_910
+};
+
+enum stb0899_frame {
+ STB0899_LONG_FRAME,
+ STB0899_SHORT_FRAME
+};
+
+enum stb0899_alpha {
+ RRC_20,
+ RRC_25,
+ RRC_35
+};
+
+struct stb0899_tab {
+ s32 real;
+ s32 read;
+};
+
+enum stb0899_fec {
+ STB0899_FEC_1_2 = 13,
+ STB0899_FEC_2_3 = 18,
+ STB0899_FEC_3_4 = 21,
+ STB0899_FEC_5_6 = 24,
+ STB0899_FEC_6_7 = 25,
+ STB0899_FEC_7_8 = 26
+};
+
+struct stb0899_params {
+ u32 freq; /* Frequency */
+ u32 srate; /* Symbol rate */
+ enum fe_code_rate fecrate;
+};
+
+struct stb0899_internal {
+ u32 master_clk;
+ u32 freq; /* Demod internal Frequency */
+ u32 srate; /* Demod internal Symbol rate */
+ enum stb0899_fec fecrate; /* Demod internal FEC rate */
+ u32 srch_range; /* Demod internal Search Range */
+ u32 sub_range; /* Demod current sub range (Hz) */
+ u32 tuner_step; /* Tuner step (Hz) */
+ u32 tuner_offst; /* Relative offset to carrier (Hz) */
+ u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */
+
+ s32 mclk; /* Masterclock Divider factor (binary) */
+ s32 rolloff; /* Current RollOff of the filter (x100) */
+
+ s16 derot_freq; /* Current derotator frequency (Hz) */
+ s16 derot_percent;
+
+ s16 direction; /* Current derotator search direction */
+ s16 derot_step; /* Derotator step (binary value) */
+ s16 t_derot; /* Derotator time constant (ms) */
+ s16 t_data; /* Data recovery time constant (ms) */
+ s16 sub_dir; /* Direction of the next sub range */
+
+ s16 t_agc1; /* Agc1 time constant (ms) */
+ s16 t_agc2; /* Agc2 time constant (ms) */
+
+ u32 lock; /* Demod internal lock state */
+ enum stb0899_status status; /* Demod internal status */
+
+ /* DVB-S2 */
+ s32 agc_gain; /* RF AGC Gain */
+ s32 center_freq; /* Nominal carrier frequency */
+ s32 av_frame_coarse; /* Coarse carrier freq search frames */
+ s32 av_frame_fine; /* Fine carrier freq search frames */
+
+ s16 step_size; /* Carrier frequency search step size */
+
+ enum stb0899_alpha rrc_alpha;
+ enum stb0899_inversion inversion;
+ enum stb0899_modcod modcod;
+ u8 pilots; /* Pilots found */
+
+ enum stb0899_frame frame_length;
+ u8 v_status; /* VSTATUS */
+ u8 err_ctrl; /* ERRCTRLn */
+};
+
+struct stb0899_state {
+ struct i2c_adapter *i2c;
+ struct stb0899_config *config;
+ struct dvb_frontend frontend;
+
+ u32 *verbose; /* Cached module verbosity level */
+
+ struct stb0899_internal internal; /* Device internal parameters */
+
+ /* cached params from API */
+ enum fe_delivery_system delsys;
+ struct stb0899_params params;
+
+ u32 rx_freq; /* DiSEqC 2.0 receiver freq */
+ struct mutex search_lock;
+};
+/* stb0899.c */
+extern int stb0899_read_reg(struct stb0899_state *state,
+ unsigned int reg);
+
+extern u32 _stb0899_read_s2reg(struct stb0899_state *state,
+ u32 stb0899_i2cdev,
+ u32 stb0899_base_addr,
+ u16 stb0899_reg_offset);
+
+extern int stb0899_read_regs(struct stb0899_state *state,
+ unsigned int reg, u8 *buf,
+ u32 count);
+
+extern int stb0899_write_regs(struct stb0899_state *state,
+ unsigned int reg, u8 *data,
+ u32 count);
+
+extern int stb0899_write_reg(struct stb0899_state *state,
+ unsigned int reg,
+ u8 data);
+
+extern int stb0899_write_s2reg(struct stb0899_state *state,
+ u32 stb0899_i2cdev,
+ u32 stb0899_base_addr,
+ u16 stb0899_reg_offset,
+ u32 stb0899_data);
+
+extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
+
+
+#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
+//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
+
+/* stb0899_algo.c */
+extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state);
+extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state);
+extern long stb0899_carr_width(struct stb0899_state *state);
+
+#endif //__STB0899_PRIV_H
diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h
new file mode 100644
index 000000000000..ba1ed56304a0
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_reg.h
@@ -0,0 +1,2027 @@
+/*
+ STB0899 Multistandard Frontend driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB0899_REG_H
+#define __STB0899_REG_H
+
+/* S1 */
+#define STB0899_DEV_ID 0xf000
+#define STB0899_CHIP_ID (0x0f << 4)
+#define STB0899_OFFST_CHIP_ID 4
+#define STB0899_WIDTH_CHIP_ID 4
+#define STB0899_CHIP_REL (0x0f << 0)
+#define STB0899_OFFST_CHIP_REL 0
+#define STB0899_WIDTH_CHIP_REL 4
+
+#define STB0899_DEMOD 0xf40e
+#define STB0899_MODECOEFF (0x01 << 0)
+#define STB0899_OFFST_MODECOEFF 0
+#define STB0899_WIDTH_MODECOEFF 1
+
+#define STB0899_RCOMPC 0xf410
+#define STB0899_AGC1CN 0xf412
+#define STB0899_AGC1REF 0xf413
+#define STB0899_RTC 0xf417
+#define STB0899_TMGCFG 0xf418
+#define STB0899_AGC2REF 0xf419
+#define STB0899_TLSR 0xf41a
+
+#define STB0899_CFD 0xf41b
+#define STB0899_CFD_ON (0x01 << 7)
+#define STB0899_OFFST_CFD_ON 7
+#define STB0899_WIDTH_CFD_ON 1
+
+#define STB0899_ACLC 0xf41c
+
+#define STB0899_BCLC 0xf41d
+#define STB0899_OFFST_ALGO 6
+#define STB0899_WIDTH_ALGO_QPSK2 2
+#define STB0899_ALGO_QPSK2 (2 << 6)
+#define STB0899_ALGO_QPSK1 (1 << 6)
+#define STB0899_ALGO_BPSK (0 << 6)
+#define STB0899_OFFST_BETA 0
+#define STB0899_WIDTH_BETA 6
+
+#define STB0899_EQON 0xf41e
+#define STB0899_LDT 0xf41f
+#define STB0899_LDT2 0xf420
+#define STB0899_EQUALREF 0xf425
+#define STB0899_TMGRAMP 0xf426
+#define STB0899_TMGTHD 0xf427
+#define STB0899_IDCCOMP 0xf428
+#define STB0899_QDCCOMP 0xf429
+#define STB0899_POWERI 0xf42a
+#define STB0899_POWERQ 0xf42b
+#define STB0899_RCOMP 0xf42c
+
+#define STB0899_AGCIQIN 0xf42e
+#define STB0899_AGCIQVALUE (0xff << 0)
+#define STB0899_OFFST_AGCIQVALUE 0
+#define STB0899_WIDTH_AGCIQVALUE 8
+
+#define STB0899_AGC2I1 0xf436
+#define STB0899_AGC2I2 0xf437
+
+#define STB0899_TLIR 0xf438
+#define STB0899_TLIR_TMG_LOCK_IND (0xff << 0)
+#define STB0899_OFFST_TLIR_TMG_LOCK_IND 0
+#define STB0899_WIDTH_TLIR_TMG_LOCK_IND 8
+
+#define STB0899_RTF 0xf439
+#define STB0899_RTF_TIMING_LOOP_FREQ (0xff << 0)
+#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ 0
+#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ 8
+
+#define STB0899_DSTATUS 0xf43a
+#define STB0899_CARRIER_FOUND (0x01 << 7)
+#define STB0899_OFFST_CARRIER_FOUND 7
+#define STB0899_WIDTH_CARRIER_FOUND 1
+#define STB0899_TMG_LOCK (0x01 << 6)
+#define STB0899_OFFST_TMG_LOCK 6
+#define STB0899_WIDTH_TMG_LOCK 1
+#define STB0899_DEMOD_LOCK (0x01 << 5)
+#define STB0899_OFFST_DEMOD_LOCK 5
+#define STB0899_WIDTH_DEMOD_LOCK 1
+#define STB0899_TMG_AUTO (0x01 << 4)
+#define STB0899_OFFST_TMG_AUTO 4
+#define STB0899_WIDTH_TMG_AUTO 1
+#define STB0899_END_MAIN (0x01 << 3)
+#define STB0899_OFFST_END_MAIN 3
+#define STB0899_WIDTH_END_MAIN 1
+
+#define STB0899_LDI 0xf43b
+#define STB0899_OFFST_LDI 0
+#define STB0899_WIDTH_LDI 8
+
+#define STB0899_CFRM 0xf43e
+#define STB0899_OFFST_CFRM 0
+#define STB0899_WIDTH_CFRM 8
+
+#define STB0899_CFRL 0xf43f
+#define STB0899_OFFST_CFRL 0
+#define STB0899_WIDTH_CFRL 8
+
+#define STB0899_NIRM 0xf440
+#define STB0899_OFFST_NIRM 0
+#define STB0899_WIDTH_NIRM 8
+
+#define STB0899_NIRL 0xf441
+#define STB0899_OFFST_NIRL 0
+#define STB0899_WIDTH_NIRL 8
+
+#define STB0899_ISYMB 0xf444
+#define STB0899_QSYMB 0xf445
+
+#define STB0899_SFRH 0xf446
+#define STB0899_OFFST_SFRH 0
+#define STB0899_WIDTH_SFRH 8
+
+#define STB0899_SFRM 0xf447
+#define STB0899_OFFST_SFRM 0
+#define STB0899_WIDTH_SFRM 8
+
+#define STB0899_SFRL 0xf448
+#define STB0899_OFFST_SFRL 4
+#define STB0899_WIDTH_SFRL 4
+
+#define STB0899_SFRUPH 0xf44c
+#define STB0899_SFRUPM 0xf44d
+#define STB0899_SFRUPL 0xf44e
+
+#define STB0899_EQUAI1 0xf4e0
+#define STB0899_EQUAQ1 0xf4e1
+#define STB0899_EQUAI2 0xf4e2
+#define STB0899_EQUAQ2 0xf4e3
+#define STB0899_EQUAI3 0xf4e4
+#define STB0899_EQUAQ3 0xf4e5
+#define STB0899_EQUAI4 0xf4e6
+#define STB0899_EQUAQ4 0xf4e7
+#define STB0899_EQUAI5 0xf4e8
+#define STB0899_EQUAQ5 0xf4e9
+
+#define STB0899_DSTATUS2 0xf50c
+#define STB0899_DS2_TMG_AUTOSRCH (0x01 << 7)
+#define STB8999_OFFST_DS2_TMG_AUTOSRCH 7
+#define STB0899_WIDTH_DS2_TMG_AUTOSRCH 1
+#define STB0899_DS2_END_MAINLOOP (0x01 << 6)
+#define STB0899_OFFST_DS2_END_MAINLOOP 6
+#define STB0899_WIDTH_DS2_END_MAINLOOP 1
+#define STB0899_DS2_CFSYNC (0x01 << 5)
+#define STB0899_OFFST_DS2_CFSYNC 5
+#define STB0899_WIDTH_DS2_CFSYNC 1
+#define STB0899_DS2_TMGLOCK (0x01 << 4)
+#define STB0899_OFFST_DS2_TMGLOCK 4
+#define STB0899_WIDTH_DS2_TMGLOCK 1
+#define STB0899_DS2_DEMODWAIT (0x01 << 3)
+#define STB0899_OFFST_DS2_DEMODWAIT 3
+#define STB0899_WIDTH_DS2_DEMODWAIT 1
+#define STB0899_DS2_FECON (0x01 << 1)
+#define STB0899_OFFST_DS2_FECON 1
+#define STB0899_WIDTH_DS2_FECON 1
+
+/* S1 FEC */
+#define STB0899_VSTATUS 0xf50d
+#define STB0899_VSTATUS_VITERBI_ON (0x01 << 7)
+#define STB0899_OFFST_VSTATUS_VITERBI_ON 7
+#define STB0899_WIDTH_VSTATUS_VITERBI_ON 1
+#define STB0899_VSTATUS_END_LOOPVIT (0x01 << 6)
+#define STB0899_OFFST_VSTATUS_END_LOOPVIT 6
+#define STB0899_WIDTH_VSTATUS_END_LOOPVIT 1
+#define STB0899_VSTATUS_PRFVIT (0x01 << 4)
+#define STB0899_OFFST_VSTATUS_PRFVIT 4
+#define STB0899_WIDTH_VSTATUS_PRFVIT 1
+#define STB0899_VSTATUS_LOCKEDVIT (0x01 << 3)
+#define STB0899_OFFST_VSTATUS_LOCKEDVIT 3
+#define STB0899_WIDTH_VSTATUS_LOCKEDVIT 1
+
+#define STB0899_VERROR 0xf50f
+
+#define STB0899_IQSWAP 0xf523
+#define STB0899_SYM (0x01 << 3)
+#define STB0899_OFFST_SYM 3
+#define STB0899_WIDTH_SYM 1
+
+#define STB0899_FECAUTO1 0xf530
+#define STB0899_DSSSRCH (0x01 << 3)
+#define STB0899_OFFST_DSSSRCH 3
+#define STB0899_WIDTH_DSSSRCH 1
+#define STB0899_SYMSRCH (0x01 << 2)
+#define STB0899_OFFST_SYMSRCH 2
+#define STB0899_WIDTH_SYMSRCH 1
+#define STB0899_QPSKSRCH (0x01 << 1)
+#define STB0899_OFFST_QPSKSRCH 1
+#define STB0899_WIDTH_QPSKSRCH 1
+#define STB0899_BPSKSRCH (0x01 << 0)
+#define STB0899_OFFST_BPSKSRCH 0
+#define STB0899_WIDTH_BPSKSRCH 1
+
+#define STB0899_FECM 0xf533
+#define STB0899_FECM_NOT_DVB (0x01 << 7)
+#define STB0899_OFFST_FECM_NOT_DVB 7
+#define STB0899_WIDTH_FECM_NOT_DVB 1
+#define STB0899_FECM_RSVD1 (0x07 << 4)
+#define STB0899_OFFST_FECM_RSVD1 4
+#define STB0899_WIDTH_FECM_RSVD1 3
+#define STB0899_FECM_VITERBI_ON (0x01 << 3)
+#define STB0899_OFFST_FECM_VITERBI_ON 3
+#define STB0899_WIDTH_FECM_VITERBI_ON 1
+#define STB0899_FECM_RSVD0 (0x01 << 2)
+#define STB0899_OFFST_FECM_RSVD0 2
+#define STB0899_WIDTH_FECM_RSVD0 1
+#define STB0899_FECM_SYNCDIS (0x01 << 1)
+#define STB0899_OFFST_FECM_SYNCDIS 1
+#define STB0899_WIDTH_FECM_SYNCDIS 1
+#define STB0899_FECM_SYMI (0x01 << 0)
+#define STB0899_OFFST_FECM_SYMI 0
+#define STB0899_WIDTH_FECM_SYMI 1
+
+#define STB0899_VTH12 0xf534
+#define STB0899_VTH23 0xf535
+#define STB0899_VTH34 0xf536
+#define STB0899_VTH56 0xf537
+#define STB0899_VTH67 0xf538
+#define STB0899_VTH78 0xf539
+
+#define STB0899_PRVIT 0xf53c
+#define STB0899_PR_7_8 (0x01 << 5)
+#define STB0899_OFFST_PR_7_8 5
+#define STB0899_WIDTH_PR_7_8 1
+#define STB0899_PR_6_7 (0x01 << 4)
+#define STB0899_OFFST_PR_6_7 4
+#define STB0899_WIDTH_PR_6_7 1
+#define STB0899_PR_5_6 (0x01 << 3)
+#define STB0899_OFFST_PR_5_6 3
+#define STB0899_WIDTH_PR_5_6 1
+#define STB0899_PR_3_4 (0x01 << 2)
+#define STB0899_OFFST_PR_3_4 2
+#define STB0899_WIDTH_PR_3_4 1
+#define STB0899_PR_2_3 (0x01 << 1)
+#define STB0899_OFFST_PR_2_3 1
+#define STB0899_WIDTH_PR_2_3 1
+#define STB0899_PR_1_2 (0x01 << 0)
+#define STB0899_OFFST_PR_1_2 0
+#define STB0899_WIDTH_PR_1_2 1
+
+#define STB0899_VITSYNC 0xf53d
+#define STB0899_AM (0x01 << 7)
+#define STB0899_OFFST_AM 7
+#define STB0899_WIDTH_AM 1
+#define STB0899_FREEZE (0x01 << 6)
+#define STB0899_OFFST_FREEZE 6
+#define STB0899_WIDTH_FREEZE 1
+#define STB0899_SN_65536 (0x03 << 4)
+#define STB0899_OFFST_SN_65536 4
+#define STB0899_WIDTH_SN_65536 2
+#define STB0899_SN_16384 (0x01 << 5)
+#define STB0899_OFFST_SN_16384 5
+#define STB0899_WIDTH_SN_16384 1
+#define STB0899_SN_4096 (0x01 << 4)
+#define STB0899_OFFST_SN_4096 4
+#define STB0899_WIDTH_SN_4096 1
+#define STB0899_SN_1024 (0x00 << 4)
+#define STB0899_OFFST_SN_1024 4
+#define STB0899_WIDTH_SN_1024 0
+#define STB0899_TO_128 (0x03 << 2)
+#define STB0899_OFFST_TO_128 2
+#define STB0899_WIDTH_TO_128 2
+#define STB0899_TO_64 (0x01 << 3)
+#define STB0899_OFFST_TO_64 3
+#define STB0899_WIDTH_TO_64 1
+#define STB0899_TO_32 (0x01 << 2)
+#define STB0899_OFFST_TO_32 2
+#define STB0899_WIDTH_TO_32 1
+#define STB0899_TO_16 (0x00 << 2)
+#define STB0899_OFFST_TO_16 2
+#define STB0899_WIDTH_TO_16 0
+#define STB0899_HYST_128 (0x03 << 1)
+#define STB0899_OFFST_HYST_128 1
+#define STB0899_WIDTH_HYST_128 2
+#define STB0899_HYST_64 (0x01 << 1)
+#define STB0899_OFFST_HYST_64 1
+#define STB0899_WIDTH_HYST_64 1
+#define STB0899_HYST_32 (0x01 << 0)
+#define STB0899_OFFST_HYST_32 0
+#define STB0899_WIDTH_HYST_32 1
+#define STB0899_HYST_16 (0x00 << 0)
+#define STB0899_OFFST_HYST_16 0
+#define STB0899_WIDTH_HYST_16 0
+
+#define STB0899_RSULC 0xf548
+#define STB0899_ULDIL_ON (0x01 << 7)
+#define STB0899_OFFST_ULDIL_ON 7
+#define STB0899_WIDTH_ULDIL_ON 1
+#define STB0899_ULAUTO_ON (0x01 << 6)
+#define STB0899_OFFST_ULAUTO_ON 6
+#define STB0899_WIDTH_ULAUTO_ON 1
+#define STB0899_ULRS_ON (0x01 << 5)
+#define STB0899_OFFST_ULRS_ON 5
+#define STB0899_WIDTH_ULRS_ON 1
+#define STB0899_ULDESCRAM_ON (0x01 << 4)
+#define STB0899_OFFST_ULDESCRAM_ON 4
+#define STB0899_WIDTH_ULDESCRAM_ON 1
+#define STB0899_UL_DISABLE (0x01 << 2)
+#define STB0899_OFFST_UL_DISABLE 2
+#define STB0899_WIDTH_UL_DISABLE 1
+#define STB0899_NOFTHRESHOLD (0x01 << 0)
+#define STB0899_OFFST_NOFTHRESHOLD 0
+#define STB0899_WIDTH_NOFTHRESHOLD 1
+
+#define STB0899_RSLLC 0xf54a
+#define STB0899_DEMAPVIT 0xf583
+#define STB0899_DEMAPVIT_RSVD (0x01 << 7)
+#define STB0899_OFFST_DEMAPVIT_RSVD 7
+#define STB0899_WIDTH_DEMAPVIT_RSVD 1
+#define STB0899_DEMAPVIT_KDIVIDER (0x7f << 0)
+#define STB0899_OFFST_DEMAPVIT_KDIVIDER 0
+#define STB0899_WIDTH_DEMAPVIT_KDIVIDER 7
+
+#define STB0899_PLPARM 0xf58c
+#define STB0899_VITMAPPING (0x07 << 5)
+#define STB0899_OFFST_VITMAPPING 5
+#define STB0899_WIDTH_VITMAPPING 3
+#define STB0899_VITMAPPING_BPSK (0x01 << 5)
+#define STB0899_OFFST_VITMAPPING_BPSK 5
+#define STB0899_WIDTH_VITMAPPING_BPSK 1
+#define STB0899_VITMAPPING_QPSK (0x00 << 5)
+#define STB0899_OFFST_VITMAPPING_QPSK 5
+#define STB0899_WIDTH_VITMAPPING_QPSK 0
+#define STB0899_VITCURPUN (0x1f << 0)
+#define STB0899_OFFST_VITCURPUN 0
+#define STB0899_WIDTH_VITCURPUN 5
+#define STB0899_VITCURPUN_1_2 (0x0d << 0)
+#define STB0899_VITCURPUN_2_3 (0x12 << 0)
+#define STB0899_VITCURPUN_3_4 (0x15 << 0)
+#define STB0899_VITCURPUN_5_6 (0x18 << 0)
+#define STB0899_VITCURPUN_6_7 (0x19 << 0)
+#define STB0899_VITCURPUN_7_8 (0x1a << 0)
+
+/* S2 DEMOD */
+#define STB0899_OFF0_DMD_STATUS 0xf300
+#define STB0899_BASE_DMD_STATUS 0x00000000
+#define STB0899_IF_AGC_LOCK (0x01 << 8)
+#define STB0899_OFFST_IF_AGC_LOCK 0
+#define STB0899_WIDTH_IF_AGC_LOCK 1
+
+#define STB0899_OFF0_CRL_FREQ 0xf304
+#define STB0899_BASE_CRL_FREQ 0x00000000
+#define STB0899_CARR_FREQ (0x3fffffff << 0)
+#define STB0899_OFFST_CARR_FREQ 0
+#define STB0899_WIDTH_CARR_FREQ 30
+
+#define STB0899_OFF0_BTR_FREQ 0xf308
+#define STB0899_BASE_BTR_FREQ 0x00000000
+#define STB0899_BTR_FREQ (0xfffffff << 0)
+#define STB0899_OFFST_BTR_FREQ 0
+#define STB0899_WIDTH_BTR_FREQ 28
+
+#define STB0899_OFF0_IF_AGC_GAIN 0xf30c
+#define STB0899_BASE_IF_AGC_GAIN 0x00000000
+#define STB0899_IF_AGC_GAIN (0x3fff < 0)
+#define STB0899_OFFST_IF_AGC_GAIN 0
+#define STB0899_WIDTH_IF_AGC_GAIN 14
+
+#define STB0899_OFF0_BB_AGC_GAIN 0xf310
+#define STB0899_BASE_BB_AGC_GAIN 0x00000000
+#define STB0899_BB_AGC_GAIN (0x3fff < 0)
+#define STB0899_OFFST_BB_AGC_GAIN 0
+#define STB0899_WIDTH_BB_AGC_GAIN 14
+
+#define STB0899_OFF0_DC_OFFSET 0xf314
+#define STB0899_BASE_DC_OFFSET 0x00000000
+#define STB0899_I (0xff < 8)
+#define STB0899_OFFST_I 8
+#define STB0899_WIDTH_I 8
+#define STB0899_Q (0xff < 0)
+#define STB0899_OFFST_Q 8
+#define STB0899_WIDTH_Q 8
+
+#define STB0899_OFF0_DMD_CNTRL 0xf31c
+#define STB0899_BASE_DMD_CNTRL 0x00000000
+#define STB0899_ADC0_PINS1IN (0x01 << 6)
+#define STB0899_OFFST_ADC0_PINS1IN 6
+#define STB0899_WIDTH_ADC0_PINS1IN 1
+#define STB0899_IN2COMP1_OFFBIN0 (0x01 << 3)
+#define STB0899_OFFST_IN2COMP1_OFFBIN0 3
+#define STB0899_WIDTH_IN2COMP1_OFFBIN0 1
+#define STB0899_DC_COMP (0x01 << 2)
+#define STB0899_OFFST_DC_COMP 2
+#define STB0899_WIDTH_DC_COMP 1
+#define STB0899_MODMODE (0x03 << 0)
+#define STB0899_OFFST_MODMODE 0
+#define STB0899_WIDTH_MODMODE 2
+
+#define STB0899_OFF0_IF_AGC_CNTRL 0xf320
+#define STB0899_BASE_IF_AGC_CNTRL 0x00000000
+#define STB0899_IF_GAIN_INIT (0x3fff << 13)
+#define STB0899_OFFST_IF_GAIN_INIT 13
+#define STB0899_WIDTH_IF_GAIN_INIT 14
+#define STB0899_IF_GAIN_SENSE (0x01 << 12)
+#define STB0899_OFFST_IF_GAIN_SENSE 12
+#define STB0899_WIDTH_IF_GAIN_SENSE 1
+#define STB0899_IF_LOOP_GAIN (0x0f << 8)
+#define STB0899_OFFST_IF_LOOP_GAIN 8
+#define STB0899_WIDTH_IF_LOOP_GAIN 4
+#define STB0899_IF_LD_GAIN_INIT (0x01 << 7)
+#define STB0899_OFFST_IF_LD_GAIN_INIT 7
+#define STB0899_WIDTH_IF_LD_GAIN_INIT 1
+#define STB0899_IF_AGC_REF (0x7f << 0)
+#define STB0899_OFFST_IF_AGC_REF 0
+#define STB0899_WIDTH_IF_AGC_REF 7
+
+#define STB0899_OFF0_BB_AGC_CNTRL 0xf324
+#define STB0899_BASE_BB_AGC_CNTRL 0x00000000
+#define STB0899_BB_GAIN_INIT (0x3fff << 12)
+#define STB0899_OFFST_BB_GAIN_INIT 12
+#define STB0899_WIDTH_BB_GAIN_INIT 14
+#define STB0899_BB_LOOP_GAIN (0x0f << 8)
+#define STB0899_OFFST_BB_LOOP_GAIN 8
+#define STB0899_WIDTH_BB_LOOP_GAIN 4
+#define STB0899_BB_LD_GAIN_INIT (0x01 << 7)
+#define STB0899_OFFST_BB_LD_GAIN_INIT 7
+#define STB0899_WIDTH_BB_LD_GAIN_INIT 1
+#define STB0899_BB_AGC_REF (0x7f << 0)
+#define STB0899_OFFST_BB_AGC_REF 0
+#define STB0899_WIDTH_BB_AGC_REF 7
+
+#define STB0899_OFF0_CRL_CNTRL 0xf328
+#define STB0899_BASE_CRL_CNTRL 0x00000000
+#define STB0899_CRL_LOCK_CLEAR (0x01 << 5)
+#define STB0899_OFFST_CRL_LOCK_CLEAR 5
+#define STB0899_WIDTH_CRL_LOCK_CLEAR 1
+#define STB0899_CRL_SWPR_CLEAR (0x01 << 4)
+#define STB0899_OFFST_CRL_SWPR_CLEAR 4
+#define STB0899_WIDTH_CRL_SWPR_CLEAR 1
+#define STB0899_CRL_SWP_ENA (0x01 << 3)
+#define STB0899_OFFST_CRL_SWP_ENA 3
+#define STB0899_WIDTH_CRL_SWP_ENA 1
+#define STB0899_CRL_DET_SEL (0x01 << 2)
+#define STB0899_OFFST_CRL_DET_SEL 2
+#define STB0899_WIDTH_CRL_DET_SEL 1
+#define STB0899_CRL_SENSE (0x01 << 1)
+#define STB0899_OFFST_CRL_SENSE 1
+#define STB0899_WIDTH_CRL_SENSE 1
+#define STB0899_CRL_PHSERR_CLEAR (0x01 << 0)
+#define STB0899_OFFST_CRL_PHSERR_CLEAR 0
+#define STB0899_WIDTH_CRL_PHSERR_CLEAR 1
+
+#define STB0899_OFF0_CRL_PHS_INIT 0xf32c
+#define STB0899_BASE_CRL_PHS_INIT 0x00000000
+#define STB0899_CRL_PHS_INIT_31 (0x1 << 30)
+#define STB0899_OFFST_CRL_PHS_INIT_31 30
+#define STB0899_WIDTH_CRL_PHS_INIT_31 1
+#define STB0899_CRL_LD_INIT_PHASE (0x1 << 24)
+#define STB0899_OFFST_CRL_LD_INIT_PHASE 24
+#define STB0899_WIDTH_CRL_LD_INIT_PHASE 1
+#define STB0899_CRL_INIT_PHASE (0xffffff << 0)
+#define STB0899_OFFST_CRL_INIT_PHASE 0
+#define STB0899_WIDTH_CRL_INIT_PHASE 24
+
+#define STB0899_OFF0_CRL_FREQ_INIT 0xf330
+#define STB0899_BASE_CRL_FREQ_INIT 0x00000000
+#define STB0899_CRL_FREQ_INIT_31 (0x1 << 30)
+#define STB0899_OFFST_CRL_FREQ_INIT_31 30
+#define STB0899_WIDTH_CRL_FREQ_INIT_31 1
+#define STB0899_CRL_LD_FREQ_INIT (0x1 << 24)
+#define STB0899_OFFST_CRL_LD_FREQ_INIT 24
+#define STB0899_WIDTH_CRL_LD_FREQ_INIT 1
+#define STB0899_CRL_FREQ_INIT (0xffffff << 0)
+#define STB0899_OFFST_CRL_FREQ_INIT 0
+#define STB0899_WIDTH_CRL_FREQ_INIT 24
+
+#define STB0899_OFF0_CRL_LOOP_GAIN 0xf334
+#define STB0899_BASE_CRL_LOOP_GAIN 0x00000000
+#define STB0899_KCRL2_RSHFT (0xf << 16)
+#define STB0899_OFFST_KCRL2_RSHFT 16
+#define STB0899_WIDTH_KCRL2_RSHFT 4
+#define STB0899_KCRL1 (0xf << 12)
+#define STB0899_OFFST_KCRL1 12
+#define STB0899_WIDTH_KCRL1 4
+#define STB0899_KCRL1_RSHFT (0xf << 8)
+#define STB0899_OFFST_KCRL1_RSHFT 8
+#define STB0899_WIDTH_KCRL1_RSHFT 4
+#define STB0899_KCRL0 (0xf << 4)
+#define STB0899_OFFST_KCRL0 4
+#define STB0899_WIDTH_KCRL0 4
+#define STB0899_KCRL0_RSHFT (0xf << 0)
+#define STB0899_OFFST_KCRL0_RSHFT 0
+#define STB0899_WIDTH_KCRL0_RSHFT 4
+
+#define STB0899_OFF0_CRL_NOM_FREQ 0xf338
+#define STB0899_BASE_CRL_NOM_FREQ 0x00000000
+#define STB0899_CRL_NOM_FREQ (0x3fffffff << 0)
+#define STB0899_OFFST_CRL_NOM_FREQ 0
+#define STB0899_WIDTH_CRL_NOM_FREQ 30
+
+#define STB0899_OFF0_CRL_SWP_RATE 0xf33c
+#define STB0899_BASE_CRL_SWP_RATE 0x00000000
+#define STB0899_CRL_SWP_RATE (0x3fffffff << 0)
+#define STB0899_OFFST_CRL_SWP_RATE 0
+#define STB0899_WIDTH_CRL_SWP_RATE 30
+
+#define STB0899_OFF0_CRL_MAX_SWP 0xf340
+#define STB0899_BASE_CRL_MAX_SWP 0x00000000
+#define STB0899_CRL_MAX_SWP (0x3fffffff << 0)
+#define STB0899_OFFST_CRL_MAX_SWP 0
+#define STB0899_WIDTH_CRL_MAX_SWP 30
+
+#define STB0899_OFF0_CRL_LK_CNTRL 0xf344
+#define STB0899_BASE_CRL_LK_CNTRL 0x00000000
+
+#define STB0899_OFF0_DECIM_CNTRL 0xf348
+#define STB0899_BASE_DECIM_CNTRL 0x00000000
+#define STB0899_BAND_LIMIT_B (0x01 << 5)
+#define STB0899_OFFST_BAND_LIMIT_B 5
+#define STB0899_WIDTH_BAND_LIMIT_B 1
+#define STB0899_WIN_SEL (0x03 << 3)
+#define STB0899_OFFST_WIN_SEL 3
+#define STB0899_WIDTH_WIN_SEL 2
+#define STB0899_DECIM_RATE (0x07 << 0)
+#define STB0899_OFFST_DECIM_RATE 0
+#define STB0899_WIDTH_DECIM_RATE 3
+
+#define STB0899_OFF0_BTR_CNTRL 0xf34c
+#define STB0899_BASE_BTR_CNTRL 0x00000000
+#define STB0899_BTR_FREQ_CORR (0x7ff << 4)
+#define STB0899_OFFST_BTR_FREQ_CORR 4
+#define STB0899_WIDTH_BTR_FREQ_CORR 11
+#define STB0899_BTR_CLR_LOCK (0x01 << 3)
+#define STB0899_OFFST_BTR_CLR_LOCK 3
+#define STB0899_WIDTH_BTR_CLR_LOCK 1
+#define STB0899_BTR_SENSE (0x01 << 2)
+#define STB0899_OFFST_BTR_SENSE 2
+#define STB0899_WIDTH_BTR_SENSE 1
+#define STB0899_BTR_ERR_ENA (0x01 << 1)
+#define STB0899_OFFST_BTR_ERR_ENA 1
+#define STB0899_WIDTH_BTR_ERR_ENA 1
+#define STB0899_INTRP_PHS_SENSE (0x01 << 0)
+#define STB0899_OFFST_INTRP_PHS_SENSE 0
+#define STB0899_WIDTH_INTRP_PHS_SENSE 1
+
+#define STB0899_OFF0_BTR_LOOP_GAIN 0xf350
+#define STB0899_BASE_BTR_LOOP_GAIN 0x00000000
+#define STB0899_KBTR2_RSHFT (0x0f << 16)
+#define STB0899_OFFST_KBTR2_RSHFT 16
+#define STB0899_WIDTH_KBTR2_RSHFT 4
+#define STB0899_KBTR1 (0x0f << 12)
+#define STB0899_OFFST_KBTR1 12
+#define STB0899_WIDTH_KBTR1 4
+#define STB0899_KBTR1_RSHFT (0x0f << 8)
+#define STB0899_OFFST_KBTR1_RSHFT 8
+#define STB0899_WIDTH_KBTR1_RSHFT 4
+#define STB0899_KBTR0 (0x0f << 4)
+#define STB0899_OFFST_KBTR0 4
+#define STB0899_WIDTH_KBTR0 4
+#define STB0899_KBTR0_RSHFT (0x0f << 0)
+#define STB0899_OFFST_KBTR0_RSHFT 0
+#define STB0899_WIDTH_KBTR0_RSHFT 4
+
+#define STB0899_OFF0_BTR_PHS_INIT 0xf354
+#define STB0899_BASE_BTR_PHS_INIT 0x00000000
+#define STB0899_BTR_LD_PHASE_INIT (0x01 << 28)
+#define STB0899_OFFST_BTR_LD_PHASE_INIT 28
+#define STB0899_WIDTH_BTR_LD_PHASE_INIT 1
+#define STB0899_BTR_INIT_PHASE (0xfffffff << 0)
+#define STB0899_OFFST_BTR_INIT_PHASE 0
+#define STB0899_WIDTH_BTR_INIT_PHASE 28
+
+#define STB0899_OFF0_BTR_FREQ_INIT 0xf358
+#define STB0899_BASE_BTR_FREQ_INIT 0x00000000
+#define STB0899_BTR_LD_FREQ_INIT (1 << 28)
+#define STB0899_OFFST_BTR_LD_FREQ_INIT 28
+#define STB0899_WIDTH_BTR_LD_FREQ_INIT 1
+#define STB0899_BTR_FREQ_INIT (0xfffffff << 0)
+#define STB0899_OFFST_BTR_FREQ_INIT 0
+#define STB0899_WIDTH_BTR_FREQ_INIT 28
+
+#define STB0899_OFF0_BTR_NOM_FREQ 0xf35c
+#define STB0899_BASE_BTR_NOM_FREQ 0x00000000
+#define STB0899_BTR_NOM_FREQ (0xfffffff << 0)
+#define STB0899_OFFST_BTR_NOM_FREQ 0
+#define STB0899_WIDTH_BTR_NOM_FREQ 28
+
+#define STB0899_OFF0_BTR_LK_CNTRL 0xf360
+#define STB0899_BASE_BTR_LK_CNTRL 0x00000000
+#define STB0899_BTR_MIN_ENERGY (0x0f << 24)
+#define STB0899_OFFST_BTR_MIN_ENERGY 24
+#define STB0899_WIDTH_BTR_MIN_ENERGY 4
+#define STB0899_BTR_LOCK_TH_LO (0xff << 16)
+#define STB0899_OFFST_BTR_LOCK_TH_LO 16
+#define STB0899_WIDTH_BTR_LOCK_TH_LO 8
+#define STB0899_BTR_LOCK_TH_HI (0xff << 8)
+#define STB0899_OFFST_BTR_LOCK_TH_HI 8
+#define STB0899_WIDTH_BTR_LOCK_TH_HI 8
+#define STB0899_BTR_LOCK_GAIN (0x03 << 6)
+#define STB0899_OFFST_BTR_LOCK_GAIN 6
+#define STB0899_WIDTH_BTR_LOCK_GAIN 2
+#define STB0899_BTR_LOCK_LEAK (0x3f << 0)
+#define STB0899_OFFST_BTR_LOCK_LEAK 0
+#define STB0899_WIDTH_BTR_LOCK_LEAK 6
+
+#define STB0899_OFF0_DECN_CNTRL 0xf364
+#define STB0899_BASE_DECN_CNTRL 0x00000000
+
+#define STB0899_OFF0_TP_CNTRL 0xf368
+#define STB0899_BASE_TP_CNTRL 0x00000000
+
+#define STB0899_OFF0_TP_BUF_STATUS 0xf36c
+#define STB0899_BASE_TP_BUF_STATUS 0x00000000
+#define STB0899_TP_BUFFER_FULL (1 << 0)
+
+#define STB0899_OFF0_DC_ESTIM 0xf37c
+#define STB0899_BASE_DC_ESTIM 0x0000
+#define STB0899_I_DC_ESTIMATE (0xff << 8)
+#define STB0899_OFFST_I_DC_ESTIMATE 8
+#define STB0899_WIDTH_I_DC_ESTIMATE 8
+#define STB0899_Q_DC_ESTIMATE (0xff << 0)
+#define STB0899_OFFST_Q_DC_ESTIMATE 0
+#define STB0899_WIDTH_Q_DC_ESTIMATE 8
+
+#define STB0899_OFF0_FLL_CNTRL 0xf310
+#define STB0899_BASE_FLL_CNTRL 0x00000020
+#define STB0899_CRL_FLL_ACC (0x01 << 4)
+#define STB0899_OFFST_CRL_FLL_ACC 4
+#define STB0899_WIDTH_CRL_FLL_ACC 1
+#define STB0899_FLL_AVG_PERIOD (0x0f << 0)
+#define STB0899_OFFST_FLL_AVG_PERIOD 0
+#define STB0899_WIDTH_FLL_AVG_PERIOD 4
+
+#define STB0899_OFF0_FLL_FREQ_WD 0xf314
+#define STB0899_BASE_FLL_FREQ_WD 0x00000020
+#define STB0899_FLL_FREQ_WD (0xffffffff << 0)
+#define STB0899_OFFST_FLL_FREQ_WD 0
+#define STB0899_WIDTH_FLL_FREQ_WD 32
+
+#define STB0899_OFF0_ANTI_ALIAS_SEL 0xf358
+#define STB0899_BASE_ANTI_ALIAS_SEL 0x00000020
+#define STB0899_ANTI_ALIAS_SELB (0x03 << 0)
+#define STB0899_OFFST_ANTI_ALIAS_SELB 0
+#define STB0899_WIDTH_ANTI_ALIAS_SELB 2
+
+#define STB0899_OFF0_RRC_ALPHA 0xf35c
+#define STB0899_BASE_RRC_ALPHA 0x00000020
+#define STB0899_RRC_ALPHA (0x03 << 0)
+#define STB0899_OFFST_RRC_ALPHA 0
+#define STB0899_WIDTH_RRC_ALPHA 2
+
+#define STB0899_OFF0_DC_ADAPT_LSHFT 0xf360
+#define STB0899_BASE_DC_ADAPT_LSHFT 0x00000020
+#define STB0899_DC_ADAPT_LSHFT (0x077 << 0)
+#define STB0899_OFFST_DC_ADAPT_LSHFT 0
+#define STB0899_WIDTH_DC_ADAPT_LSHFT 3
+
+#define STB0899_OFF0_IMB_OFFSET 0xf364
+#define STB0899_BASE_IMB_OFFSET 0x00000020
+#define STB0899_PHS_IMB_COMP (0xff << 8)
+#define STB0899_OFFST_PHS_IMB_COMP 8
+#define STB0899_WIDTH_PHS_IMB_COMP 8
+#define STB0899_AMPL_IMB_COMP (0xff << 0)
+#define STB0899_OFFST_AMPL_IMB_COMP 0
+#define STB0899_WIDTH_AMPL_IMB_COMP 8
+
+#define STB0899_OFF0_IMB_ESTIMATE 0xf368
+#define STB0899_BASE_IMB_ESTIMATE 0x00000020
+#define STB0899_PHS_IMB_ESTIMATE (0xff << 8)
+#define STB0899_OFFST_PHS_IMB_ESTIMATE 8
+#define STB0899_WIDTH_PHS_IMB_ESTIMATE 8
+#define STB0899_AMPL_IMB_ESTIMATE (0xff << 0)
+#define STB0899_OFFST_AMPL_IMB_ESTIMATE 0
+#define STB0899_WIDTH_AMPL_IMB_ESTIMATE 8
+
+#define STB0899_OFF0_IMB_CNTRL 0xf36c
+#define STB0899_BASE_IMB_CNTRL 0x00000020
+#define STB0899_PHS_ADAPT_LSHFT (0x07 << 4)
+#define STB0899_OFFST_PHS_ADAPT_LSHFT 4
+#define STB0899_WIDTH_PHS_ADAPT_LSHFT 3
+#define STB0899_AMPL_ADAPT_LSHFT (0x07 << 1)
+#define STB0899_OFFST_AMPL_ADAPT_LSHFT 1
+#define STB0899_WIDTH_AMPL_ADAPT_LSHFT 3
+#define STB0899_IMB_COMP (0x01 << 0)
+#define STB0899_OFFST_IMB_COMP 0
+#define STB0899_WIDTH_IMB_COMP 1
+
+#define STB0899_OFF0_IF_AGC_CNTRL2 0xf374
+#define STB0899_BASE_IF_AGC_CNTRL2 0x00000020
+#define STB0899_IF_AGC_LOCK_TH (0xff << 11)
+#define STB0899_OFFST_IF_AGC_LOCK_TH 11
+#define STB0899_WIDTH_IF_AGC_LOCK_TH 8
+#define STB0899_IF_AGC_SD_DIV (0xff << 3)
+#define STB0899_OFFST_IF_AGC_SD_DIV 3
+#define STB0899_WIDTH_IF_AGC_SD_DIV 8
+#define STB0899_IF_AGC_DUMP_PER (0x07 << 0)
+#define STB0899_OFFST_IF_AGC_DUMP_PER 0
+#define STB0899_WIDTH_IF_AGC_DUMP_PER 3
+
+#define STB0899_OFF0_DMD_CNTRL2 0xf378
+#define STB0899_BASE_DMD_CNTRL2 0x00000020
+#define STB0899_SPECTRUM_INVERT (0x01 << 2)
+#define STB0899_OFFST_SPECTRUM_INVERT 2
+#define STB0899_WIDTH_SPECTRUM_INVERT 1
+#define STB0899_AGC_MODE (0x01 << 1)
+#define STB0899_OFFST_AGC_MODE 1
+#define STB0899_WIDTH_AGC_MODE 1
+#define STB0899_CRL_FREQ_ADJ (0x01 << 0)
+#define STB0899_OFFST_CRL_FREQ_ADJ 0
+#define STB0899_WIDTH_CRL_FREQ_ADJ 1
+
+#define STB0899_OFF0_TP_BUFFER 0xf300
+#define STB0899_BASE_TP_BUFFER 0x00000040
+#define STB0899_TP_BUFFER_IN (0xffff << 0)
+#define STB0899_OFFST_TP_BUFFER_IN 0
+#define STB0899_WIDTH_TP_BUFFER_IN 16
+
+#define STB0899_OFF0_TP_BUFFER1 0xf304
+#define STB0899_BASE_TP_BUFFER1 0x00000040
+#define STB0899_OFF0_TP_BUFFER2 0xf308
+#define STB0899_BASE_TP_BUFFER2 0x00000040
+#define STB0899_OFF0_TP_BUFFER3 0xf30c
+#define STB0899_BASE_TP_BUFFER3 0x00000040
+#define STB0899_OFF0_TP_BUFFER4 0xf310
+#define STB0899_BASE_TP_BUFFER4 0x00000040
+#define STB0899_OFF0_TP_BUFFER5 0xf314
+#define STB0899_BASE_TP_BUFFER5 0x00000040
+#define STB0899_OFF0_TP_BUFFER6 0xf318
+#define STB0899_BASE_TP_BUFFER6 0x00000040
+#define STB0899_OFF0_TP_BUFFER7 0xf31c
+#define STB0899_BASE_TP_BUFFER7 0x00000040
+#define STB0899_OFF0_TP_BUFFER8 0xf320
+#define STB0899_BASE_TP_BUFFER8 0x00000040
+#define STB0899_OFF0_TP_BUFFER9 0xf324
+#define STB0899_BASE_TP_BUFFER9 0x00000040
+#define STB0899_OFF0_TP_BUFFER10 0xf328
+#define STB0899_BASE_TP_BUFFER10 0x00000040
+#define STB0899_OFF0_TP_BUFFER11 0xf32c
+#define STB0899_BASE_TP_BUFFER11 0x00000040
+#define STB0899_OFF0_TP_BUFFER12 0xf330
+#define STB0899_BASE_TP_BUFFER12 0x00000040
+#define STB0899_OFF0_TP_BUFFER13 0xf334
+#define STB0899_BASE_TP_BUFFER13 0x00000040
+#define STB0899_OFF0_TP_BUFFER14 0xf338
+#define STB0899_BASE_TP_BUFFER14 0x00000040
+#define STB0899_OFF0_TP_BUFFER15 0xf33c
+#define STB0899_BASE_TP_BUFFER15 0x00000040
+#define STB0899_OFF0_TP_BUFFER16 0xf340
+#define STB0899_BASE_TP_BUFFER16 0x00000040
+#define STB0899_OFF0_TP_BUFFER17 0xf344
+#define STB0899_BASE_TP_BUFFER17 0x00000040
+#define STB0899_OFF0_TP_BUFFER18 0xf348
+#define STB0899_BASE_TP_BUFFER18 0x00000040
+#define STB0899_OFF0_TP_BUFFER19 0xf34c
+#define STB0899_BASE_TP_BUFFER19 0x00000040
+#define STB0899_OFF0_TP_BUFFER20 0xf350
+#define STB0899_BASE_TP_BUFFER20 0x00000040
+#define STB0899_OFF0_TP_BUFFER21 0xf354
+#define STB0899_BASE_TP_BUFFER21 0x00000040
+#define STB0899_OFF0_TP_BUFFER22 0xf358
+#define STB0899_BASE_TP_BUFFER22 0x00000040
+#define STB0899_OFF0_TP_BUFFER23 0xf35c
+#define STB0899_BASE_TP_BUFFER23 0x00000040
+#define STB0899_OFF0_TP_BUFFER24 0xf360
+#define STB0899_BASE_TP_BUFFER24 0x00000040
+#define STB0899_OFF0_TP_BUFFER25 0xf364
+#define STB0899_BASE_TP_BUFFER25 0x00000040
+#define STB0899_OFF0_TP_BUFFER26 0xf368
+#define STB0899_BASE_TP_BUFFER26 0x00000040
+#define STB0899_OFF0_TP_BUFFER27 0xf36c
+#define STB0899_BASE_TP_BUFFER27 0x00000040
+#define STB0899_OFF0_TP_BUFFER28 0xf370
+#define STB0899_BASE_TP_BUFFER28 0x00000040
+#define STB0899_OFF0_TP_BUFFER29 0xf374
+#define STB0899_BASE_TP_BUFFER29 0x00000040
+#define STB0899_OFF0_TP_BUFFER30 0xf378
+#define STB0899_BASE_TP_BUFFER30 0x00000040
+#define STB0899_OFF0_TP_BUFFER31 0xf37c
+#define STB0899_BASE_TP_BUFFER31 0x00000040
+#define STB0899_OFF0_TP_BUFFER32 0xf300
+#define STB0899_BASE_TP_BUFFER32 0x00000060
+#define STB0899_OFF0_TP_BUFFER33 0xf304
+#define STB0899_BASE_TP_BUFFER33 0x00000060
+#define STB0899_OFF0_TP_BUFFER34 0xf308
+#define STB0899_BASE_TP_BUFFER34 0x00000060
+#define STB0899_OFF0_TP_BUFFER35 0xf30c
+#define STB0899_BASE_TP_BUFFER35 0x00000060
+#define STB0899_OFF0_TP_BUFFER36 0xf310
+#define STB0899_BASE_TP_BUFFER36 0x00000060
+#define STB0899_OFF0_TP_BUFFER37 0xf314
+#define STB0899_BASE_TP_BUFFER37 0x00000060
+#define STB0899_OFF0_TP_BUFFER38 0xf318
+#define STB0899_BASE_TP_BUFFER38 0x00000060
+#define STB0899_OFF0_TP_BUFFER39 0xf31c
+#define STB0899_BASE_TP_BUFFER39 0x00000060
+#define STB0899_OFF0_TP_BUFFER40 0xf320
+#define STB0899_BASE_TP_BUFFER40 0x00000060
+#define STB0899_OFF0_TP_BUFFER41 0xf324
+#define STB0899_BASE_TP_BUFFER41 0x00000060
+#define STB0899_OFF0_TP_BUFFER42 0xf328
+#define STB0899_BASE_TP_BUFFER42 0x00000060
+#define STB0899_OFF0_TP_BUFFER43 0xf32c
+#define STB0899_BASE_TP_BUFFER43 0x00000060
+#define STB0899_OFF0_TP_BUFFER44 0xf330
+#define STB0899_BASE_TP_BUFFER44 0x00000060
+#define STB0899_OFF0_TP_BUFFER45 0xf334
+#define STB0899_BASE_TP_BUFFER45 0x00000060
+#define STB0899_OFF0_TP_BUFFER46 0xf338
+#define STB0899_BASE_TP_BUFFER46 0x00000060
+#define STB0899_OFF0_TP_BUFFER47 0xf33c
+#define STB0899_BASE_TP_BUFFER47 0x00000060
+#define STB0899_OFF0_TP_BUFFER48 0xf340
+#define STB0899_BASE_TP_BUFFER48 0x00000060
+#define STB0899_OFF0_TP_BUFFER49 0xf344
+#define STB0899_BASE_TP_BUFFER49 0x00000060
+#define STB0899_OFF0_TP_BUFFER50 0xf348
+#define STB0899_BASE_TP_BUFFER50 0x00000060
+#define STB0899_OFF0_TP_BUFFER51 0xf34c
+#define STB0899_BASE_TP_BUFFER51 0x00000060
+#define STB0899_OFF0_TP_BUFFER52 0xf350
+#define STB0899_BASE_TP_BUFFER52 0x00000060
+#define STB0899_OFF0_TP_BUFFER53 0xf354
+#define STB0899_BASE_TP_BUFFER53 0x00000060
+#define STB0899_OFF0_TP_BUFFER54 0xf358
+#define STB0899_BASE_TP_BUFFER54 0x00000060
+#define STB0899_OFF0_TP_BUFFER55 0xf35c
+#define STB0899_BASE_TP_BUFFER55 0x00000060
+#define STB0899_OFF0_TP_BUFFER56 0xf360
+#define STB0899_BASE_TP_BUFFER56 0x00000060
+#define STB0899_OFF0_TP_BUFFER57 0xf364
+#define STB0899_BASE_TP_BUFFER57 0x00000060
+#define STB0899_OFF0_TP_BUFFER58 0xf368
+#define STB0899_BASE_TP_BUFFER58 0x00000060
+#define STB0899_OFF0_TP_BUFFER59 0xf36c
+#define STB0899_BASE_TP_BUFFER59 0x00000060
+#define STB0899_OFF0_TP_BUFFER60 0xf370
+#define STB0899_BASE_TP_BUFFER60 0x00000060
+#define STB0899_OFF0_TP_BUFFER61 0xf374
+#define STB0899_BASE_TP_BUFFER61 0x00000060
+#define STB0899_OFF0_TP_BUFFER62 0xf378
+#define STB0899_BASE_TP_BUFFER62 0x00000060
+#define STB0899_OFF0_TP_BUFFER63 0xf37c
+#define STB0899_BASE_TP_BUFFER63 0x00000060
+
+#define STB0899_OFF0_RESET_CNTRL 0xf300
+#define STB0899_BASE_RESET_CNTRL 0x00000400
+#define STB0899_DVBS2_RESET (0x01 << 0)
+#define STB0899_OFFST_DVBS2_RESET 0
+#define STB0899_WIDTH_DVBS2_RESET 1
+
+#define STB0899_OFF0_ACM_ENABLE 0xf304
+#define STB0899_BASE_ACM_ENABLE 0x00000400
+#define STB0899_ACM_ENABLE 1
+
+#define STB0899_OFF0_DESCR_CNTRL 0xf30c
+#define STB0899_BASE_DESCR_CNTRL 0x00000400
+#define STB0899_OFFST_DESCR_CNTRL 0
+#define STB0899_WIDTH_DESCR_CNTRL 16
+
+#define STB0899_OFF0_UWP_CNTRL1 0xf320
+#define STB0899_BASE_UWP_CNTRL1 0x00000400
+#define STB0899_UWP_TH_SOF (0x7fff << 11)
+#define STB0899_OFFST_UWP_TH_SOF 11
+#define STB0899_WIDTH_UWP_TH_SOF 15
+#define STB0899_UWP_ESN0_QUANT (0xff << 3)
+#define STB0899_OFFST_UWP_ESN0_QUANT 3
+#define STB0899_WIDTH_UWP_ESN0_QUANT 8
+#define STB0899_UWP_ESN0_AVE (0x03 << 1)
+#define STB0899_OFFST_UWP_ESN0_AVE 1
+#define STB0899_WIDTH_UWP_ESN0_AVE 2
+#define STB0899_UWP_START (0x01 << 0)
+#define STB0899_OFFST_UWP_START 0
+#define STB0899_WIDTH_UWP_START 1
+
+#define STB0899_OFF0_UWP_CNTRL2 0xf324
+#define STB0899_BASE_UWP_CNTRL2 0x00000400
+#define STB0899_UWP_MISS_TH (0xff << 16)
+#define STB0899_OFFST_UWP_MISS_TH 16
+#define STB0899_WIDTH_UWP_MISS_TH 8
+#define STB0899_FE_FINE_TRK (0xff << 8)
+#define STB0899_OFFST_FE_FINE_TRK 8
+#define STB0899_WIDTH_FE_FINE_TRK 8
+#define STB0899_FE_COARSE_TRK (0xff << 0)
+#define STB0899_OFFST_FE_COARSE_TRK 0
+#define STB0899_WIDTH_FE_COARSE_TRK 8
+
+#define STB0899_OFF0_UWP_STAT1 0xf328
+#define STB0899_BASE_UWP_STAT1 0x00000400
+#define STB0899_UWP_STATE (0x03ff << 15)
+#define STB0899_OFFST_UWP_STATE 15
+#define STB0899_WIDTH_UWP_STATE 10
+#define STB0899_UW_MAX_PEAK (0x7fff << 0)
+#define STB0899_OFFST_UW_MAX_PEAK 0
+#define STB0899_WIDTH_UW_MAX_PEAK 15
+
+#define STB0899_OFF0_UWP_STAT2 0xf32c
+#define STB0899_BASE_UWP_STAT2 0x00000400
+#define STB0899_ESNO_EST (0x07ffff << 7)
+#define STB0899_OFFST_ESN0_EST 7
+#define STB0899_WIDTH_ESN0_EST 19
+#define STB0899_UWP_DECODE_MOD (0x7f << 0)
+#define STB0899_OFFST_UWP_DECODE_MOD 0
+#define STB0899_WIDTH_UWP_DECODE_MOD 7
+
+#define STB0899_OFF0_DMD_CORE_ID 0xf334
+#define STB0899_BASE_DMD_CORE_ID 0x00000400
+#define STB0899_CORE_ID (0xffffffff << 0)
+#define STB0899_OFFST_CORE_ID 0
+#define STB0899_WIDTH_CORE_ID 32
+
+#define STB0899_OFF0_DMD_VERSION_ID 0xf33c
+#define STB0899_BASE_DMD_VERSION_ID 0x00000400
+#define STB0899_VERSION_ID (0xff << 0)
+#define STB0899_OFFST_VERSION_ID 0
+#define STB0899_WIDTH_VERSION_ID 8
+
+#define STB0899_OFF0_DMD_STAT2 0xf340
+#define STB0899_BASE_DMD_STAT2 0x00000400
+#define STB0899_CSM_LOCK (0x01 << 1)
+#define STB0899_OFFST_CSM_LOCK 1
+#define STB0899_WIDTH_CSM_LOCK 1
+#define STB0899_UWP_LOCK (0x01 << 0)
+#define STB0899_OFFST_UWP_LOCK 0
+#define STB0899_WIDTH_UWP_LOCK 1
+
+#define STB0899_OFF0_FREQ_ADJ_SCALE 0xf344
+#define STB0899_BASE_FREQ_ADJ_SCALE 0x00000400
+#define STB0899_FREQ_ADJ_SCALE (0x0fff << 0)
+#define STB0899_OFFST_FREQ_ADJ_SCALE 0
+#define STB0899_WIDTH_FREQ_ADJ_SCALE 12
+
+#define STB0899_OFF0_UWP_CNTRL3 0xf34c
+#define STB0899_BASE_UWP_CNTRL3 0x00000400
+#define STB0899_UWP_TH_TRACK (0x7fff << 15)
+#define STB0899_OFFST_UWP_TH_TRACK 15
+#define STB0899_WIDTH_UWP_TH_TRACK 15
+#define STB0899_UWP_TH_ACQ (0x7fff << 0)
+#define STB0899_OFFST_UWP_TH_ACQ 0
+#define STB0899_WIDTH_UWP_TH_ACQ 15
+
+#define STB0899_OFF0_SYM_CLK_SEL 0xf350
+#define STB0899_BASE_SYM_CLK_SEL 0x00000400
+#define STB0899_SYM_CLK_SEL (0x03 << 0)
+#define STB0899_OFFST_SYM_CLK_SEL 0
+#define STB0899_WIDTH_SYM_CLK_SEL 2
+
+#define STB0899_OFF0_SOF_SRCH_TO 0xf354
+#define STB0899_BASE_SOF_SRCH_TO 0x00000400
+#define STB0899_SOF_SEARCH_TIMEOUT (0x3fffff << 0)
+#define STB0899_OFFST_SOF_SEARCH_TIMEOUT 0
+#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT 22
+
+#define STB0899_OFF0_ACQ_CNTRL1 0xf358
+#define STB0899_BASE_ACQ_CNTRL1 0x00000400
+#define STB0899_FE_FINE_ACQ (0xff << 8)
+#define STB0899_OFFST_FE_FINE_ACQ 8
+#define STB0899_WIDTH_FE_FINE_ACQ 8
+#define STB0899_FE_COARSE_ACQ (0xff << 0)
+#define STB0899_OFFST_FE_COARSE_ACQ 0
+#define STB0899_WIDTH_FE_COARSE_ACQ 8
+
+#define STB0899_OFF0_ACQ_CNTRL2 0xf35c
+#define STB0899_BASE_ACQ_CNTRL2 0x00000400
+#define STB0899_ZIGZAG (0x01 << 25)
+#define STB0899_OFFST_ZIGZAG 25
+#define STB0899_WIDTH_ZIGZAG 1
+#define STB0899_NUM_STEPS (0xff << 17)
+#define STB0899_OFFST_NUM_STEPS 17
+#define STB0899_WIDTH_NUM_STEPS 8
+#define STB0899_FREQ_STEPSIZE (0x1ffff << 0)
+#define STB0899_OFFST_FREQ_STEPSIZE 0
+#define STB0899_WIDTH_FREQ_STEPSIZE 17
+
+#define STB0899_OFF0_ACQ_CNTRL3 0xf360
+#define STB0899_BASE_ACQ_CNTRL3 0x00000400
+#define STB0899_THRESHOLD_SCL (0x3f << 23)
+#define STB0899_OFFST_THRESHOLD_SCL 23
+#define STB0899_WIDTH_THRESHOLD_SCL 6
+#define STB0899_UWP_TH_SRCH (0x7fff << 8)
+#define STB0899_OFFST_UWP_TH_SRCH 8
+#define STB0899_WIDTH_UWP_TH_SRCH 15
+#define STB0899_AUTO_REACQUIRE (0x01 << 7)
+#define STB0899_OFFST_AUTO_REACQUIRE 7
+#define STB0899_WIDTH_AUTO_REACQUIRE 1
+#define STB0899_TRACK_LOCK_SEL (0x01 << 6)
+#define STB0899_OFFST_TRACK_LOCK_SEL 6
+#define STB0899_WIDTH_TRACK_LOCK_SEL 1
+#define STB0899_ACQ_SEARCH_MODE (0x03 << 4)
+#define STB0899_OFFST_ACQ_SEARCH_MODE 4
+#define STB0899_WIDTH_ACQ_SEARCH_MODE 2
+#define STB0899_CONFIRM_FRAMES (0x0f << 0)
+#define STB0899_OFFST_CONFIRM_FRAMES 0
+#define STB0899_WIDTH_CONFIRM_FRAMES 4
+
+#define STB0899_OFF0_FE_SETTLE 0xf364
+#define STB0899_BASE_FE_SETTLE 0x00000400
+#define STB0899_SETTLING_TIME (0x3fffff << 0)
+#define STB0899_OFFST_SETTLING_TIME 0
+#define STB0899_WIDTH_SETTLING_TIME 22
+
+#define STB0899_OFF0_AC_DWELL 0xf368
+#define STB0899_BASE_AC_DWELL 0x00000400
+#define STB0899_DWELL_TIME (0x3fffff << 0)
+#define STB0899_OFFST_DWELL_TIME 0
+#define STB0899_WIDTH_DWELL_TIME 22
+
+#define STB0899_OFF0_ACQUIRE_TRIG 0xf36c
+#define STB0899_BASE_ACQUIRE_TRIG 0x00000400
+#define STB0899_ACQUIRE (0x01 << 0)
+#define STB0899_OFFST_ACQUIRE 0
+#define STB0899_WIDTH_ACQUIRE 1
+
+#define STB0899_OFF0_LOCK_LOST 0xf370
+#define STB0899_BASE_LOCK_LOST 0x00000400
+#define STB0899_LOCK_LOST (0x01 << 0)
+#define STB0899_OFFST_LOCK_LOST 0
+#define STB0899_WIDTH_LOCK_LOST 1
+
+#define STB0899_OFF0_ACQ_STAT1 0xf374
+#define STB0899_BASE_ACQ_STAT1 0x00000400
+#define STB0899_STEP_FREQ (0x1fffff << 11)
+#define STB0899_OFFST_STEP_FREQ 11
+#define STB0899_WIDTH_STEP_FREQ 21
+#define STB0899_ACQ_STATE (0x07 << 8)
+#define STB0899_OFFST_ACQ_STATE 8
+#define STB0899_WIDTH_ACQ_STATE 3
+#define STB0899_UW_DETECT_COUNT (0xff << 0)
+#define STB0899_OFFST_UW_DETECT_COUNT 0
+#define STB0899_WIDTH_UW_DETECT_COUNT 8
+
+#define STB0899_OFF0_ACQ_TIMEOUT 0xf378
+#define STB0899_BASE_ACQ_TIMEOUT 0x00000400
+#define STB0899_ACQ_TIMEOUT (0x3fffff << 0)
+#define STB0899_OFFST_ACQ_TIMEOUT 0
+#define STB0899_WIDTH_ACQ_TIMEOUT 22
+
+#define STB0899_OFF0_ACQ_TIME 0xf37c
+#define STB0899_BASE_ACQ_TIME 0x00000400
+#define STB0899_ACQ_TIME_SYM (0xffffff << 0)
+#define STB0899_OFFST_ACQ_TIME_SYM 0
+#define STB0899_WIDTH_ACQ_TIME_SYM 24
+
+#define STB0899_OFF0_FINAL_AGC_CNTRL 0xf308
+#define STB0899_BASE_FINAL_AGC_CNTRL 0x00000440
+#define STB0899_FINAL_GAIN_INIT (0x3fff << 12)
+#define STB0899_OFFST_FINAL_GAIN_INIT 12
+#define STB0899_WIDTH_FINAL_GAIN_INIT 14
+#define STB0899_FINAL_LOOP_GAIN (0x0f << 8)
+#define STB0899_OFFST_FINAL_LOOP_GAIN 8
+#define STB0899_WIDTH_FINAL_LOOP_GAIN 4
+#define STB0899_FINAL_LD_GAIN_INIT (0x01 << 7)
+#define STB0899_OFFST_FINAL_LD_GAIN_INIT 7
+#define STB0899_WIDTH_FINAL_LD_GAIN_INIT 1
+#define STB0899_FINAL_AGC_REF (0x7f << 0)
+#define STB0899_OFFST_FINAL_AGC_REF 0
+#define STB0899_WIDTH_FINAL_AGC_REF 7
+
+#define STB0899_OFF0_FINAL_AGC_GAIN 0xf30c
+#define STB0899_BASE_FINAL_AGC_GAIN 0x00000440
+#define STB0899_FINAL_AGC_GAIN (0x3fff << 0)
+#define STB0899_OFFST_FINAL_AGC_GAIN 0
+#define STB0899_WIDTH_FINAL_AGC_GAIN 14
+
+#define STB0899_OFF0_EQUALIZER_INIT 0xf310
+#define STB0899_BASE_EQUALIZER_INIT 0x00000440
+#define STB0899_EQ_SRST (0x01 << 1)
+#define STB0899_OFFST_EQ_SRST 1
+#define STB0899_WIDTH_EQ_SRST 1
+#define STB0899_EQ_INIT (0x01 << 0)
+#define STB0899_OFFST_EQ_INIT 0
+#define STB0899_WIDTH_EQ_INIT 1
+
+#define STB0899_OFF0_EQ_CNTRL 0xf314
+#define STB0899_BASE_EQ_CNTRL 0x00000440
+#define STB0899_EQ_ADAPT_MODE (0x01 << 18)
+#define STB0899_OFFST_EQ_ADAPT_MODE 18
+#define STB0899_WIDTH_EQ_ADAPT_MODE 1
+#define STB0899_EQ_DELAY (0x0f << 14)
+#define STB0899_OFFST_EQ_DELAY 14
+#define STB0899_WIDTH_EQ_DELAY 4
+#define STB0899_EQ_QUANT_LEVEL (0xff << 6)
+#define STB0899_OFFST_EQ_QUANT_LEVEL 6
+#define STB0899_WIDTH_EQ_QUANT_LEVEL 8
+#define STB0899_EQ_DISABLE_UPDATE (0x01 << 5)
+#define STB0899_OFFST_EQ_DISABLE_UPDATE 5
+#define STB0899_WIDTH_EQ_DISABLE_UPDATE 1
+#define STB0899_EQ_BYPASS (0x01 << 4)
+#define STB0899_OFFST_EQ_BYPASS 4
+#define STB0899_WIDTH_EQ_BYPASS 1
+#define STB0899_EQ_SHIFT (0x0f << 0)
+#define STB0899_OFFST_EQ_SHIFT 0
+#define STB0899_WIDTH_EQ_SHIFT 4
+
+#define STB0899_OFF0_EQ_I_INIT_COEFF_0 0xf320
+#define STB0899_OFF1_EQ_I_INIT_COEFF_1 0xf324
+#define STB0899_OFF2_EQ_I_INIT_COEFF_2 0xf328
+#define STB0899_OFF3_EQ_I_INIT_COEFF_3 0xf32c
+#define STB0899_OFF4_EQ_I_INIT_COEFF_4 0xf330
+#define STB0899_OFF5_EQ_I_INIT_COEFF_5 0xf334
+#define STB0899_OFF6_EQ_I_INIT_COEFF_6 0xf338
+#define STB0899_OFF7_EQ_I_INIT_COEFF_7 0xf33c
+#define STB0899_OFF8_EQ_I_INIT_COEFF_8 0xf340
+#define STB0899_OFF9_EQ_I_INIT_COEFF_9 0xf344
+#define STB0899_OFFa_EQ_I_INIT_COEFF_10 0xf348
+#define STB0899_BASE_EQ_I_INIT_COEFF_N 0x00000440
+#define STB0899_EQ_I_INIT_COEFF_N (0x0fff << 0)
+#define STB0899_OFFST_EQ_I_INIT_COEFF_N 0
+#define STB0899_WIDTH_EQ_I_INIT_COEFF_N 12
+
+#define STB0899_OFF0_EQ_Q_INIT_COEFF_0 0xf350
+#define STB0899_OFF1_EQ_Q_INIT_COEFF_1 0xf354
+#define STB0899_OFF2_EQ_Q_INIT_COEFF_2 0xf358
+#define STB0899_OFF3_EQ_Q_INIT_COEFF_3 0xf35c
+#define STB0899_OFF4_EQ_Q_INIT_COEFF_4 0xf360
+#define STB0899_OFF5_EQ_Q_INIT_COEFF_5 0xf364
+#define STB0899_OFF6_EQ_Q_INIT_COEFF_6 0xf368
+#define STB0899_OFF7_EQ_Q_INIT_COEFF_7 0xf36c
+#define STB0899_OFF8_EQ_Q_INIT_COEFF_8 0xf370
+#define STB0899_OFF9_EQ_Q_INIT_COEFF_9 0xf374
+#define STB0899_OFFa_EQ_Q_INIT_COEFF_10 0xf378
+#define STB0899_BASE_EQ_Q_INIT_COEFF_N 0x00000440
+#define STB0899_EQ_Q_INIT_COEFF_N (0x0fff << 0)
+#define STB0899_OFFST_EQ_Q_INIT_COEFF_N 0
+#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N 12
+
+#define STB0899_OFF0_EQ_I_OUT_COEFF_0 0xf300
+#define STB0899_OFF1_EQ_I_OUT_COEFF_1 0xf304
+#define STB0899_OFF2_EQ_I_OUT_COEFF_2 0xf308
+#define STB0899_OFF3_EQ_I_OUT_COEFF_3 0xf30c
+#define STB0899_OFF4_EQ_I_OUT_COEFF_4 0xf310
+#define STB0899_OFF5_EQ_I_OUT_COEFF_5 0xf314
+#define STB0899_OFF6_EQ_I_OUT_COEFF_6 0xf318
+#define STB0899_OFF7_EQ_I_OUT_COEFF_7 0xf31c
+#define STB0899_OFF8_EQ_I_OUT_COEFF_8 0xf320
+#define STB0899_OFF9_EQ_I_OUT_COEFF_9 0xf324
+#define STB0899_OFFa_EQ_I_OUT_COEFF_10 0xf328
+#define STB0899_BASE_EQ_I_OUT_COEFF_N 0x00000460
+#define STB0899_EQ_I_OUT_COEFF_N (0x0fff << 0)
+#define STB0899_OFFST_EQ_I_OUT_COEFF_N 0
+#define STB0899_WIDTH_EQ_I_OUT_COEFF_N 12
+
+#define STB0899_OFF0_EQ_Q_OUT_COEFF_0 0xf330
+#define STB0899_OFF1_EQ_Q_OUT_COEFF_1 0xf334
+#define STB0899_OFF2_EQ_Q_OUT_COEFF_2 0xf338
+#define STB0899_OFF3_EQ_Q_OUT_COEFF_3 0xf33c
+#define STB0899_OFF4_EQ_Q_OUT_COEFF_4 0xf340
+#define STB0899_OFF5_EQ_Q_OUT_COEFF_5 0xf344
+#define STB0899_OFF6_EQ_Q_OUT_COEFF_6 0xf348
+#define STB0899_OFF7_EQ_Q_OUT_COEFF_7 0xf34c
+#define STB0899_OFF8_EQ_Q_OUT_COEFF_8 0xf350
+#define STB0899_OFF9_EQ_Q_OUT_COEFF_9 0xf354
+#define STB0899_OFFa_EQ_Q_OUT_COEFF_10 0xf358
+#define STB0899_BASE_EQ_Q_OUT_COEFF_N 0x00000460
+#define STB0899_EQ_Q_OUT_COEFF_N (0x0fff << 0)
+#define STB0899_OFFST_EQ_Q_OUT_COEFF_N 0
+#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N 12
+
+/* S2 FEC */
+#define STB0899_OFF0_BLOCK_LNGTH 0xfa04
+#define STB0899_BASE_BLOCK_LNGTH 0x00000000
+#define STB0899_BLOCK_LENGTH (0xff << 0)
+#define STB0899_OFFST_BLOCK_LENGTH 0
+#define STB0899_WIDTH_BLOCK_LENGTH 8
+
+#define STB0899_OFF0_ROW_STR 0xfa08
+#define STB0899_BASE_ROW_STR 0x00000000
+#define STB0899_ROW_STRIDE (0xff << 0)
+#define STB0899_OFFST_ROW_STRIDE 0
+#define STB0899_WIDTH_ROW_STRIDE 8
+
+#define STB0899_OFF0_MAX_ITER 0xfa0c
+#define STB0899_BASE_MAX_ITER 0x00000000
+#define STB0899_MAX_ITERATIONS (0xff << 0)
+#define STB0899_OFFST_MAX_ITERATIONS 0
+#define STB0899_WIDTH_MAX_ITERATIONS 8
+
+#define STB0899_OFF0_BN_END_ADDR 0xfa10
+#define STB0899_BASE_BN_END_ADDR 0x00000000
+#define STB0899_BN_END_ADDR (0x0fff << 0)
+#define STB0899_OFFST_BN_END_ADDR 0
+#define STB0899_WIDTH_BN_END_ADDR 12
+
+#define STB0899_OFF0_CN_END_ADDR 0xfa14
+#define STB0899_BASE_CN_END_ADDR 0x00000000
+#define STB0899_CN_END_ADDR (0x0fff << 0)
+#define STB0899_OFFST_CN_END_ADDR 0
+#define STB0899_WIDTH_CN_END_ADDR 12
+
+#define STB0899_OFF0_INFO_LENGTH 0xfa1c
+#define STB0899_BASE_INFO_LENGTH 0x00000000
+#define STB0899_INFO_LENGTH (0xff << 0)
+#define STB0899_OFFST_INFO_LENGTH 0
+#define STB0899_WIDTH_INFO_LENGTH 8
+
+#define STB0899_OFF0_BOT_ADDR 0xfa20
+#define STB0899_BASE_BOT_ADDR 0x00000000
+#define STB0899_BOTTOM_BASE_ADDR (0x03ff << 0)
+#define STB0899_OFFST_BOTTOM_BASE_ADDR 0
+#define STB0899_WIDTH_BOTTOM_BASE_ADDR 10
+
+#define STB0899_OFF0_BCH_BLK_LN 0xfa24
+#define STB0899_BASE_BCH_BLK_LN 0x00000000
+#define STB0899_BCH_BLOCK_LENGTH (0xffff << 0)
+#define STB0899_OFFST_BCH_BLOCK_LENGTH 0
+#define STB0899_WIDTH_BCH_BLOCK_LENGTH 16
+
+#define STB0899_OFF0_BCH_T 0xfa28
+#define STB0899_BASE_BCH_T 0x00000000
+#define STB0899_BCH_T (0x0f << 0)
+#define STB0899_OFFST_BCH_T 0
+#define STB0899_WIDTH_BCH_T 4
+
+#define STB0899_OFF0_CNFG_MODE 0xfa00
+#define STB0899_BASE_CNFG_MODE 0x00000800
+#define STB0899_MODCOD (0x1f << 2)
+#define STB0899_OFFST_MODCOD 2
+#define STB0899_WIDTH_MODCOD 5
+#define STB0899_MODCOD_SEL (0x01 << 1)
+#define STB0899_OFFST_MODCOD_SEL 1
+#define STB0899_WIDTH_MODCOD_SEL 1
+#define STB0899_CONFIG_MODE (0x01 << 0)
+#define STB0899_OFFST_CONFIG_MODE 0
+#define STB0899_WIDTH_CONFIG_MODE 1
+
+#define STB0899_OFF0_LDPC_STAT 0xfa04
+#define STB0899_BASE_LDPC_STAT 0x00000800
+#define STB0899_ITERATION (0xff << 3)
+#define STB0899_OFFST_ITERATION 3
+#define STB0899_WIDTH_ITERATION 8
+#define STB0899_LDPC_DEC_STATE (0x07 << 0)
+#define STB0899_OFFST_LDPC_DEC_STATE 0
+#define STB0899_WIDTH_LDPC_DEC_STATE 3
+
+#define STB0899_OFF0_ITER_SCALE 0xfa08
+#define STB0899_BASE_ITER_SCALE 0x00000800
+#define STB0899_ITERATION_SCALE (0xff << 0)
+#define STB0899_OFFST_ITERATION_SCALE 0
+#define STB0899_WIDTH_ITERATION_SCALE 8
+
+#define STB0899_OFF0_INPUT_MODE 0xfa0c
+#define STB0899_BASE_INPUT_MODE 0x00000800
+#define STB0899_SD_BLOCK1_STREAM0 (0x01 << 0)
+#define STB0899_OFFST_SD_BLOCK1_STREAM0 0
+#define STB0899_WIDTH_SD_BLOCK1_STREAM0 1
+
+#define STB0899_OFF0_LDPCDECRST 0xfa10
+#define STB0899_BASE_LDPCDECRST 0x00000800
+#define STB0899_LDPC_DEC_RST (0x01 << 0)
+#define STB0899_OFFST_LDPC_DEC_RST 0
+#define STB0899_WIDTH_LDPC_DEC_RST 1
+
+#define STB0899_OFF0_CLK_PER_BYTE_RW 0xfa14
+#define STB0899_BASE_CLK_PER_BYTE_RW 0x00000800
+#define STB0899_CLKS_PER_BYTE (0x0f << 0)
+#define STB0899_OFFST_CLKS_PER_BYTE 0
+#define STB0899_WIDTH_CLKS_PER_BYTE 5
+
+#define STB0899_OFF0_BCH_ERRORS 0xfa18
+#define STB0899_BASE_BCH_ERRORS 0x00000800
+#define STB0899_BCH_ERRORS (0x0f << 0)
+#define STB0899_OFFST_BCH_ERRORS 0
+#define STB0899_WIDTH_BCH_ERRORS 4
+
+#define STB0899_OFF0_LDPC_ERRORS 0xfa1c
+#define STB0899_BASE_LDPC_ERRORS 0x00000800
+#define STB0899_LDPC_ERRORS (0xffff << 0)
+#define STB0899_OFFST_LDPC_ERRORS 0
+#define STB0899_WIDTH_LDPC_ERRORS 16
+
+#define STB0899_OFF0_BCH_MODE 0xfa20
+#define STB0899_BASE_BCH_MODE 0x00000800
+#define STB0899_BCH_CORRECT_N (0x01 << 1)
+#define STB0899_OFFST_BCH_CORRECT_N 1
+#define STB0899_WIDTH_BCH_CORRECT_N 1
+#define STB0899_FULL_BYPASS (0x01 << 0)
+#define STB0899_OFFST_FULL_BYPASS 0
+#define STB0899_WIDTH_FULL_BYPASS 1
+
+#define STB0899_OFF0_ERR_ACC_PER 0xfa24
+#define STB0899_BASE_ERR_ACC_PER 0x00000800
+#define STB0899_BCH_ERR_ACC_PERIOD (0x0f << 0)
+#define STB0899_OFFST_BCH_ERR_ACC_PERIOD 0
+#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD 4
+
+#define STB0899_OFF0_BCH_ERR_ACC 0xfa28
+#define STB0899_BASE_BCH_ERR_ACC 0x00000800
+#define STB0899_BCH_ERR_ACCUM (0xff << 0)
+#define STB0899_OFFST_BCH_ERR_ACCUM 0
+#define STB0899_WIDTH_BCH_ERR_ACCUM 8
+
+#define STB0899_OFF0_FEC_CORE_ID_REG 0xfa2c
+#define STB0899_BASE_FEC_CORE_ID_REG 0x00000800
+#define STB0899_FEC_CORE_ID (0xffffffff << 0)
+#define STB0899_OFFST_FEC_CORE_ID 0
+#define STB0899_WIDTH_FEC_CORE_ID 32
+
+#define STB0899_OFF0_FEC_VER_ID_REG 0xfa34
+#define STB0899_BASE_FEC_VER_ID_REG 0x00000800
+#define STB0899_FEC_VER_ID (0xff << 0)
+#define STB0899_OFFST_FEC_VER_ID 0
+#define STB0899_WIDTH_FEC_VER_ID 8
+
+#define STB0899_OFF0_FEC_TP_SEL 0xfa38
+#define STB0899_BASE_FEC_TP_SEL 0x00000800
+
+#define STB0899_OFF0_CSM_CNTRL1 0xf310
+#define STB0899_BASE_CSM_CNTRL1 0x00000400
+#define STB0899_CSM_FORCE_FREQLOCK (0x01 << 19)
+#define STB0899_OFFST_CSM_FORCE_FREQLOCK 19
+#define STB0899_WIDTH_CSM_FORCE_FREQLOCK 1
+#define STB0899_CSM_FREQ_LOCKSTATE (0x01 << 18)
+#define STB0899_OFFST_CSM_FREQ_LOCKSTATE 18
+#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE 1
+#define STB0899_CSM_AUTO_PARAM (0x01 << 17)
+#define STB0899_OFFST_CSM_AUTO_PARAM 17
+#define STB0899_WIDTH_CSM_AUTO_PARAM 1
+#define STB0899_FE_LOOP_SHIFT (0x07 << 14)
+#define STB0899_OFFST_FE_LOOP_SHIFT 14
+#define STB0899_WIDTH_FE_LOOP_SHIFT 3
+#define STB0899_CSM_AGC_SHIFT (0x07 << 11)
+#define STB0899_OFFST_CSM_AGC_SHIFT 11
+#define STB0899_WIDTH_CSM_AGC_SHIFT 3
+#define STB0899_CSM_AGC_GAIN (0x1ff << 2)
+#define STB0899_OFFST_CSM_AGC_GAIN 2
+#define STB0899_WIDTH_CSM_AGC_GAIN 9
+#define STB0899_CSM_TWO_PASS (0x01 << 1)
+#define STB0899_OFFST_CSM_TWO_PASS 1
+#define STB0899_WIDTH_CSM_TWO_PASS 1
+#define STB0899_CSM_DVT_TABLE (0x01 << 0)
+#define STB0899_OFFST_CSM_DVT_TABLE 0
+#define STB0899_WIDTH_CSM_DVT_TABLE 1
+
+#define STB0899_OFF0_CSM_CNTRL2 0xf314
+#define STB0899_BASE_CSM_CNTRL2 0x00000400
+#define STB0899_CSM_GAMMA_RHO_ACQ (0x1ff << 9)
+#define STB0899_OFFST_CSM_GAMMA_RHOACQ 9
+#define STB0899_WIDTH_CSM_GAMMA_RHOACQ 9
+#define STB0899_CSM_GAMMA_ACQ (0x1ff << 0)
+#define STB0899_OFFST_CSM_GAMMA_ACQ 0
+#define STB0899_WIDTH_CSM_GAMMA_ACQ 9
+
+#define STB0899_OFF0_CSM_CNTRL3 0xf318
+#define STB0899_BASE_CSM_CNTRL3 0x00000400
+#define STB0899_CSM_GAMMA_RHO_TRACK (0x1ff << 9)
+#define STB0899_OFFST_CSM_GAMMA_RHOTRACK 9
+#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK 9
+#define STB0899_CSM_GAMMA_TRACK (0x1ff << 0)
+#define STB0899_OFFST_CSM_GAMMA_TRACK 0
+#define STB0899_WIDTH_CSM_GAMMA_TRACK 9
+
+#define STB0899_OFF0_CSM_CNTRL4 0xf31c
+#define STB0899_BASE_CSM_CNTRL4 0x00000400
+#define STB0899_CSM_PHASEDIFF_THRESH (0x0f << 8)
+#define STB0899_OFFST_CSM_PHASEDIFF_THRESH 8
+#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH 4
+#define STB0899_CSM_LOCKCOUNT_THRESH (0xff << 0)
+#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH 0
+#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH 8
+
+/* Check on chapter 8 page 42 */
+#define STB0899_ERRCTRL1 0xf574
+#define STB0899_ERRCTRL2 0xf575
+#define STB0899_ERRCTRL3 0xf576
+#define STB0899_ERR_SRC_S1 (0x1f << 3)
+#define STB0899_OFFST_ERR_SRC_S1 3
+#define STB0899_WIDTH_ERR_SRC_S1 5
+#define STB0899_ERR_SRC_S2 (0x0f << 0)
+#define STB0899_OFFST_ERR_SRC_S2 0
+#define STB0899_WIDTH_ERR_SRC_S2 4
+#define STB0899_NOE (0x07 << 0)
+#define STB0899_OFFST_NOE 0
+#define STB0899_WIDTH_NOE 3
+
+#define STB0899_ECNT1M 0xf524
+#define STB0899_ECNT1L 0xf525
+#define STB0899_ECNT2M 0xf526
+#define STB0899_ECNT2L 0xf527
+#define STB0899_ECNT3M 0xf528
+#define STB0899_ECNT3L 0xf529
+
+#define STB0899_DMONMSK1 0xf57b
+#define STB0899_DMONMSK1_WAIT_1STEP (1 << 7)
+#define STB0899_DMONMSK1_FREE_14 (1 << 6)
+#define STB0899_DMONMSK1_AVRGVIT_CALC (1 << 5)
+#define STB0899_DMONMSK1_FREE_12 (1 << 4)
+#define STB0899_DMONMSK1_FREE_11 (1 << 3)
+#define STB0899_DMONMSK1_B0DIV_CALC (1 << 2)
+#define STB0899_DMONMSK1_KDIVB1_CALC (1 << 1)
+#define STB0899_DMONMSK1_KDIVB2_CALC (1 << 0)
+
+#define STB0899_DMONMSK0 0xf57c
+#define STB0899_DMONMSK0_SMOTTH_CALC (1 << 7)
+#define STB0899_DMONMSK0_FREE_6 (1 << 6)
+#define STB0899_DMONMSK0_SIGPOWER_CALC (1 << 5)
+#define STB0899_DMONMSK0_QSEUIL_CALC (1 << 4)
+#define STB0899_DMONMSK0_FREE_3 (1 << 3)
+#define STB0899_DMONMSK0_FREE_2 (1 << 2)
+#define STB0899_DMONMSK0_KVDIVB1_CALC (1 << 1)
+#define STB0899_DMONMSK0_KVDIVB2_CALC (1 << 0)
+
+#define STB0899_TSULC 0xf549
+#define STB0899_ULNOSYNCBYTES (0x01 << 7)
+#define STB0899_OFFST_ULNOSYNCBYTES 7
+#define STB0899_WIDTH_ULNOSYNCBYTES 1
+#define STB0899_ULPARITY_ON (0x01 << 6)
+#define STB0899_OFFST_ULPARITY_ON 6
+#define STB0899_WIDTH_ULPARITY_ON 1
+#define STB0899_ULSYNCOUTRS (0x01 << 5)
+#define STB0899_OFFST_ULSYNCOUTRS 5
+#define STB0899_WIDTH_ULSYNCOUTRS 1
+#define STB0899_ULDSS_PACKETS (0x01 << 0)
+#define STB0899_OFFST_ULDSS_PACKETS 0
+#define STB0899_WIDTH_ULDSS_PACKETS 1
+
+#define STB0899_TSLPL 0xf54b
+#define STB0899_LLDVBS2_MODE (0x01 << 4)
+#define STB0899_OFFST_LLDVBS2_MODE 4
+#define STB0899_WIDTH_LLDVBS2_MODE 1
+#define STB0899_LLISSYI_ON (0x01 << 3)
+#define STB0899_OFFST_LLISSYI_ON 3
+#define STB0899_WIDTH_LLISSYI_ON 1
+#define STB0899_LLNPD_ON (0x01 << 2)
+#define STB0899_OFFST_LLNPD_ON 2
+#define STB0899_WIDTH_LLNPD_ON 1
+#define STB0899_LLCRC8_ON (0x01 << 1)
+#define STB0899_OFFST_LLCRC8_ON 1
+#define STB0899_WIDTH_LLCRC8_ON 1
+
+#define STB0899_TSCFGH 0xf54c
+#define STB0899_OUTRS_PS (0x01 << 6)
+#define STB0899_OFFST_OUTRS_PS 6
+#define STB0899_WIDTH_OUTRS_PS 1
+#define STB0899_SYNCBYTE (0x01 << 5)
+#define STB0899_OFFST_SYNCBYTE 5
+#define STB0899_WIDTH_SYNCBYTE 1
+#define STB0899_PFBIT (0x01 << 4)
+#define STB0899_OFFST_PFBIT 4
+#define STB0899_WIDTH_PFBIT 1
+#define STB0899_ERR_BIT (0x01 << 3)
+#define STB0899_OFFST_ERR_BIT 3
+#define STB0899_WIDTH_ERR_BIT 1
+#define STB0899_MPEG (0x01 << 2)
+#define STB0899_OFFST_MPEG 2
+#define STB0899_WIDTH_MPEG 1
+#define STB0899_CLK_POL (0x01 << 1)
+#define STB0899_OFFST_CLK_POL 1
+#define STB0899_WIDTH_CLK_POL 1
+#define STB0899_FORCE0 (0x01 << 0)
+#define STB0899_OFFST_FORCE0 0
+#define STB0899_WIDTH_FORCE0 1
+
+#define STB0899_TSCFGM 0xf54d
+#define STB0899_LLPRIORITY (0x01 << 3)
+#define STB0899_OFFST_LLPRIORIY 3
+#define STB0899_WIDTH_LLPRIORITY 1
+#define STB0899_EN188 (0x01 << 2)
+#define STB0899_OFFST_EN188 2
+#define STB0899_WIDTH_EN188 1
+
+#define STB0899_TSCFGL 0xf54e
+#define STB0899_DEL_ERRPCK (0x01 << 7)
+#define STB0899_OFFST_DEL_ERRPCK 7
+#define STB0899_WIDTH_DEL_ERRPCK 1
+#define STB0899_ERRFLAGSTD (0x01 << 5)
+#define STB0899_OFFST_ERRFLAGSTD 5
+#define STB0899_WIDTH_ERRFLAGSTD 1
+#define STB0899_MPEGERR (0x01 << 4)
+#define STB0899_OFFST_MPEGERR 4
+#define STB0899_WIDTH_MPEGERR 1
+#define STB0899_BCH_CHK (0x01 << 3)
+#define STB0899_OFFST_BCH_CHK 5
+#define STB0899_WIDTH_BCH_CHK 1
+#define STB0899_CRC8CHK (0x01 << 2)
+#define STB0899_OFFST_CRC8CHK 2
+#define STB0899_WIDTH_CRC8CHK 1
+#define STB0899_SPEC_INFO (0x01 << 1)
+#define STB0899_OFFST_SPEC_INFO 1
+#define STB0899_WIDTH_SPEC_INFO 1
+#define STB0899_LOW_PRIO_CLK (0x01 << 0)
+#define STB0899_OFFST_LOW_PRIO_CLK 0
+#define STB0899_WIDTH_LOW_PRIO_CLK 1
+#define STB0899_ERROR_NORM (0x00 << 0)
+#define STB0899_OFFST_ERROR_NORM 0
+#define STB0899_WIDTH_ERROR_NORM 0
+
+#define STB0899_TSOUT 0xf54f
+#define STB0899_RSSYNCDEL 0xf550
+#define STB0899_TSINHDELH 0xf551
+#define STB0899_TSINHDELM 0xf552
+#define STB0899_TSINHDELL 0xf553
+#define STB0899_TSLLSTKM 0xf55a
+#define STB0899_TSLLSTKL 0xf55b
+#define STB0899_TSULSTKM 0xf55c
+#define STB0899_TSULSTKL 0xf55d
+#define STB0899_TSSTATUS 0xf561
+
+#define STB0899_PDELCTRL 0xf600
+#define STB0899_INVERT_RES (0x01 << 7)
+#define STB0899_OFFST_INVERT_RES 7
+#define STB0899_WIDTH_INVERT_RES 1
+#define STB0899_FORCE_ACCEPTED (0x01 << 6)
+#define STB0899_OFFST_FORCE_ACCEPTED 6
+#define STB0899_WIDTH_FORCE_ACCEPTED 1
+#define STB0899_FILTER_EN (0x01 << 5)
+#define STB0899_OFFST_FILTER_EN 5
+#define STB0899_WIDTH_FILTER_EN 1
+#define STB0899_LOCKFALL_THRESH (0x01 << 4)
+#define STB0899_OFFST_LOCKFALL_THRESH 4
+#define STB0899_WIDTH_LOCKFALL_THRESH 1
+#define STB0899_HYST_EN (0x01 << 3)
+#define STB0899_OFFST_HYST_EN 3
+#define STB0899_WIDTH_HYST_EN 1
+#define STB0899_HYST_SWRST (0x01 << 2)
+#define STB0899_OFFST_HYST_SWRST 2
+#define STB0899_WIDTH_HYST_SWRST 1
+#define STB0899_ALGO_EN (0x01 << 1)
+#define STB0899_OFFST_ALGO_EN 1
+#define STB0899_WIDTH_ALGO_EN 1
+#define STB0899_ALGO_SWRST (0x01 << 0)
+#define STB0899_OFFST_ALGO_SWRST 0
+#define STB0899_WIDTH_ALGO_SWRST 1
+
+#define STB0899_PDELCTRL2 0xf601
+#define STB0899_BBHCTRL1 0xf602
+#define STB0899_BBHCTRL2 0xf603
+#define STB0899_HYSTTHRESH 0xf604
+
+#define STB0899_MATCSTM 0xf605
+#define STB0899_MATCSTL 0xf606
+#define STB0899_UPLCSTM 0xf607
+#define STB0899_UPLCSTL 0xf608
+#define STB0899_DFLCSTM 0xf609
+#define STB0899_DFLCSTL 0xf60a
+#define STB0899_SYNCCST 0xf60b
+#define STB0899_SYNCDCSTM 0xf60c
+#define STB0899_SYNCDCSTL 0xf60d
+#define STB0899_ISI_ENTRY 0xf60e
+#define STB0899_ISI_BIT_EN 0xf60f
+#define STB0899_MATSTRM 0xf610
+#define STB0899_MATSTRL 0xf611
+#define STB0899_UPLSTRM 0xf612
+#define STB0899_UPLSTRL 0xf613
+#define STB0899_DFLSTRM 0xf614
+#define STB0899_DFLSTRL 0xf615
+#define STB0899_SYNCSTR 0xf616
+#define STB0899_SYNCDSTRM 0xf617
+#define STB0899_SYNCDSTRL 0xf618
+
+#define STB0899_CFGPDELSTATUS1 0xf619
+#define STB0899_BADDFL (0x01 << 6)
+#define STB0899_OFFST_BADDFL 6
+#define STB0899_WIDTH_BADDFL 1
+#define STB0899_CONTINUOUS_STREAM (0x01 << 5)
+#define STB0899_OFFST_CONTINUOUS_STREAM 5
+#define STB0899_WIDTH_CONTINUOUS_STREAM 1
+#define STB0899_ACCEPTED_STREAM (0x01 << 4)
+#define STB0899_OFFST_ACCEPTED_STREAM 4
+#define STB0899_WIDTH_ACCEPTED_STREAM 1
+#define STB0899_BCH_ERRFLAG (0x01 << 3)
+#define STB0899_OFFST_BCH_ERRFLAG 3
+#define STB0899_WIDTH_BCH_ERRFLAG 1
+#define STB0899_CRCRES (0x01 << 2)
+#define STB0899_OFFST_CRCRES 2
+#define STB0899_WIDTH_CRCRES 1
+#define STB0899_CFGPDELSTATUS_LOCK (0x01 << 1)
+#define STB0899_OFFST_CFGPDELSTATUS_LOCK 1
+#define STB0899_WIDTH_CFGPDELSTATUS_LOCK 1
+#define STB0899_1STLOCK (0x01 << 0)
+#define STB0899_OFFST_1STLOCK 0
+#define STB0899_WIDTH_1STLOCK 1
+
+#define STB0899_CFGPDELSTATUS2 0xf61a
+#define STB0899_BBFERRORM 0xf61b
+#define STB0899_BBFERRORL 0xf61c
+#define STB0899_UPKTERRORM 0xf61d
+#define STB0899_UPKTERRORL 0xf61e
+
+#define STB0899_TSTCK 0xff10
+
+#define STB0899_TSTRES 0xff11
+#define STB0899_FRESLDPC (0x01 << 7)
+#define STB0899_OFFST_FRESLDPC 7
+#define STB0899_WIDTH_FRESLDPC 1
+#define STB0899_FRESRS (0x01 << 6)
+#define STB0899_OFFST_FRESRS 6
+#define STB0899_WIDTH_FRESRS 1
+#define STB0899_FRESVIT (0x01 << 5)
+#define STB0899_OFFST_FRESVIT 5
+#define STB0899_WIDTH_FRESVIT 1
+#define STB0899_FRESMAS1_2 (0x01 << 4)
+#define STB0899_OFFST_FRESMAS1_2 4
+#define STB0899_WIDTH_FRESMAS1_2 1
+#define STB0899_FRESACS (0x01 << 3)
+#define STB0899_OFFST_FRESACS 3
+#define STB0899_WIDTH_FRESACS 1
+#define STB0899_FRESSYM (0x01 << 2)
+#define STB0899_OFFST_FRESSYM 2
+#define STB0899_WIDTH_FRESSYM 1
+#define STB0899_FRESMAS (0x01 << 1)
+#define STB0899_OFFST_FRESMAS 1
+#define STB0899_WIDTH_FRESMAS 1
+#define STB0899_FRESINT (0x01 << 0)
+#define STB0899_OFFST_FRESINIT 0
+#define STB0899_WIDTH_FRESINIT 1
+
+#define STB0899_TSTOUT 0xff12
+#define STB0899_EN_SIGNATURE (0x01 << 7)
+#define STB0899_OFFST_EN_SIGNATURE 7
+#define STB0899_WIDTH_EN_SIGNATURE 1
+#define STB0899_BCLK_CLK (0x01 << 6)
+#define STB0899_OFFST_BCLK_CLK 6
+#define STB0899_WIDTH_BCLK_CLK 1
+#define STB0899_SGNL_OUT (0x01 << 5)
+#define STB0899_OFFST_SGNL_OUT 5
+#define STB0899_WIDTH_SGNL_OUT 1
+#define STB0899_TS (0x01 << 4)
+#define STB0899_OFFST_TS 4
+#define STB0899_WIDTH_TS 1
+#define STB0899_CTEST (0x01 << 0)
+#define STB0899_OFFST_CTEST 0
+#define STB0899_WIDTH_CTEST 1
+
+#define STB0899_TSTIN 0xff13
+#define STB0899_TEST_IN (0x01 << 7)
+#define STB0899_OFFST_TEST_IN 7
+#define STB0899_WIDTH_TEST_IN 1
+#define STB0899_EN_ADC (0x01 << 6)
+#define STB0899_OFFST_EN_ADC 6
+#define STB0899_WIDTH_ENADC 1
+#define STB0899_SGN_ADC (0x01 << 5)
+#define STB0899_OFFST_SGN_ADC 5
+#define STB0899_WIDTH_SGN_ADC 1
+#define STB0899_BCLK_IN (0x01 << 4)
+#define STB0899_OFFST_BCLK_IN 4
+#define STB0899_WIDTH_BCLK_IN 1
+#define STB0899_JETONIN_MODE (0x01 << 3)
+#define STB0899_OFFST_JETONIN_MODE 3
+#define STB0899_WIDTH_JETONIN_MODE 1
+#define STB0899_BCLK_VALUE (0x01 << 2)
+#define STB0899_OFFST_BCLK_VALUE 2
+#define STB0899_WIDTH_BCLK_VALUE 1
+#define STB0899_SGNRST_T12 (0x01 << 1)
+#define STB0899_OFFST_SGNRST_T12 1
+#define STB0899_WIDTH_SGNRST_T12 1
+#define STB0899_LOWSP_ENAX (0x01 << 0)
+#define STB0899_OFFST_LOWSP_ENAX 0
+#define STB0899_WIDTH_LOWSP_ENAX 1
+
+#define STB0899_TSTSYS 0xff14
+#define STB0899_TSTCHIP 0xff15
+#define STB0899_TSTFREE 0xff16
+#define STB0899_TSTI2C 0xff17
+#define STB0899_BITSPEEDM 0xff1c
+#define STB0899_BITSPEEDL 0xff1d
+#define STB0899_TBUSBIT 0xff1e
+#define STB0899_TSTDIS 0xff24
+#define STB0899_TSTDISRX 0xff25
+#define STB0899_TSTJETON 0xff28
+#define STB0899_TSTDCADJ 0xff40
+#define STB0899_TSTAGC1 0xff41
+#define STB0899_TSTAGC1N 0xff42
+#define STB0899_TSTPOLYPH 0xff48
+#define STB0899_TSTR 0xff49
+#define STB0899_TSTAGC2 0xff4a
+#define STB0899_TSTCTL1 0xff4b
+#define STB0899_TSTCTL2 0xff4c
+#define STB0899_TSTCTL3 0xff4d
+#define STB0899_TSTDEMAP 0xff50
+#define STB0899_TSTDEMAP2 0xff51
+#define STB0899_TSTDEMMON 0xff52
+#define STB0899_TSTRATE 0xff53
+#define STB0899_TSTSELOUT 0xff54
+#define STB0899_TSYNC 0xff55
+#define STB0899_TSTERR 0xff56
+#define STB0899_TSTRAM1 0xff58
+#define STB0899_TSTVSELOUT 0xff59
+#define STB0899_TSTFORCEIN 0xff5a
+#define STB0899_TSTRS1 0xff5c
+#define STB0899_TSTRS2 0xff5d
+#define STB0899_TSTRS3 0xff53
+
+#define STB0899_INTBUFSTATUS 0xf200
+#define STB0899_INTBUFCTRL 0xf201
+#define STB0899_PCKLENUL 0xf55e
+#define STB0899_PCKLENLL 0xf55f
+#define STB0899_RSPCKLEN 0xf560
+
+/* 2 registers */
+#define STB0899_SYNCDCST 0xf60c
+
+/* DiSEqC */
+#define STB0899_DISCNTRL1 0xf0a0
+#define STB0899_TIMOFF (0x01 << 7)
+#define STB0899_OFFST_TIMOFF 7
+#define STB0899_WIDTH_TIMOFF 1
+#define STB0899_DISEQCRESET (0x01 << 6)
+#define STB0899_OFFST_DISEQCRESET 6
+#define STB0899_WIDTH_DISEQCRESET 1
+#define STB0899_TIMCMD (0x03 << 4)
+#define STB0899_OFFST_TIMCMD 4
+#define STB0899_WIDTH_TIMCMD 2
+#define STB0899_DISPRECHARGE (0x01 << 2)
+#define STB0899_OFFST_DISPRECHARGE 2
+#define STB0899_WIDTH_DISPRECHARGE 1
+#define STB0899_DISEQCMODE (0x03 << 0)
+#define STB0899_OFFST_DISEQCMODE 0
+#define STB0899_WIDTH_DISEQCMODE 2
+
+#define STB0899_DISCNTRL2 0xf0a1
+#define STB0899_RECEIVER_ON (0x01 << 7)
+#define STB0899_OFFST_RECEIVER_ON 7
+#define STB0899_WIDTH_RECEIVER_ON 1
+#define STB0899_IGNO_SHORT_22K (0x01 << 6)
+#define STB0899_OFFST_IGNO_SHORT_22K 6
+#define STB0899_WIDTH_IGNO_SHORT_22K 1
+#define STB0899_ONECHIP_TRX (0x01 << 5)
+#define STB0899_OFFST_ONECHIP_TRX 5
+#define STB0899_WIDTH_ONECHIP_TRX 1
+#define STB0899_EXT_ENVELOP (0x01 << 4)
+#define STB0899_OFFST_EXT_ENVELOP 4
+#define STB0899_WIDTH_EXT_ENVELOP 1
+#define STB0899_PIN_SELECT (0x03 << 2)
+#define STB0899_OFFST_PIN_SELCT 2
+#define STB0899_WIDTH_PIN_SELCT 2
+#define STB0899_IRQ_RXEND (0x01 << 1)
+#define STB0899_OFFST_IRQ_RXEND 1
+#define STB0899_WIDTH_IRQ_RXEND 1
+#define STB0899_IRQ_4NBYTES (0x01 << 0)
+#define STB0899_OFFST_IRQ_4NBYTES 0
+#define STB0899_WIDTH_IRQ_4NBYTES 1
+
+#define STB0899_DISRX_ST0 0xf0a4
+#define STB0899_RXEND (0x01 << 7)
+#define STB0899_OFFST_RXEND 7
+#define STB0899_WIDTH_RXEND 1
+#define STB0899_RXACTIVE (0x01 << 6)
+#define STB0899_OFFST_RXACTIVE 6
+#define STB0899_WIDTH_RXACTIVE 1
+#define STB0899_SHORT22K (0x01 << 5)
+#define STB0899_OFFST_SHORT22K 5
+#define STB0899_WIDTH_SHORT22K 1
+#define STB0899_CONTTONE (0x01 << 4)
+#define STB0899_OFFST_CONTTONE 4
+#define STB0899_WIDTH_CONTONE 1
+#define STB0899_4BFIFOREDY (0x01 << 3)
+#define STB0899_OFFST_4BFIFOREDY 3
+#define STB0899_WIDTH_4BFIFOREDY 1
+#define STB0899_FIFOEMPTY (0x01 << 2)
+#define STB0899_OFFST_FIFOEMPTY 2
+#define STB0899_WIDTH_FIFOEMPTY 1
+#define STB0899_ABORTTRX (0x01 << 0)
+#define STB0899_OFFST_ABORTTRX 0
+#define STB0899_WIDTH_ABORTTRX 1
+
+#define STB0899_DISRX_ST1 0xf0a5
+#define STB0899_RXFAIL (0x01 << 7)
+#define STB0899_OFFST_RXFAIL 7
+#define STB0899_WIDTH_RXFAIL 1
+#define STB0899_FIFOPFAIL (0x01 << 6)
+#define STB0899_OFFST_FIFOPFAIL 6
+#define STB0899_WIDTH_FIFOPFAIL 1
+#define STB0899_RXNONBYTES (0x01 << 5)
+#define STB0899_OFFST_RXNONBYTES 5
+#define STB0899_WIDTH_RXNONBYTES 1
+#define STB0899_FIFOOVF (0x01 << 4)
+#define STB0899_OFFST_FIFOOVF 4
+#define STB0899_WIDTH_FIFOOVF 1
+#define STB0899_FIFOBYTENBR (0x0f << 0)
+#define STB0899_OFFST_FIFOBYTENBR 0
+#define STB0899_WIDTH_FIFOBYTENBR 4
+
+#define STB0899_DISPARITY 0xf0a6
+
+#define STB0899_DISFIFO 0xf0a7
+
+#define STB0899_DISSTATUS 0xf0a8
+#define STB0899_FIFOFULL (0x01 << 6)
+#define STB0899_OFFST_FIFOFULL 6
+#define STB0899_WIDTH_FIFOFULL 1
+#define STB0899_TXIDLE (0x01 << 5)
+#define STB0899_OFFST_TXIDLE 5
+#define STB0899_WIDTH_TXIDLE 1
+#define STB0899_GAPBURST (0x01 << 4)
+#define STB0899_OFFST_GAPBURST 4
+#define STB0899_WIDTH_GAPBURST 1
+#define STB0899_TXFIFOBYTES (0x0f << 0)
+#define STB0899_OFFST_TXFIFOBYTES 0
+#define STB0899_WIDTH_TXFIFOBYTES 4
+#define STB0899_DISF22 0xf0a9
+
+#define STB0899_DISF22RX 0xf0aa
+
+/* General Purpose */
+#define STB0899_SYSREG 0xf101
+#define STB0899_ACRPRESC 0xf110
+#define STB0899_OFFST_RSVD2 7
+#define STB0899_WIDTH_RSVD2 1
+#define STB0899_OFFST_ACRPRESC 4
+#define STB0899_WIDTH_ACRPRESC 3
+#define STB0899_OFFST_RSVD1 3
+#define STB0899_WIDTH_RSVD1 1
+#define STB0899_OFFST_ACRPRESC2 0
+#define STB0899_WIDTH_ACRPRESC2 3
+
+#define STB0899_ACRDIV1 0xf111
+#define STB0899_ACRDIV2 0xf112
+#define STB0899_DACR1 0xf113
+#define STB0899_DACR2 0xf114
+#define STB0899_OUTCFG 0xf11c
+#define STB0899_MODECFG 0xf11d
+#define STB0899_NCOARSE 0xf1b3
+
+#define STB0899_SYNTCTRL 0xf1b6
+#define STB0899_STANDBY (0x01 << 7)
+#define STB0899_OFFST_STANDBY 7
+#define STB0899_WIDTH_STANDBY 1
+#define STB0899_BYPASSPLL (0x01 << 6)
+#define STB0899_OFFST_BYPASSPLL 6
+#define STB0899_WIDTH_BYPASSPLL 1
+#define STB0899_SEL1XRATIO (0x01 << 5)
+#define STB0899_OFFST_SEL1XRATIO 5
+#define STB0899_WIDTH_SEL1XRATIO 1
+#define STB0899_SELOSCI (0x01 << 1)
+#define STB0899_OFFST_SELOSCI 1
+#define STB0899_WIDTH_SELOSCI 1
+
+#define STB0899_FILTCTRL 0xf1b7
+#define STB0899_SYSCTRL 0xf1b8
+
+#define STB0899_STOPCLK1 0xf1c2
+#define STB0899_STOP_CKINTBUF108 (0x01 << 7)
+#define STB0899_OFFST_STOP_CKINTBUF108 7
+#define STB0899_WIDTH_STOP_CKINTBUF108 1
+#define STB0899_STOP_CKINTBUF216 (0x01 << 6)
+#define STB0899_OFFST_STOP_CKINTBUF216 6
+#define STB0899_WIDTH_STOP_CKINTBUF216 1
+#define STB0899_STOP_CHK8PSK (0x01 << 5)
+#define STB0899_OFFST_STOP_CHK8PSK 5
+#define STB0899_WIDTH_STOP_CHK8PSK 1
+#define STB0899_STOP_CKFEC108 (0x01 << 4)
+#define STB0899_OFFST_STOP_CKFEC108 4
+#define STB0899_WIDTH_STOP_CKFEC108 1
+#define STB0899_STOP_CKFEC216 (0x01 << 3)
+#define STB0899_OFFST_STOP_CKFEC216 3
+#define STB0899_WIDTH_STOP_CKFEC216 1
+#define STB0899_STOP_CKCORE216 (0x01 << 2)
+#define STB0899_OFFST_STOP_CKCORE216 2
+#define STB0899_WIDTH_STOP_CKCORE216 1
+#define STB0899_STOP_CKADCI108 (0x01 << 1)
+#define STB0899_OFFST_STOP_CKADCI108 1
+#define STB0899_WIDTH_STOP_CKADCI108 1
+#define STB0899_STOP_INVCKADCI108 (0x01 << 0)
+#define STB0899_OFFST_STOP_INVCKADCI108 0
+#define STB0899_WIDTH_STOP_INVCKADCI108 1
+
+#define STB0899_STOPCLK2 0xf1c3
+#define STB0899_STOP_CKS2DMD108 (0x01 << 2)
+#define STB0899_OFFST_STOP_CKS2DMD108 2
+#define STB0899_WIDTH_STOP_CKS2DMD108 1
+#define STB0899_STOP_CKPKDLIN108 (0x01 << 1)
+#define STB0899_OFFST_STOP_CKPKDLIN108 1
+#define STB0899_WIDTH_STOP_CKPKDLIN108 1
+#define STB0899_STOP_CKPKDLIN216 (0x01 << 0)
+#define STB0899_OFFST_STOP_CKPKDLIN216 0
+#define STB0899_WIDTH_STOP_CKPKDLIN216 1
+
+#define STB0899_TSTTNR1 0xf1e0
+#define STB0899_BYPASS_ADC (0x01 << 7)
+#define STB0899_OFFST_BYPASS_ADC 7
+#define STB0899_WIDTH_BYPASS_ADC 1
+#define STB0899_INVADCICKOUT (0x01 << 6)
+#define STB0899_OFFST_INVADCICKOUT 6
+#define STB0899_WIDTH_INVADCICKOUT 1
+#define STB0899_ADCTEST_VOLTAGE (0x03 << 4)
+#define STB0899_OFFST_ADCTEST_VOLTAGE 4
+#define STB0899_WIDTH_ADCTEST_VOLTAGE 1
+#define STB0899_ADC_RESET (0x01 << 3)
+#define STB0899_OFFST_ADC_RESET 3
+#define STB0899_WIDTH_ADC_RESET 1
+#define STB0899_TSTTNR1_2 (0x01 << 2)
+#define STB0899_OFFST_TSTTNR1_2 2
+#define STB0899_WIDTH_TSTTNR1_2 1
+#define STB0899_ADCPON (0x01 << 1)
+#define STB0899_OFFST_ADCPON 1
+#define STB0899_WIDTH_ADCPON 1
+#define STB0899_ADCIN_MODE (0x01 << 0)
+#define STB0899_OFFST_ADCIN_MODE 0
+#define STB0899_WIDTH_ADCIN_MODE 1
+
+#define STB0899_TSTTNR2 0xf1e1
+#define STB0899_TSTTNR2_7 (0x01 << 7)
+#define STB0899_OFFST_TSTTNR2_7 7
+#define STB0899_WIDTH_TSTTNR2_7 1
+#define STB0899_NOT_DISRX_WIRED (0x01 << 6)
+#define STB0899_OFFST_NOT_DISRX_WIRED 6
+#define STB0899_WIDTH_NOT_DISRX_WIRED 1
+#define STB0899_DISEQC_DCURRENT (0x01 << 5)
+#define STB0899_OFFST_DISEQC_DCURRENT 5
+#define STB0899_WIDTH_DISEQC_DCURRENT 1
+#define STB0899_DISEQC_ZCURRENT (0x01 << 4)
+#define STB0899_OFFST_DISEQC_ZCURRENT 4
+#define STB0899_WIDTH_DISEQC_ZCURRENT 1
+#define STB0899_DISEQC_SINC_SOURCE (0x03 << 2)
+#define STB0899_OFFST_DISEQC_SINC_SOURCE 2
+#define STB0899_WIDTH_DISEQC_SINC_SOURCE 2
+#define STB0899_SELIQSRC (0x03 << 0)
+#define STB0899_OFFST_SELIQSRC 0
+#define STB0899_WIDTH_SELIQSRC 2
+
+#define STB0899_TSTTNR3 0xf1e2
+
+#define STB0899_I2CCFG 0xf129
+#define STB0899_I2CCFGRSVD (0x0f << 4)
+#define STB0899_OFFST_I2CCFGRSVD 4
+#define STB0899_WIDTH_I2CCFGRSVD 4
+#define STB0899_I2CFASTMODE (0x01 << 3)
+#define STB0899_OFFST_I2CFASTMODE 3
+#define STB0899_WIDTH_I2CFASTMODE 1
+#define STB0899_STATUSWR (0x01 << 2)
+#define STB0899_OFFST_STATUSWR 2
+#define STB0899_WIDTH_STATUSWR 1
+#define STB0899_I2CADDRINC (0x03 << 0)
+#define STB0899_OFFST_I2CADDRINC 0
+#define STB0899_WIDTH_I2CADDRINC 2
+
+#define STB0899_I2CRPT 0xf12a
+#define STB0899_I2CTON (0x01 << 7)
+#define STB0899_OFFST_I2CTON 7
+#define STB0899_WIDTH_I2CTON 1
+#define STB0899_ENARPTLEVEL (0x01 << 6)
+#define STB0899_OFFST_ENARPTLEVEL 6
+#define STB0899_WIDTH_ENARPTLEVEL 2
+#define STB0899_SCLTDELAY (0x01 << 3)
+#define STB0899_OFFST_SCLTDELAY 3
+#define STB0899_WIDTH_SCLTDELAY 1
+#define STB0899_STOPENA (0x01 << 2)
+#define STB0899_OFFST_STOPENA 2
+#define STB0899_WIDTH_STOPENA 1
+#define STB0899_STOPSDAT2SDA (0x01 << 1)
+#define STB0899_OFFST_STOPSDAT2SDA 1
+#define STB0899_WIDTH_STOPSDAT2SDA 1
+
+#define STB0899_IOPVALUE8 0xf136
+#define STB0899_IOPVALUE7 0xf137
+#define STB0899_IOPVALUE6 0xf138
+#define STB0899_IOPVALUE5 0xf139
+#define STB0899_IOPVALUE4 0xf13a
+#define STB0899_IOPVALUE3 0xf13b
+#define STB0899_IOPVALUE2 0xf13c
+#define STB0899_IOPVALUE1 0xf13d
+#define STB0899_IOPVALUE0 0xf13e
+
+#define STB0899_GPIO00CFG 0xf140
+
+#define STB0899_GPIO01CFG 0xf141
+#define STB0899_GPIO02CFG 0xf142
+#define STB0899_GPIO03CFG 0xf143
+#define STB0899_GPIO04CFG 0xf144
+#define STB0899_GPIO05CFG 0xf145
+#define STB0899_GPIO06CFG 0xf146
+#define STB0899_GPIO07CFG 0xf147
+#define STB0899_GPIO08CFG 0xf148
+#define STB0899_GPIO09CFG 0xf149
+#define STB0899_GPIO10CFG 0xf14a
+#define STB0899_GPIO11CFG 0xf14b
+#define STB0899_GPIO12CFG 0xf14c
+#define STB0899_GPIO13CFG 0xf14d
+#define STB0899_GPIO14CFG 0xf14e
+#define STB0899_GPIO15CFG 0xf14f
+#define STB0899_GPIO16CFG 0xf150
+#define STB0899_GPIO17CFG 0xf151
+#define STB0899_GPIO18CFG 0xf152
+#define STB0899_GPIO19CFG 0xf153
+#define STB0899_GPIO20CFG 0xf154
+
+#define STB0899_SDATCFG 0xf155
+#define STB0899_SCLTCFG 0xf156
+#define STB0899_AGCRFCFG 0xf157
+#define STB0899_GPIO22 0xf158 /* AGCBB2CFG */
+#define STB0899_GPIO21 0xf159 /* AGCBB1CFG */
+#define STB0899_DIRCLKCFG 0xf15a
+#define STB0899_CLKOUT27CFG 0xf15b
+#define STB0899_STDBYCFG 0xf15c
+#define STB0899_CS0CFG 0xf15d
+#define STB0899_CS1CFG 0xf15e
+#define STB0899_DISEQCOCFG 0xf15f
+
+#define STB0899_GPIO32CFG 0xf160
+#define STB0899_GPIO33CFG 0xf161
+#define STB0899_GPIO34CFG 0xf162
+#define STB0899_GPIO35CFG 0xf163
+#define STB0899_GPIO36CFG 0xf164
+#define STB0899_GPIO37CFG 0xf165
+#define STB0899_GPIO38CFG 0xf166
+#define STB0899_GPIO39CFG 0xf167
+
+#define STB0899_IRQSTATUS_3 0xf120
+#define STB0899_IRQSTATUS_2 0xf121
+#define STB0899_IRQSTATUS_1 0xf122
+#define STB0899_IRQSTATUS_0 0xf123
+
+#define STB0899_IRQMSK_3 0xf124
+#define STB0899_IRQMSK_2 0xf125
+#define STB0899_IRQMSK_1 0xf126
+#define STB0899_IRQMSK_0 0xf127
+
+#define STB0899_IRQCFG 0xf128
+
+#define STB0899_GHOSTREG 0xf000
+
+#define STB0899_S2DEMOD 0xf3fc
+#define STB0899_S2FEC 0xfafc
+
+
+#endif
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
new file mode 100644
index 000000000000..ff39275ab49c
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -0,0 +1,545 @@
+/*
+ STB6100 Silicon Tuner
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include "dvb_frontend.h"
+#include "stb6100.h"
+
+static unsigned int verbose;
+module_param(verbose, int, 0644);
+
+
+#define FE_ERROR 0
+#define FE_NOTICE 1
+#define FE_INFO 2
+#define FE_DEBUG 3
+
+#define dprintk(x, y, z, format, arg...) do { \
+ if (z) { \
+ if ((x > FE_ERROR) && (x > y)) \
+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
+ else if ((x > FE_NOTICE) && (x > y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
+ else if ((x > FE_INFO) && (x > y)) \
+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+ else if ((x > FE_DEBUG) && (x > y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
+ } else { \
+ if (x > y) \
+ printk(format, ##arg); \
+ } \
+} while(0)
+
+struct stb6100_lkup {
+ u32 val_low;
+ u32 val_high;
+ u8 reg;
+};
+
+static int stb6100_release(struct dvb_frontend *fe);
+
+static const struct stb6100_lkup lkup[] = {
+ { 0, 950000, 0x0a },
+ { 950000, 1000000, 0x0a },
+ { 1000000, 1075000, 0x0c },
+ { 1075000, 1200000, 0x00 },
+ { 1200000, 1300000, 0x01 },
+ { 1300000, 1370000, 0x02 },
+ { 1370000, 1470000, 0x04 },
+ { 1470000, 1530000, 0x05 },
+ { 1530000, 1650000, 0x06 },
+ { 1650000, 1800000, 0x08 },
+ { 1800000, 1950000, 0x0a },
+ { 1950000, 2150000, 0x0c },
+ { 2150000, 9999999, 0x0c },
+ { 0, 0, 0x00 }
+};
+
+/* Register names for easy debugging. */
+static const char *stb6100_regnames[] = {
+ [STB6100_LD] = "LD",
+ [STB6100_VCO] = "VCO",
+ [STB6100_NI] = "NI",
+ [STB6100_NF_LSB] = "NF",
+ [STB6100_K] = "K",
+ [STB6100_G] = "G",
+ [STB6100_F] = "F",
+ [STB6100_DLB] = "DLB",
+ [STB6100_TEST1] = "TEST1",
+ [STB6100_FCCK] = "FCCK",
+ [STB6100_LPEN] = "LPEN",
+ [STB6100_TEST3] = "TEST3",
+};
+
+/* Template for normalisation, i.e. setting unused or undocumented
+ * bits as required according to the documentation.
+ */
+struct stb6100_regmask {
+ u8 mask;
+ u8 set;
+};
+
+static const struct stb6100_regmask stb6100_template[] = {
+ [STB6100_LD] = { 0xff, 0x00 },
+ [STB6100_VCO] = { 0xff, 0x00 },
+ [STB6100_NI] = { 0xff, 0x00 },
+ [STB6100_NF_LSB] = { 0xff, 0x00 },
+ [STB6100_K] = { 0xc7, 0x38 },
+ [STB6100_G] = { 0xef, 0x10 },
+ [STB6100_F] = { 0x1f, 0xc0 },
+ [STB6100_DLB] = { 0x38, 0xc4 },
+ [STB6100_TEST1] = { 0x00, 0x8f },
+ [STB6100_FCCK] = { 0x40, 0x0d },
+ [STB6100_LPEN] = { 0xf0, 0x0b },
+ [STB6100_TEST3] = { 0x00, 0xde },
+};
+
+static void stb6100_normalise_regs(u8 regs[])
+{
+ int i;
+
+ for (i = 0; i < STB6100_NUMREGS; i++)
+ regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set;
+}
+
+static int stb6100_read_regs(struct stb6100_state *state, u8 regs[])
+{
+ int rc;
+ struct i2c_msg msg = {
+ .addr = state->config->tuner_address,
+ .flags = I2C_M_RD,
+ .buf = regs,
+ .len = STB6100_NUMREGS
+ };
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+ if (unlikely(rc != 1)) {
+ dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]",
+ state->config->tuner_address, rc);
+
+ return -EREMOTEIO;
+ }
+ if (unlikely(verbose > FE_DEBUG)) {
+ int i;
+
+ dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
+ for (i = 0; i < STB6100_NUMREGS; i++)
+ dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[i], regs[i]);
+ }
+ return 0;
+}
+
+static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
+{
+ u8 regs[STB6100_NUMREGS];
+ int rc;
+
+ if (unlikely(reg >= STB6100_NUMREGS)) {
+ dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
+ return -EINVAL;
+ }
+ if ((rc = stb6100_read_regs(state, regs)) < 0)
+ return rc;
+ return (unsigned int)regs[reg];
+}
+
+static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
+{
+ int rc;
+ u8 cmdbuf[len + 1];
+ struct i2c_msg msg = {
+ .addr = state->config->tuner_address,
+ .flags = 0,
+ .buf = cmdbuf,
+ .len = len + 1
+ };
+
+ if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) {
+ dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d",
+ start, len);
+ return -EINVAL;
+ }
+ memcpy(&cmdbuf[1], buf, len);
+ cmdbuf[0] = start;
+
+ if (unlikely(verbose > FE_DEBUG)) {
+ int i;
+
+ dprintk(verbose, FE_DEBUG, 1, " Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len);
+ for (i = 0; i < len; i++)
+ dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[start + i], buf[i]);
+ }
+ rc = i2c_transfer(state->i2c, &msg, 1);
+ if (unlikely(rc != 1)) {
+ dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]",
+ (unsigned int)state->config->tuner_address, start, len, rc);
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
+{
+ if (unlikely(reg >= STB6100_NUMREGS)) {
+ dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
+ return -EREMOTEIO;
+ }
+ data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
+ return stb6100_write_reg_range(state, &data, reg, 1);
+}
+
+static int stb6100_write_regs(struct stb6100_state *state, u8 regs[])
+{
+ stb6100_normalise_regs(regs);
+ return stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 1);
+}
+
+static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
+{
+ int rc;
+ struct stb6100_state *state = fe->tuner_priv;
+
+ if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0)
+ return rc;
+
+ return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
+}
+
+static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ int rc;
+ u8 f;
+ struct stb6100_state *state = fe->tuner_priv;
+
+ if ((rc = stb6100_read_reg(state, STB6100_F)) < 0)
+ return rc;
+ f = rc & STB6100_F_F;
+
+ state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */
+
+ *bandwidth = state->bandwidth = state->status.bandwidth * 1000;
+ dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth);
+ return 0;
+}
+
+static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ u32 tmp;
+ int rc;
+ struct stb6100_state *state = fe->tuner_priv;
+
+ dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth);
+
+ bandwidth /= 2; /* ZIF */
+
+ if (bandwidth >= 36000000) /* F[4:0] BW/2 max =31+5=36 mhz for F=31 */
+ tmp = 31;
+ else if (bandwidth <= 5000000) /* bw/2 min = 5Mhz for F=0 */
+ tmp = 0;
+ else /* if 5 < bw/2 < 36 */
+ tmp = (bandwidth + 500000) / 1000000 - 5;
+
+ /* Turn on LPF bandwidth setting clock control,
+ * set bandwidth, wait 10ms, turn off.
+ */
+ if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0)
+ return rc;
+ if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0)
+ return rc;
+ msleep(1);
+ if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0)
+ return rc;
+
+ return 0;
+}
+
+static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ int rc;
+ u32 nint, nfrac, fvco;
+ int psd2, odiv;
+ struct stb6100_state *state = fe->tuner_priv;
+ u8 regs[STB6100_NUMREGS];
+
+ if ((rc = stb6100_read_regs(state, regs)) < 0)
+ return rc;
+
+ odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
+ psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT;
+ nint = regs[STB6100_NI];
+ nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB];
+ fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2);
+ *frequency = state->frequency = fvco >> (odiv + 1);
+
+ dprintk(verbose, FE_DEBUG, 1,
+ "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u",
+ state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac);
+ return 0;
+}
+
+
+static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ int rc;
+ const struct stb6100_lkup *ptr;
+ struct stb6100_state *state = fe->tuner_priv;
+ struct dvb_frontend_parameters p;
+
+ u32 srate = 0, fvco, nint, nfrac;
+ u8 regs[STB6100_NUMREGS];
+ u8 g, psd2, odiv;
+
+ if ((rc = stb6100_read_regs(state, regs)) < 0)
+ return rc;
+
+ if (fe->ops.get_frontend) {
+ dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
+ fe->ops.get_frontend(fe, &p);
+ }
+ srate = p.u.qpsk.symbol_rate;
+
+ regs[STB6100_DLB] = 0xdc;
+ /* Disable LPEN */
+ regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */
+
+ if ((rc = stb6100_write_regs(state, regs)) < 0)
+ return rc;
+
+ /* Baseband gain. */
+ if (srate >= 15000000)
+ g = 9; // +4 dB
+ else if (srate >= 5000000)
+ g = 11; // +8 dB
+ else
+ g = 14; // +14 dB
+
+ regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g;
+ regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
+ regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
+
+ /* VCO divide ratio (LO divide ratio, VCO prescaler enable). */
+ if (frequency <= 1075000)
+ odiv = 1;
+ else
+ odiv = 0;
+ regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT);
+
+ if ((frequency > 1075000) && (frequency <= 1325000))
+ psd2 = 0;
+ else
+ psd2 = 1;
+ regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
+
+ /* OSM */
+ for (ptr = lkup;
+ (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
+ ptr++);
+ if (ptr->val_high == 0) {
+ printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
+ return -EINVAL;
+ }
+ regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
+
+ /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */
+ fvco = frequency << (1 + odiv);
+ /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
+ nint = fvco / (state->reference << psd2);
+ /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
+ nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference;
+ dprintk(verbose, FE_DEBUG, 1,
+ "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
+ frequency, srate, (unsigned int)g, (unsigned int)odiv,
+ (unsigned int)psd2, state->reference,
+ ptr->reg, fvco, nint, nfrac);
+ regs[STB6100_NI] = nint;
+ regs[STB6100_NF_LSB] = nfrac;
+ regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
+ regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */
+ regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */
+ regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */
+ regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */
+ /* Power up. */
+ regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN;
+
+ msleep(2);
+ if ((rc = stb6100_write_regs(state, regs)) < 0)
+ return rc;
+
+ msleep(2);
+ regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */
+ if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0)
+ return rc;
+
+ regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */
+ if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
+ return rc;
+
+ msleep(10); /* wait for LO to lock */
+ regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */
+ regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */
+ if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
+ return rc;
+ regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */
+ stb6100_normalise_regs(regs);
+ if ((rc = stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 3)) < 0)
+ return rc;
+
+ msleep(100);
+
+ return 0;
+}
+
+static int stb6100_sleep(struct dvb_frontend *fe)
+{
+ /* TODO: power down */
+ return 0;
+}
+
+static int stb6100_init(struct dvb_frontend *fe)
+{
+ struct stb6100_state *state = fe->tuner_priv;
+ struct tuner_state *status = &state->status;
+
+ status->tunerstep = 125000;
+ status->ifreq = 0;
+ status->refclock = 27000000; /* Hz */
+ status->iqsense = 1;
+ status->bandwidth = 36000; /* kHz */
+ state->bandwidth = status->bandwidth * 1000; /* MHz */
+ state->reference = status->refclock / 1000; /* kHz */
+
+ /* Set default bandwidth. */
+ return stb6100_set_bandwidth(fe, status->bandwidth);
+}
+
+static int stb6100_get_state(struct dvb_frontend *fe,
+ enum tuner_param param,
+ struct tuner_state *state)
+{
+ switch (param) {
+ case DVBFE_TUNER_FREQUENCY:
+ stb6100_get_frequency(fe, &state->frequency);
+ break;
+ case DVBFE_TUNER_TUNERSTEP:
+ break;
+ case DVBFE_TUNER_IFFREQ:
+ break;
+ case DVBFE_TUNER_BANDWIDTH:
+ stb6100_get_bandwidth(fe, &state->bandwidth);
+ break;
+ case DVBFE_TUNER_REFCLOCK:
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int stb6100_set_state(struct dvb_frontend *fe,
+ enum tuner_param param,
+ struct tuner_state *state)
+{
+ struct stb6100_state *tstate = fe->tuner_priv;
+
+ switch (param) {
+ case DVBFE_TUNER_FREQUENCY:
+ stb6100_set_frequency(fe, state->frequency);
+ tstate->frequency = state->frequency;
+ break;
+ case DVBFE_TUNER_TUNERSTEP:
+ break;
+ case DVBFE_TUNER_IFFREQ:
+ break;
+ case DVBFE_TUNER_BANDWIDTH:
+ stb6100_set_bandwidth(fe, state->bandwidth);
+ tstate->bandwidth = state->bandwidth;
+ break;
+ case DVBFE_TUNER_REFCLOCK:
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct dvb_tuner_ops stb6100_ops = {
+ .info = {
+ .name = "STB6100 Silicon Tuner",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 0,
+ },
+
+ .init = stb6100_init,
+ .sleep = stb6100_sleep,
+ .get_status = stb6100_get_status,
+ .get_state = stb6100_get_state,
+ .set_state = stb6100_set_state,
+ .release = stb6100_release
+};
+
+struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
+ struct stb6100_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct stb6100_state *state = NULL;
+
+ state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ state->config = config;
+ state->i2c = i2c;
+ state->frontend = fe;
+ state->reference = config->refclock / 1000; /* kHz */
+ fe->tuner_priv = state;
+ fe->ops.tuner_ops = stb6100_ops;
+
+ printk("%s: Attaching STB6100 \n", __func__);
+ return fe;
+
+error:
+ kfree(state);
+ return NULL;
+}
+
+static int stb6100_release(struct dvb_frontend *fe)
+{
+ struct stb6100_state *state = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(state);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(stb6100_attach);
+MODULE_PARM_DESC(verbose, "Set Verbosity level");
+
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("STB6100 Silicon tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h
new file mode 100644
index 000000000000..395d056599a6
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100.h
@@ -0,0 +1,115 @@
+/*
+ STB6100 Silicon Tuner
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __STB_6100_REG_H
+#define __STB_6100_REG_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+#define STB6100_LD 0x00
+#define STB6100_LD_LOCK (1 << 0)
+
+#define STB6100_VCO 0x01
+#define STB6100_VCO_OSCH (0x01 << 7)
+#define STB6100_VCO_OSCH_SHIFT 7
+#define STB6100_VCO_OCK (0x03 << 5)
+#define STB6100_VCO_OCK_SHIFT 5
+#define STB6100_VCO_ODIV (0x01 << 4)
+#define STB6100_VCO_ODIV_SHIFT 4
+#define STB6100_VCO_OSM (0x0f << 0)
+
+#define STB6100_NI 0x02
+#define STB6100_NF_LSB 0x03
+
+#define STB6100_K 0x04
+#define STB6100_K_PSD2 (0x01 << 2)
+#define STB6100_K_PSD2_SHIFT 2
+#define STB6100_K_NF_MSB (0x03 << 0)
+
+#define STB6100_G 0x05
+#define STB6100_G_G (0x0f << 0)
+#define STB6100_G_GCT (0x07 << 5)
+
+#define STB6100_F 0x06
+#define STB6100_F_F (0x1f << 0)
+
+#define STB6100_DLB 0x07
+
+#define STB6100_TEST1 0x08
+
+#define STB6100_FCCK 0x09
+#define STB6100_FCCK_FCCK (0x01 << 6)
+
+#define STB6100_LPEN 0x0a
+#define STB6100_LPEN_LPEN (0x01 << 4)
+#define STB6100_LPEN_SYNP (0x01 << 5)
+#define STB6100_LPEN_OSCP (0x01 << 6)
+#define STB6100_LPEN_BEN (0x01 << 7)
+
+#define STB6100_TEST3 0x0b
+
+#define STB6100_NUMREGS 0x0c
+
+
+#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \
+ ((y <= val) && (val <= x)) ? 1 : 0)
+
+#define CHKRANGE(val, x, y) (((val >= x) && (val < y)) ? 1 : 0)
+
+struct stb6100_config {
+ u8 tuner_address;
+ u32 refclock;
+};
+
+struct stb6100_state {
+ struct i2c_adapter *i2c;
+
+ const struct stb6100_config *config;
+ struct dvb_tuner_ops ops;
+ struct dvb_frontend *frontend;
+ struct tuner_state status;
+
+ u32 frequency;
+ u32 srate;
+ u32 bandwidth;
+ u32 reference;
+};
+
+#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
+ struct stb6100_config *config,
+ struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
+ struct stb6100_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+#endif //CONFIG_DVB_STB6100
+
+#endif
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
new file mode 100644
index 000000000000..d3133405dc03
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -0,0 +1,108 @@
+/*
+ STB6100 Silicon Tuner
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ Copyright (C) ST Microelectronics
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ struct tuner_state t_state;
+ int err = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->get_state) {
+ if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ *frequency = t_state.frequency;
+ printk("%s: Frequency=%d\n", __func__, t_state.frequency);
+ }
+ return 0;
+}
+
+static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ struct tuner_state t_state;
+ int err = 0;
+
+ t_state.frequency = frequency;
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->set_state) {
+ if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ }
+ printk("%s: Frequency=%d\n", __func__, t_state.frequency);
+ return 0;
+}
+
+static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
+ struct tuner_state t_state;
+ int err = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->get_state) {
+ if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ *bandwidth = t_state.bandwidth;
+ }
+ printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
+ return 0;
+}
+
+static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ struct tuner_state t_state;
+ int err = 0;
+
+ t_state.bandwidth = bandwidth;
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->set_state) {
+ if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ }
+ printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
+ return 0;
+}
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
new file mode 100644
index 000000000000..b6d177799104
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -0,0 +1,230 @@
+/*
+ TDA8261 8PSK/QPSK tuner driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "dvb_frontend.h"
+#include "tda8261.h"
+
+struct tda8261_state {
+ struct dvb_frontend *fe;
+ struct i2c_adapter *i2c;
+ const struct tda8261_config *config;
+
+ /* state cache */
+ u32 frequency;
+ u32 bandwidth;
+};
+
+static int tda8261_read(struct tda8261_state *state, u8 *buf)
+{
+ const struct tda8261_config *config = state->config;
+ int err = 0;
+ struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 };
+
+ if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
+ printk("%s: read error, err=%d\n", __func__, err);
+
+ return err;
+}
+
+static int tda8261_write(struct tda8261_state *state, u8 *buf)
+{
+ const struct tda8261_config *config = state->config;
+ int err = 0;
+ struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
+
+ if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
+ printk("%s: write error, err=%d\n", __func__, err);
+
+ return err;
+}
+
+static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
+{
+ struct tda8261_state *state = fe->tuner_priv;
+ u8 result = 0;
+ int err = 0;
+
+ *status = 0;
+
+ if ((err = tda8261_read(state, &result)) < 0) {
+ printk("%s: I/O Error\n", __func__);
+ return err;
+ }
+ if ((result >> 6) & 0x01) {
+ printk("%s: Tuner Phase Locked\n", __func__);
+ *status = 1;
+ }
+
+ return err;
+}
+
+static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */
+static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 };
+
+static int tda8261_get_state(struct dvb_frontend *fe,
+ enum tuner_param param,
+ struct tuner_state *tstate)
+{
+ struct tda8261_state *state = fe->tuner_priv;
+ int err = 0;
+
+ switch (param) {
+ case DVBFE_TUNER_FREQUENCY:
+ tstate->frequency = state->frequency;
+ break;
+ case DVBFE_TUNER_BANDWIDTH:
+ tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
+ break;
+ default:
+ printk("%s: Unknown parameter (param=%d)\n", __func__, param);
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int tda8261_set_state(struct dvb_frontend *fe,
+ enum tuner_param param,
+ struct tuner_state *tstate)
+{
+ struct tda8261_state *state = fe->tuner_priv;
+ const struct tda8261_config *config = state->config;
+ u32 frequency, N, status = 0;
+ u8 buf[4];
+ int err = 0;
+
+ if (param & DVBFE_TUNER_FREQUENCY) {
+ /**
+ * N = Max VCO Frequency / Channel Spacing
+ * Max VCO Frequency = VCO frequency + (channel spacing - 1)
+ * (to account for half channel spacing on either side)
+ */
+ frequency = tstate->frequency;
+ if ((frequency < 950000) || (frequency > 2150000)) {
+ printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
+ return -EINVAL;
+ }
+ N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
+ printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
+ __func__, config->step_size, div_tab[config->step_size], N, N);
+
+ buf[0] = (N >> 8) & 0xff;
+ buf[1] = N & 0xff;
+ buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
+
+ if (frequency < 1450000)
+ buf[3] = 0x00;
+ if (frequency < 2000000)
+ buf[3] = 0x40;
+ if (frequency < 2150000)
+ buf[3] = 0x80;
+
+ /* Set params */
+ if ((err = tda8261_write(state, buf)) < 0) {
+ printk("%s: I/O Error\n", __func__);
+ return err;
+ }
+ /* sleep for some time */
+ printk("%s: Waiting to Phase LOCK\n", __func__);
+ msleep(20);
+ /* check status */
+ if ((err = tda8261_get_status(fe, &status)) < 0) {
+ printk("%s: I/O Error\n", __func__);
+ return err;
+ }
+ if (status == 1) {
+ printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
+ state->frequency = frequency; /* cache successful state */
+ } else {
+ printk("%s: No Phase lock: status=%d\n", __func__, status);
+ }
+ } else {
+ printk("%s: Unknown parameter (param=%d)\n", __func__, param);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int tda8261_release(struct dvb_frontend *fe)
+{
+ struct tda8261_state *state = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(state);
+ return 0;
+}
+
+static struct dvb_tuner_ops tda8261_ops = {
+
+ .info = {
+ .name = "TDA8261",
+// .tuner_name = NULL,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 0
+ },
+
+ .set_state = tda8261_set_state,
+ .get_state = tda8261_get_state,
+ .get_status = tda8261_get_status,
+ .release = tda8261_release
+};
+
+struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
+ const struct tda8261_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct tda8261_state *state = NULL;
+
+ if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL)
+ goto exit;
+
+ state->config = config;
+ state->i2c = i2c;
+ state->fe = fe;
+ fe->tuner_priv = state;
+ fe->ops.tuner_ops = tda8261_ops;
+
+ fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size];
+// fe->ops.tuner_ops.tuner_name = &config->buf;
+
+// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
+// __func__, fe->ops.tuner_ops.tuner_name);
+ printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
+
+ return fe;
+
+exit:
+ kfree(state);
+ return NULL;
+}
+
+EXPORT_SYMBOL(tda8261_attach);
+MODULE_PARM_DESC(verbose, "Set verbosity level");
+
+MODULE_AUTHOR("Manu Abraham");
+MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb/frontends/tda8261.h
new file mode 100644
index 000000000000..006e45351b94
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261.h
@@ -0,0 +1,55 @@
+/*
+ TDA8261 8PSK/QPSK tuner driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TDA8261_H
+#define __TDA8261_H
+
+enum tda8261_step {
+ TDA8261_STEP_2000 = 0, /* 2000 kHz */
+ TDA8261_STEP_1000, /* 1000 kHz */
+ TDA8261_STEP_500, /* 500 kHz */
+ TDA8261_STEP_250, /* 250 kHz */
+ TDA8261_STEP_125 /* 125 kHz */
+};
+
+struct tda8261_config {
+// u8 buf[16];
+ u8 addr;
+ enum tda8261_step step_size;
+};
+
+#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE))
+
+extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
+ const struct tda8261_config *config,
+ struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
+ const struct tda8261_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+#endif //CONFIG_DVB_TDA8261
+
+#endif// __TDA8261_H
diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb/frontends/tda8261_cfg.h
new file mode 100644
index 000000000000..1af1ee49b542
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261_cfg.h
@@ -0,0 +1,84 @@
+/*
+ TDA8261 8PSK/QPSK tuner driver
+ Copyright (C) Manu Abraham (abraham.manu@gmail.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ struct tuner_state t_state;
+ int err = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->get_state) {
+ if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ *frequency = t_state.frequency;
+ printk("%s: Frequency=%d\n", __func__, t_state.frequency);
+ }
+ return 0;
+}
+
+static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ struct tuner_state t_state;
+ int err = 0;
+
+ t_state.frequency = frequency;
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->set_state) {
+ if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ }
+ printk("%s: Frequency=%d\n", __func__, t_state.frequency);
+ return 0;
+}
+
+static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
+ struct tuner_state t_state;
+ int err = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+ if (tuner_ops->get_state) {
+ if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+ printk("%s: Invalid parameter\n", __func__);
+ return err;
+ }
+ *bandwidth = t_state.bandwidth;
+ }
+ printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
+ return 0;
+}
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 36a5a1c101d5..5506f80e180e 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -220,15 +220,18 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
/* These are extrapolated from the 7 and 8MHz values */
zl10353_single_write(fe, MCLK_RATIO, 0x97);
zl10353_single_write(fe, 0x64, 0x34);
+ zl10353_single_write(fe, 0xcc, 0xdd);
break;
case BANDWIDTH_7_MHZ:
zl10353_single_write(fe, MCLK_RATIO, 0x86);
zl10353_single_write(fe, 0x64, 0x35);
+ zl10353_single_write(fe, 0xcc, 0x73);
break;
case BANDWIDTH_8_MHZ:
default:
zl10353_single_write(fe, MCLK_RATIO, 0x75);
zl10353_single_write(fe, 0x64, 0x36);
+ zl10353_single_write(fe, 0xcc, 0x73);
}
zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 867027ceab3e..9e2ece9e4d2b 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -104,6 +104,8 @@ config DVB_BUDGET_CI
select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
+ select DVB_STB0899 if !DVB_FE_CUSTOMISE
+ select DVB_STB6100 if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
@@ -131,6 +133,8 @@ config DVB_BUDGET_AV
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ select DVB_STB0899 if !DVB_FE_CUSTOMISE
+ select DVB_TDA8261 if !DVB_FE_CUSTOMISE
select DVB_TUA6100 if !DVB_FE_CUSTOMISE
help
Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 1032ea77837e..f996cef79ec1 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -35,6 +35,11 @@
#include "budget.h"
#include "stv0299.h"
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+#include "tda8261.h"
+#include "tda8261_cfg.h"
#include "tda1002x.h"
#include "tda1004x.h"
#include "tua6100.h"
@@ -882,6 +887,281 @@ static struct stv0299_config philips_sd1878_config = {
.set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
};
+/* KNC1 DVB-S (STB0899) Inittab */
+static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
+
+ { STB0899_DEV_ID , 0x81 },
+ { STB0899_DISCNTRL1 , 0x32 },
+ { STB0899_DISCNTRL2 , 0x80 },
+ { STB0899_DISRX_ST0 , 0x04 },
+ { STB0899_DISRX_ST1 , 0x00 },
+ { STB0899_DISPARITY , 0x00 },
+ { STB0899_DISFIFO , 0x00 },
+ { STB0899_DISSTATUS , 0x20 },
+ { STB0899_DISF22 , 0x8c },
+ { STB0899_DISF22RX , 0x9a },
+ { STB0899_SYSREG , 0x0b },
+ { STB0899_ACRPRESC , 0x11 },
+ { STB0899_ACRDIV1 , 0x0a },
+ { STB0899_ACRDIV2 , 0x05 },
+ { STB0899_DACR1 , 0x00 },
+ { STB0899_DACR2 , 0x00 },
+ { STB0899_OUTCFG , 0x00 },
+ { STB0899_MODECFG , 0x00 },
+ { STB0899_IRQSTATUS_3 , 0x30 },
+ { STB0899_IRQSTATUS_2 , 0x00 },
+ { STB0899_IRQSTATUS_1 , 0x00 },
+ { STB0899_IRQSTATUS_0 , 0x00 },
+ { STB0899_IRQMSK_3 , 0xf3 },
+ { STB0899_IRQMSK_2 , 0xfc },
+ { STB0899_IRQMSK_1 , 0xff },
+ { STB0899_IRQMSK_0 , 0xff },
+ { STB0899_IRQCFG , 0x00 },
+ { STB0899_I2CCFG , 0x88 },
+ { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */
+ { STB0899_IOPVALUE5 , 0x00 },
+ { STB0899_IOPVALUE4 , 0x20 },
+ { STB0899_IOPVALUE3 , 0xc9 },
+ { STB0899_IOPVALUE2 , 0x90 },
+ { STB0899_IOPVALUE1 , 0x40 },
+ { STB0899_IOPVALUE0 , 0x00 },
+ { STB0899_GPIO00CFG , 0x82 },
+ { STB0899_GPIO01CFG , 0x82 },
+ { STB0899_GPIO02CFG , 0x82 },
+ { STB0899_GPIO03CFG , 0x82 },
+ { STB0899_GPIO04CFG , 0x82 },
+ { STB0899_GPIO05CFG , 0x82 },
+ { STB0899_GPIO06CFG , 0x82 },
+ { STB0899_GPIO07CFG , 0x82 },
+ { STB0899_GPIO08CFG , 0x82 },
+ { STB0899_GPIO09CFG , 0x82 },
+ { STB0899_GPIO10CFG , 0x82 },
+ { STB0899_GPIO11CFG , 0x82 },
+ { STB0899_GPIO12CFG , 0x82 },
+ { STB0899_GPIO13CFG , 0x82 },
+ { STB0899_GPIO14CFG , 0x82 },
+ { STB0899_GPIO15CFG , 0x82 },
+ { STB0899_GPIO16CFG , 0x82 },
+ { STB0899_GPIO17CFG , 0x82 },
+ { STB0899_GPIO18CFG , 0x82 },
+ { STB0899_GPIO19CFG , 0x82 },
+ { STB0899_GPIO20CFG , 0x82 },
+ { STB0899_SDATCFG , 0xb8 },
+ { STB0899_SCLTCFG , 0xba },
+ { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */
+ { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
+ { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
+ { STB0899_DIRCLKCFG , 0x82 },
+ { STB0899_CLKOUT27CFG , 0x7e },
+ { STB0899_STDBYCFG , 0x82 },
+ { STB0899_CS0CFG , 0x82 },
+ { STB0899_CS1CFG , 0x82 },
+ { STB0899_DISEQCOCFG , 0x20 },
+ { STB0899_GPIO32CFG , 0x82 },
+ { STB0899_GPIO33CFG , 0x82 },
+ { STB0899_GPIO34CFG , 0x82 },
+ { STB0899_GPIO35CFG , 0x82 },
+ { STB0899_GPIO36CFG , 0x82 },
+ { STB0899_GPIO37CFG , 0x82 },
+ { STB0899_GPIO38CFG , 0x82 },
+ { STB0899_GPIO39CFG , 0x82 },
+ { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+ { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+ { STB0899_FILTCTRL , 0x00 },
+ { STB0899_SYSCTRL , 0x00 },
+ { STB0899_STOPCLK1 , 0x20 },
+ { STB0899_STOPCLK2 , 0x00 },
+ { STB0899_INTBUFSTATUS , 0x00 },
+ { STB0899_INTBUFCTRL , 0x0a },
+ { 0xffff , 0xff },
+};
+
+static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
+ { STB0899_DEMOD , 0x00 },
+ { STB0899_RCOMPC , 0xc9 },
+ { STB0899_AGC1CN , 0x41 },
+ { STB0899_AGC1REF , 0x08 },
+ { STB0899_RTC , 0x7a },
+ { STB0899_TMGCFG , 0x4e },
+ { STB0899_AGC2REF , 0x33 },
+ { STB0899_TLSR , 0x84 },
+ { STB0899_CFD , 0xee },
+ { STB0899_ACLC , 0x87 },
+ { STB0899_BCLC , 0x94 },
+ { STB0899_EQON , 0x41 },
+ { STB0899_LDT , 0xdd },
+ { STB0899_LDT2 , 0xc9 },
+ { STB0899_EQUALREF , 0xb4 },
+ { STB0899_TMGRAMP , 0x10 },
+ { STB0899_TMGTHD , 0x30 },
+ { STB0899_IDCCOMP , 0xfb },
+ { STB0899_QDCCOMP , 0x03 },
+ { STB0899_POWERI , 0x3b },
+ { STB0899_POWERQ , 0x3d },
+ { STB0899_RCOMP , 0x81 },
+ { STB0899_AGCIQIN , 0x80 },
+ { STB0899_AGC2I1 , 0x04 },
+ { STB0899_AGC2I2 , 0xf5 },
+ { STB0899_TLIR , 0x25 },
+ { STB0899_RTF , 0x80 },
+ { STB0899_DSTATUS , 0x00 },
+ { STB0899_LDI , 0xca },
+ { STB0899_CFRM , 0xf1 },
+ { STB0899_CFRL , 0xf3 },
+ { STB0899_NIRM , 0x2a },
+ { STB0899_NIRL , 0x05 },
+ { STB0899_ISYMB , 0x17 },
+ { STB0899_QSYMB , 0xfa },
+ { STB0899_SFRH , 0x2f },
+ { STB0899_SFRM , 0x68 },
+ { STB0899_SFRL , 0x40 },
+ { STB0899_SFRUPH , 0x2f },
+ { STB0899_SFRUPM , 0x68 },
+ { STB0899_SFRUPL , 0x40 },
+ { STB0899_EQUAI1 , 0xfd },
+ { STB0899_EQUAQ1 , 0x04 },
+ { STB0899_EQUAI2 , 0x0f },
+ { STB0899_EQUAQ2 , 0xff },
+ { STB0899_EQUAI3 , 0xdf },
+ { STB0899_EQUAQ3 , 0xfa },
+ { STB0899_EQUAI4 , 0x37 },
+ { STB0899_EQUAQ4 , 0x0d },
+ { STB0899_EQUAI5 , 0xbd },
+ { STB0899_EQUAQ5 , 0xf7 },
+ { STB0899_DSTATUS2 , 0x00 },
+ { STB0899_VSTATUS , 0x00 },
+ { STB0899_VERROR , 0xff },
+ { STB0899_IQSWAP , 0x2a },
+ { STB0899_ECNT1M , 0x00 },
+ { STB0899_ECNT1L , 0x00 },
+ { STB0899_ECNT2M , 0x00 },
+ { STB0899_ECNT2L , 0x00 },
+ { STB0899_ECNT3M , 0x00 },
+ { STB0899_ECNT3L , 0x00 },
+ { STB0899_FECAUTO1 , 0x06 },
+ { STB0899_FECM , 0x01 },
+ { STB0899_VTH12 , 0xf0 },
+ { STB0899_VTH23 , 0xa0 },
+ { STB0899_VTH34 , 0x78 },
+ { STB0899_VTH56 , 0x4e },
+ { STB0899_VTH67 , 0x48 },
+ { STB0899_VTH78 , 0x38 },
+ { STB0899_PRVIT , 0xff },
+ { STB0899_VITSYNC , 0x19 },
+ { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+ { STB0899_TSULC , 0x42 },
+ { STB0899_RSLLC , 0x40 },
+ { STB0899_TSLPL , 0x12 },
+ { STB0899_TSCFGH , 0x0c },
+ { STB0899_TSCFGM , 0x00 },
+ { STB0899_TSCFGL , 0x0c },
+ { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */
+ { STB0899_RSSYNCDEL , 0x00 },
+ { STB0899_TSINHDELH , 0x02 },
+ { STB0899_TSINHDELM , 0x00 },
+ { STB0899_TSINHDELL , 0x00 },
+ { STB0899_TSLLSTKM , 0x00 },
+ { STB0899_TSLLSTKL , 0x00 },
+ { STB0899_TSULSTKM , 0x00 },
+ { STB0899_TSULSTKL , 0xab },
+ { STB0899_PCKLENUL , 0x00 },
+ { STB0899_PCKLENLL , 0xcc },
+ { STB0899_RSPCKLEN , 0xcc },
+ { STB0899_TSSTATUS , 0x80 },
+ { STB0899_ERRCTRL1 , 0xb6 },
+ { STB0899_ERRCTRL2 , 0x96 },
+ { STB0899_ERRCTRL3 , 0x89 },
+ { STB0899_DMONMSK1 , 0x27 },
+ { STB0899_DMONMSK0 , 0x03 },
+ { STB0899_DEMAPVIT , 0x5c },
+ { STB0899_PLPARM , 0x1f },
+ { STB0899_PDELCTRL , 0x48 },
+ { STB0899_PDELCTRL2 , 0x00 },
+ { STB0899_BBHCTRL1 , 0x00 },
+ { STB0899_BBHCTRL2 , 0x00 },
+ { STB0899_HYSTTHRESH , 0x77 },
+ { STB0899_MATCSTM , 0x00 },
+ { STB0899_MATCSTL , 0x00 },
+ { STB0899_UPLCSTM , 0x00 },
+ { STB0899_UPLCSTL , 0x00 },
+ { STB0899_DFLCSTM , 0x00 },
+ { STB0899_DFLCSTL , 0x00 },
+ { STB0899_SYNCCST , 0x00 },
+ { STB0899_SYNCDCSTM , 0x00 },
+ { STB0899_SYNCDCSTL , 0x00 },
+ { STB0899_ISI_ENTRY , 0x00 },
+ { STB0899_ISI_BIT_EN , 0x00 },
+ { STB0899_MATSTRM , 0x00 },
+ { STB0899_MATSTRL , 0x00 },
+ { STB0899_UPLSTRM , 0x00 },
+ { STB0899_UPLSTRL , 0x00 },
+ { STB0899_DFLSTRM , 0x00 },
+ { STB0899_DFLSTRL , 0x00 },
+ { STB0899_SYNCSTR , 0x00 },
+ { STB0899_SYNCDSTRM , 0x00 },
+ { STB0899_SYNCDSTRL , 0x00 },
+ { STB0899_CFGPDELSTATUS1 , 0x10 },
+ { STB0899_CFGPDELSTATUS2 , 0x00 },
+ { STB0899_BBFERRORM , 0x00 },
+ { STB0899_BBFERRORL , 0x00 },
+ { STB0899_UPKTERRORM , 0x00 },
+ { STB0899_UPKTERRORL , 0x00 },
+ { 0xffff , 0xff },
+};
+
+/* STB0899 demodulator config for the KNC1 and clones */
+static struct stb0899_config knc1_dvbs2_config = {
+ .init_dev = knc1_stb0899_s1_init_1,
+ .init_s2_demod = stb0899_s2_init_2,
+ .init_s1_demod = knc1_stb0899_s1_init_3,
+ .init_s2_fec = stb0899_s2_init_4,
+ .init_tst = stb0899_s1_init_5,
+
+ .postproc = NULL,
+
+ .demod_address = 0x68,
+// .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */
+ .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */
+// .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */
+
+ .xtal_freq = 27000000,
+ .inversion = IQ_SWAP_OFF, /* 1 */
+
+ .lo_clk = 76500000,
+ .hi_clk = 90000000,
+
+ .esno_ave = STB0899_DVBS2_ESNO_AVE,
+ .esno_quant = STB0899_DVBS2_ESNO_QUANT,
+ .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
+ .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
+ .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
+ .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+ .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+ .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
+ .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+ .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
+ .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+ .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
+ .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
+
+ .tuner_get_frequency = tda8261_get_frequency,
+ .tuner_set_frequency = tda8261_set_frequency,
+ .tuner_set_bandwidth = NULL,
+ .tuner_get_bandwidth = tda8261_get_bandwidth,
+ .tuner_set_rfsiggain = NULL
+};
+
+/*
+ * SD1878/SHA tuner config
+ * 1F, Single I/P, Horizontal mount, High Sensitivity
+ */
+static const struct tda8261_config sd1878c_config = {
+// .name = "SD1878/SHA",
+ .addr = 0x60,
+ .step_size = TDA8261_STEP_1000 /* kHz */
+};
+
static u8 read_pwm(struct budget_av *budget_av)
{
u8 b = 0xff;
@@ -905,8 +1185,11 @@ static u8 read_pwm(struct budget_av *budget_av)
#define SUBID_DVBS_TV_STAR 0x0014
#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
#define SUBID_DVBS_TV_STAR_CI 0x0016
+#define SUBID_DVBS2_KNC1 0x0018
+#define SUBID_DVBS2_KNC1_OEM 0x0019
#define SUBID_DVBS_EASYWATCH_1 0x001a
#define SUBID_DVBS_EASYWATCH_2 0x001b
+#define SUBID_DVBS2_EASYWATCH 0x001d
#define SUBID_DVBS_EASYWATCH 0x001e
#define SUBID_DVBC_EASYWATCH 0x002a
@@ -941,6 +1224,9 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBT_KNC1_PLUS:
case SUBID_DVBC_EASYWATCH:
case SUBID_DVBC_KNC1_PLUS_MK3:
+ case SUBID_DVBS2_KNC1:
+ case SUBID_DVBS2_KNC1_OEM:
+ case SUBID_DVBS2_EASYWATCH:
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
@@ -993,7 +1279,14 @@ static void frontend_init(struct budget_av *budget_av)
fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
}
break;
+ case SUBID_DVBS2_KNC1:
+ case SUBID_DVBS2_KNC1_OEM:
+ case SUBID_DVBS2_EASYWATCH:
+ budget_av->reinitialise_demod = 1;
+ if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
+ dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
+ break;
case SUBID_DVBS_CINERGY1200:
fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
&budget_av->budget.i2c_adap);
@@ -1260,6 +1553,8 @@ static struct saa7146_ext_vv vv_data = {
static struct saa7146_extension budget_extension;
MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
+MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
+MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
@@ -1290,6 +1585,9 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
+ MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
+ MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
+ MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 0a5aad45435d..3507463fdac9 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -43,6 +43,11 @@
#include "stv0299.h"
#include "stv0297.h"
#include "tda1004x.h"
+#include "stb0899_drv.h"
+#include "stb0899_reg.h"
+#include "stb0899_cfg.h"
+#include "stb6100.h"
+#include "stb6100_cfg.h"
#include "lnbp21.h"
#include "bsbe1.h"
#include "bsru6.h"
@@ -1071,7 +1076,271 @@ static struct tda10023_config tda10023_config = {
.deltaf = 0xa511,
};
+/* TT S2-3200 DVB-S (STB0899) Inittab */
+static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
+
+ { STB0899_DEV_ID , 0x81 },
+ { STB0899_DISCNTRL1 , 0x32 },
+ { STB0899_DISCNTRL2 , 0x80 },
+ { STB0899_DISRX_ST0 , 0x04 },
+ { STB0899_DISRX_ST1 , 0x00 },
+ { STB0899_DISPARITY , 0x00 },
+ { STB0899_DISFIFO , 0x00 },
+ { STB0899_DISSTATUS , 0x20 },
+ { STB0899_DISF22 , 0x8c },
+ { STB0899_DISF22RX , 0x9a },
+ { STB0899_SYSREG , 0x0b },
+ { STB0899_ACRPRESC , 0x11 },
+ { STB0899_ACRDIV1 , 0x0a },
+ { STB0899_ACRDIV2 , 0x05 },
+ { STB0899_DACR1 , 0x00 },
+ { STB0899_DACR2 , 0x00 },
+ { STB0899_OUTCFG , 0x00 },
+ { STB0899_MODECFG , 0x00 },
+ { STB0899_IRQSTATUS_3 , 0x30 },
+ { STB0899_IRQSTATUS_2 , 0x00 },
+ { STB0899_IRQSTATUS_1 , 0x00 },
+ { STB0899_IRQSTATUS_0 , 0x00 },
+ { STB0899_IRQMSK_3 , 0xf3 },
+ { STB0899_IRQMSK_2 , 0xfc },
+ { STB0899_IRQMSK_1 , 0xff },
+ { STB0899_IRQMSK_0 , 0xff },
+ { STB0899_IRQCFG , 0x00 },
+ { STB0899_I2CCFG , 0x88 },
+ { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
+ { STB0899_IOPVALUE5 , 0x00 },
+ { STB0899_IOPVALUE4 , 0x20 },
+ { STB0899_IOPVALUE3 , 0xc9 },
+ { STB0899_IOPVALUE2 , 0x90 },
+ { STB0899_IOPVALUE1 , 0x40 },
+ { STB0899_IOPVALUE0 , 0x00 },
+ { STB0899_GPIO00CFG , 0x82 },
+ { STB0899_GPIO01CFG , 0x82 },
+ { STB0899_GPIO02CFG , 0x82 },
+ { STB0899_GPIO03CFG , 0x82 },
+ { STB0899_GPIO04CFG , 0x82 },
+ { STB0899_GPIO05CFG , 0x82 },
+ { STB0899_GPIO06CFG , 0x82 },
+ { STB0899_GPIO07CFG , 0x82 },
+ { STB0899_GPIO08CFG , 0x82 },
+ { STB0899_GPIO09CFG , 0x82 },
+ { STB0899_GPIO10CFG , 0x82 },
+ { STB0899_GPIO11CFG , 0x82 },
+ { STB0899_GPIO12CFG , 0x82 },
+ { STB0899_GPIO13CFG , 0x82 },
+ { STB0899_GPIO14CFG , 0x82 },
+ { STB0899_GPIO15CFG , 0x82 },
+ { STB0899_GPIO16CFG , 0x82 },
+ { STB0899_GPIO17CFG , 0x82 },
+ { STB0899_GPIO18CFG , 0x82 },
+ { STB0899_GPIO19CFG , 0x82 },
+ { STB0899_GPIO20CFG , 0x82 },
+ { STB0899_SDATCFG , 0xb8 },
+ { STB0899_SCLTCFG , 0xba },
+ { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
+ { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
+ { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
+ { STB0899_DIRCLKCFG , 0x82 },
+ { STB0899_CLKOUT27CFG , 0x7e },
+ { STB0899_STDBYCFG , 0x82 },
+ { STB0899_CS0CFG , 0x82 },
+ { STB0899_CS1CFG , 0x82 },
+ { STB0899_DISEQCOCFG , 0x20 },
+ { STB0899_GPIO32CFG , 0x82 },
+ { STB0899_GPIO33CFG , 0x82 },
+ { STB0899_GPIO34CFG , 0x82 },
+ { STB0899_GPIO35CFG , 0x82 },
+ { STB0899_GPIO36CFG , 0x82 },
+ { STB0899_GPIO37CFG , 0x82 },
+ { STB0899_GPIO38CFG , 0x82 },
+ { STB0899_GPIO39CFG , 0x82 },
+ { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+ { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+ { STB0899_FILTCTRL , 0x00 },
+ { STB0899_SYSCTRL , 0x00 },
+ { STB0899_STOPCLK1 , 0x20 },
+ { STB0899_STOPCLK2 , 0x00 },
+ { STB0899_INTBUFSTATUS , 0x00 },
+ { STB0899_INTBUFCTRL , 0x0a },
+ { 0xffff , 0xff },
+};
+
+static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
+ { STB0899_DEMOD , 0x00 },
+ { STB0899_RCOMPC , 0xc9 },
+ { STB0899_AGC1CN , 0x41 },
+ { STB0899_AGC1REF , 0x10 },
+ { STB0899_RTC , 0x7a },
+ { STB0899_TMGCFG , 0x4e },
+ { STB0899_AGC2REF , 0x34 },
+ { STB0899_TLSR , 0x84 },
+ { STB0899_CFD , 0xc7 },
+ { STB0899_ACLC , 0x87 },
+ { STB0899_BCLC , 0x94 },
+ { STB0899_EQON , 0x41 },
+ { STB0899_LDT , 0xdd },
+ { STB0899_LDT2 , 0xc9 },
+ { STB0899_EQUALREF , 0xb4 },
+ { STB0899_TMGRAMP , 0x10 },
+ { STB0899_TMGTHD , 0x30 },
+ { STB0899_IDCCOMP , 0xfb },
+ { STB0899_QDCCOMP , 0x03 },
+ { STB0899_POWERI , 0x3b },
+ { STB0899_POWERQ , 0x3d },
+ { STB0899_RCOMP , 0x81 },
+ { STB0899_AGCIQIN , 0x80 },
+ { STB0899_AGC2I1 , 0x04 },
+ { STB0899_AGC2I2 , 0xf5 },
+ { STB0899_TLIR , 0x25 },
+ { STB0899_RTF , 0x80 },
+ { STB0899_DSTATUS , 0x00 },
+ { STB0899_LDI , 0xca },
+ { STB0899_CFRM , 0xf1 },
+ { STB0899_CFRL , 0xf3 },
+ { STB0899_NIRM , 0x2a },
+ { STB0899_NIRL , 0x05 },
+ { STB0899_ISYMB , 0x17 },
+ { STB0899_QSYMB , 0xfa },
+ { STB0899_SFRH , 0x2f },
+ { STB0899_SFRM , 0x68 },
+ { STB0899_SFRL , 0x40 },
+ { STB0899_SFRUPH , 0x2f },
+ { STB0899_SFRUPM , 0x68 },
+ { STB0899_SFRUPL , 0x40 },
+ { STB0899_EQUAI1 , 0xfd },
+ { STB0899_EQUAQ1 , 0x04 },
+ { STB0899_EQUAI2 , 0x0f },
+ { STB0899_EQUAQ2 , 0xff },
+ { STB0899_EQUAI3 , 0xdf },
+ { STB0899_EQUAQ3 , 0xfa },
+ { STB0899_EQUAI4 , 0x37 },
+ { STB0899_EQUAQ4 , 0x0d },
+ { STB0899_EQUAI5 , 0xbd },
+ { STB0899_EQUAQ5 , 0xf7 },
+ { STB0899_DSTATUS2 , 0x00 },
+ { STB0899_VSTATUS , 0x00 },
+ { STB0899_VERROR , 0xff },
+ { STB0899_IQSWAP , 0x2a },
+ { STB0899_ECNT1M , 0x00 },
+ { STB0899_ECNT1L , 0x00 },
+ { STB0899_ECNT2M , 0x00 },
+ { STB0899_ECNT2L , 0x00 },
+ { STB0899_ECNT3M , 0x00 },
+ { STB0899_ECNT3L , 0x00 },
+ { STB0899_FECAUTO1 , 0x06 },
+ { STB0899_FECM , 0x01 },
+ { STB0899_VTH12 , 0xf0 },
+ { STB0899_VTH23 , 0xa0 },
+ { STB0899_VTH34 , 0x78 },
+ { STB0899_VTH56 , 0x4e },
+ { STB0899_VTH67 , 0x48 },
+ { STB0899_VTH78 , 0x38 },
+ { STB0899_PRVIT , 0xff },
+ { STB0899_VITSYNC , 0x19 },
+ { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+ { STB0899_TSULC , 0x42 },
+ { STB0899_RSLLC , 0x40 },
+ { STB0899_TSLPL , 0x12 },
+ { STB0899_TSCFGH , 0x0c },
+ { STB0899_TSCFGM , 0x00 },
+ { STB0899_TSCFGL , 0x0c },
+ { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */
+ { STB0899_RSSYNCDEL , 0x00 },
+ { STB0899_TSINHDELH , 0x02 },
+ { STB0899_TSINHDELM , 0x00 },
+ { STB0899_TSINHDELL , 0x00 },
+ { STB0899_TSLLSTKM , 0x00 },
+ { STB0899_TSLLSTKL , 0x00 },
+ { STB0899_TSULSTKM , 0x00 },
+ { STB0899_TSULSTKL , 0xab },
+ { STB0899_PCKLENUL , 0x00 },
+ { STB0899_PCKLENLL , 0xcc },
+ { STB0899_RSPCKLEN , 0xcc },
+ { STB0899_TSSTATUS , 0x80 },
+ { STB0899_ERRCTRL1 , 0xb6 },
+ { STB0899_ERRCTRL2 , 0x96 },
+ { STB0899_ERRCTRL3 , 0x89 },
+ { STB0899_DMONMSK1 , 0x27 },
+ { STB0899_DMONMSK0 , 0x03 },
+ { STB0899_DEMAPVIT , 0x5c },
+ { STB0899_PLPARM , 0x1f },
+ { STB0899_PDELCTRL , 0x48 },
+ { STB0899_PDELCTRL2 , 0x00 },
+ { STB0899_BBHCTRL1 , 0x00 },
+ { STB0899_BBHCTRL2 , 0x00 },
+ { STB0899_HYSTTHRESH , 0x77 },
+ { STB0899_MATCSTM , 0x00 },
+ { STB0899_MATCSTL , 0x00 },
+ { STB0899_UPLCSTM , 0x00 },
+ { STB0899_UPLCSTL , 0x00 },
+ { STB0899_DFLCSTM , 0x00 },
+ { STB0899_DFLCSTL , 0x00 },
+ { STB0899_SYNCCST , 0x00 },
+ { STB0899_SYNCDCSTM , 0x00 },
+ { STB0899_SYNCDCSTL , 0x00 },
+ { STB0899_ISI_ENTRY , 0x00 },
+ { STB0899_ISI_BIT_EN , 0x00 },
+ { STB0899_MATSTRM , 0x00 },
+ { STB0899_MATSTRL , 0x00 },
+ { STB0899_UPLSTRM , 0x00 },
+ { STB0899_UPLSTRL , 0x00 },
+ { STB0899_DFLSTRM , 0x00 },
+ { STB0899_DFLSTRL , 0x00 },
+ { STB0899_SYNCSTR , 0x00 },
+ { STB0899_SYNCDSTRM , 0x00 },
+ { STB0899_SYNCDSTRL , 0x00 },
+ { STB0899_CFGPDELSTATUS1 , 0x10 },
+ { STB0899_CFGPDELSTATUS2 , 0x00 },
+ { STB0899_BBFERRORM , 0x00 },
+ { STB0899_BBFERRORL , 0x00 },
+ { STB0899_UPKTERRORM , 0x00 },
+ { STB0899_UPKTERRORL , 0x00 },
+ { 0xffff , 0xff },
+};
+static struct stb0899_config tt3200_config = {
+ .init_dev = tt3200_stb0899_s1_init_1,
+ .init_s2_demod = stb0899_s2_init_2,
+ .init_s1_demod = tt3200_stb0899_s1_init_3,
+ .init_s2_fec = stb0899_s2_init_4,
+ .init_tst = stb0899_s1_init_5,
+
+ .postproc = NULL,
+
+ .demod_address = 0x68,
+
+ .xtal_freq = 27000000,
+ .inversion = IQ_SWAP_ON, /* 1 */
+
+ .lo_clk = 76500000,
+ .hi_clk = 99000000,
+
+ .esno_ave = STB0899_DVBS2_ESNO_AVE,
+ .esno_quant = STB0899_DVBS2_ESNO_QUANT,
+ .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
+ .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
+ .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
+ .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
+ .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
+ .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
+ .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
+
+ .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
+ .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
+ .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
+ .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
+
+ .tuner_get_frequency = stb6100_get_frequency,
+ .tuner_set_frequency = stb6100_set_frequency,
+ .tuner_set_bandwidth = stb6100_set_bandwidth,
+ .tuner_get_bandwidth = stb6100_get_bandwidth,
+ .tuner_set_rfsiggain = NULL
+};
+
+struct stb6100_config tt3200_stb6100_config = {
+ .tuner_address = 0x60,
+ .refclock = 27000000,
+};
static void frontend_init(struct budget_ci *budget_ci)
{
@@ -1152,6 +1421,46 @@ static void frontend_init(struct budget_ci *budget_ci)
}
}
break;
+
+ case 0x1019: // TT S2-3200 PCI
+ /*
+ * NOTE! on some STB0899 versions, the internal PLL takes a longer time
+ * to settle, aka LOCK. On the older revisions of the chip, we don't see
+ * this, as a result on the newer chips the entire clock tree, will not
+ * be stable after a freshly POWER 'ed up situation.
+ * In this case, we should RESET the STB0899 (Active LOW) and wait for
+ * PLL stabilization.
+ *
+ * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
+ * connected to the SAA7146 GPIO, GPIO2, Pin 142
+ */
+ /* Reset Demodulator */
+ saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
+ /* Wait for everything to die */
+ msleep(50);
+ /* Pull it up out of Reset state */
+ saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
+ /* Wait for PLL to stabilize */
+ msleep(250);
+ /*
+ * PLL state should be stable now. Ideally, we should check
+ * for PLL LOCK status. But well, never mind!
+ */
+ budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
+ if (budget_ci->budget.dvb_frontend) {
+ if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
+ if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
+ printk("%s: No LNBP21 found!\n", __FUNCTION__);
+ dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+ budget_ci->budget.dvb_frontend = NULL;
+ }
+ } else {
+ dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+ budget_ci->budget.dvb_frontend = NULL;
+ }
+ }
+ break;
+
}
if (budget_ci->budget.dvb_frontend == NULL) {
@@ -1242,6 +1551,7 @@ MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1251,6 +1561,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
+ MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
{
.vendor = 0,
}
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
index 86435bf16260..3ad0c6789ba7 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -103,6 +103,7 @@ static struct saa7146_pci_extension_data x_var = { \
#define BUDGET_CIN1200C_MK3 15
#define BUDGET_KNC1C_MK3 16
#define BUDGET_KNC1CP_MK3 17
+#define BUDGET_KNC1S2 18
#define BUDGET_VIDEO_PORTA 0
#define BUDGET_VIDEO_PORTB 1
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index a5ca176a7b08..eafa547ca96b 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -93,8 +93,8 @@
*/
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define DRIVER_VERSION "v0.41"
-#define RADIO_VERSION KERNEL_VERSION(0,4,1)
+#define DRIVER_VERSION "v0.43"
+#define RADIO_VERSION KERNEL_VERSION(0, 4, 3)
static struct v4l2_queryctrl radio_qctrl[] = {
{
@@ -104,7 +104,27 @@ static struct v4l2_queryctrl radio_qctrl[] = {
.maximum = 1,
.default_value = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
- }
+ },
+/* HINT: the disabled controls are only here to satify kradio and such apps */
+ { .id = V4L2_CID_AUDIO_VOLUME,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_BALANCE,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_BASS,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_TREBLE,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
+ {
+ .id = V4L2_CID_AUDIO_LOUDNESS,
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+ },
};
#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
@@ -131,6 +151,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
static void usb_dsbr100_disconnect(struct usb_interface *intf);
static int usb_dsbr100_open(struct inode *inode, struct file *file);
static int usb_dsbr100_close(struct inode *inode, struct file *file);
+static int usb_dsbr100_suspend(struct usb_interface *intf,
+ pm_message_t message);
+static int usb_dsbr100_resume(struct usb_interface *intf);
static int radio_nr = -1;
module_param(radio_nr, int, 0);
@@ -157,10 +180,14 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
/* USB subsystem interface */
static struct usb_driver usb_dsbr100_driver = {
- .name = "dsbr100",
- .probe = usb_dsbr100_probe,
- .disconnect = usb_dsbr100_disconnect,
- .id_table = usb_dsbr100_device_table,
+ .name = "dsbr100",
+ .probe = usb_dsbr100_probe,
+ .disconnect = usb_dsbr100_disconnect,
+ .id_table = usb_dsbr100_device_table,
+ .suspend = usb_dsbr100_suspend,
+ .resume = usb_dsbr100_resume,
+ .reset_resume = usb_dsbr100_resume,
+ .supports_autosuspend = 0,
};
/* Low-level device interface begins here */
@@ -448,6 +475,36 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
return 0;
}
+/* Suspend device - stop device. */
+static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct dsbr100_device *radio = usb_get_intfdata(intf);
+ int retval;
+
+ retval = dsbr100_stop(radio);
+ if (retval == -1)
+ dev_warn(&intf->dev, "dsbr100_stop failed\n");
+
+ dev_info(&intf->dev, "going into suspend..\n");
+
+ return 0;
+}
+
+/* Resume device - start device. */
+static int usb_dsbr100_resume(struct usb_interface *intf)
+{
+ struct dsbr100_device *radio = usb_get_intfdata(intf);
+ int retval;
+
+ retval = dsbr100_start(radio);
+ if (retval == -1)
+ dev_warn(&intf->dev, "dsbr100_start failed\n");
+
+ dev_info(&intf->dev, "coming out of suspend..\n");
+
+ return 0;
+}
+
/* File system interface */
static const struct file_operations usb_dsbr100_fops = {
.owner = THIS_MODULE,
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 9305e958fc66..dd6d3dfcd7d2 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -1,7 +1,7 @@
/* radiotrack (radioreveal) driver for Linux radio support
* (c) 1997 M. Kirkwood
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
- * Converted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
*
* History:
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 0490a1fa999d..bfd37f38b9ab 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -23,7 +23,7 @@
* 2002-01-17 Adam Belay <ambx1@neo.rr.com>
* Updated to latest pnp code
*
- * 2003-01-31 Alan Cox <alan@redhat.com>
+ * 2003-01-31 Alan Cox <alan@lxorguk.ukuu.org.uk>
* Cleaned up locking, delay code, general odds and ends
*
* 2006-07-30 Hans J. Koch <koch@hjk-az.de>
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index d131a5d38128..e13118da307b 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -8,7 +8,7 @@
* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
*
* Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- * Converted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
*
* TODO: Allow for more than one of these foolish entities :-)
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 256cbeffdcb6..61760019b033 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -72,6 +72,11 @@ MODULE_LICENSE("GPL");
#define USB_AMRADIO_VENDOR 0x07ca
#define USB_AMRADIO_PRODUCT 0xb800
+/* dev_warn macro with driver name */
+#define MR800_DRIVER_NAME "radio-mr800"
+#define amradio_dev_warn(dev, fmt, arg...) \
+ dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
+
/* Probably USB_TIMEOUT should be modified in module parameter */
#define BUFFER_LENGTH 8
#define USB_TIMEOUT 500
@@ -154,7 +159,7 @@ MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
/* USB subsystem interface */
static struct usb_driver usb_amradio_driver = {
- .name = "radio-mr800",
+ .name = MR800_DRIVER_NAME,
.probe = usb_amradio_probe,
.disconnect = usb_amradio_disconnect,
.suspend = usb_amradio_suspend,
@@ -359,7 +364,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
radio->curfreq = f->frequency;
if (amradio_setfreq(radio, radio->curfreq) < 0)
- warn("Set frequency failed");
+ amradio_dev_warn(&radio->videodev->dev,
+ "set frequency failed\n");
return 0;
}
@@ -382,8 +388,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
+ memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
return 0;
}
}
@@ -414,12 +419,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value) {
if (amradio_stop(radio) < 0) {
- warn("amradio_stop() failed");
+ amradio_dev_warn(&radio->videodev->dev,
+ "amradio_stop failed\n");
return -1;
}
} else {
if (amradio_start(radio) < 0) {
- warn("amradio_start() failed");
+ amradio_dev_warn(&radio->videodev->dev,
+ "amradio_start failed\n");
return -1;
}
}
@@ -475,13 +482,15 @@ static int usb_amradio_open(struct inode *inode, struct file *file)
radio->muted = 1;
if (amradio_start(radio) < 0) {
- warn("Radio did not start up properly");
+ amradio_dev_warn(&radio->videodev->dev,
+ "radio did not start up properly\n");
radio->users = 0;
unlock_kernel();
return -EIO;
}
if (amradio_setfreq(radio, radio->curfreq) < 0)
- warn("Set frequency failed");
+ amradio_dev_warn(&radio->videodev->dev,
+ "set frequency failed\n");
unlock_kernel();
return 0;
@@ -508,9 +517,9 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
struct amradio_device *radio = usb_get_intfdata(intf);
if (amradio_stop(radio) < 0)
- warn("amradio_stop() failed");
+ dev_warn(&intf->dev, "amradio_stop failed\n");
- info("radio-mr800: Going into suspend..");
+ dev_info(&intf->dev, "going into suspend..\n");
return 0;
}
@@ -521,9 +530,9 @@ static int usb_amradio_resume(struct usb_interface *intf)
struct amradio_device *radio = usb_get_intfdata(intf);
if (amradio_start(radio) < 0)
- warn("amradio_start() failed");
+ dev_warn(&intf->dev, "amradio_start failed\n");
- info("radio-mr800: Coming out of suspend..");
+ dev_info(&intf->dev, "coming out of suspend..\n");
return 0;
}
@@ -602,7 +611,7 @@ static int usb_amradio_probe(struct usb_interface *intf,
video_set_drvdata(radio->videodev, radio);
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
- warn("Could not register video device");
+ dev_warn(&intf->dev, "could not register video device\n");
video_device_release(radio->videodev);
kfree(radio->buffer);
kfree(radio);
@@ -617,9 +626,13 @@ static int __init amradio_init(void)
{
int retval = usb_register(&usb_amradio_driver);
- info(DRIVER_VERSION " " DRIVER_DESC);
+ pr_info(KBUILD_MODNAME
+ ": version " DRIVER_VERSION " " DRIVER_DESC "\n");
+
if (retval)
- err("usb_register failed. Error number %d", retval);
+ pr_err(KBUILD_MODNAME
+ ": usb_register failed. Error number %d\n", retval);
+
return retval;
}
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index a67079777419..7704f243b6f0 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -1,7 +1,7 @@
/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
*
* Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- * Converted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
*
* TODO: Allow for more than one of these foolish entities :-)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 329c90bddadd..834d43651c70 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -3,7 +3,7 @@
* (c) 1997 M. Kirkwood
* (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
*
- * Fitted to new interface by Alan Cox <alan.cox@linux.org>
+ * Fitted to new interface by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Made working and cleaned up functions <mikael.hedin@irf.se>
* Support for ISAPnP by Ladislav Michl <ladis@psi.cz>
*
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 47102c2c8250..c4ee10c3719e 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -184,7 +184,7 @@ config VIDEO_MSP3400
config VIDEO_CS5345
tristate "Cirrus Logic CS5345 audio ADC"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Cirrus Logic CS5345 24-bit, 192 kHz
stereo A/D converter.
@@ -204,7 +204,7 @@ config VIDEO_CS53L32A
config VIDEO_M52790
tristate "Mitsubishi M52790 A/V switch"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Mitsubishi M52790 A/V switch.
@@ -242,7 +242,7 @@ config VIDEO_WM8739
config VIDEO_VP27SMPX
tristate "Panasonic VP27s internal MPX"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the internal MPX of the Panasonic VP27s tuner.
@@ -387,7 +387,7 @@ comment "MPEG video encoders"
config VIDEO_CX2341X
tristate "Conexant CX2341x MPEG encoders"
- depends on VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_COMMON
+ depends on VIDEO_V4L2 && VIDEO_V4L2_COMMON
---help---
Support for the Conexant CX23416 MPEG encoders
and CX23415 MPEG encoder/decoders.
@@ -750,6 +750,12 @@ config SOC_CAMERA_PLATFORM
help
This is a generic SoC camera platform driver, useful for testing
+config SOC_CAMERA_OV772X
+ tristate "ov772x camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a ov772x camera driver
+
config VIDEO_PXA27x
tristate "PXA27x Quick Capture Interface driver"
depends on VIDEO_DEV && PXA27x && SOC_CAMERA
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 16962f3aa157..53d43f9e017d 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,7 +10,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o
videodev-objs := v4l2-dev.o v4l2-ioctl.o
-obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-compat-ioctl32.o v4l2-int-device.o
obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
@@ -25,6 +25,7 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
+obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
@@ -133,6 +134,7 @@ obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
obj-$(CONFIG_VIDEO_AU0828) += au0828/
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index e09b00693230..2ba6abd92b6f 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -396,8 +396,7 @@ out_up:
return ret;
}
-static int ar_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int ar_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *dev = video_devdata(file);
struct ar_device *ar = video_get_drvdata(dev);
@@ -543,7 +542,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, ar_do_ioctl);
+ return video_usercopy(file, cmd, arg, ar_do_ioctl);
}
#if USE_INT
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
index dce6dae5740e..74c325e594a2 100644
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ b/drivers/media/video/bt8xx/bttv-gpio.c
@@ -42,7 +42,7 @@ static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
int len = strlen(sub->wanted);
- if (0 == strncmp(dev->bus_id, sub->wanted, len))
+ if (0 == strncmp(dev_name(dev), sub->wanted, len))
return 1;
return 0;
}
@@ -91,15 +91,14 @@ int bttv_sub_add_device(struct bttv_core *core, char *name)
sub->dev.parent = &core->pci->dev;
sub->dev.bus = &bttv_sub_bus_type;
sub->dev.release = release_sub_device;
- snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d",
- name, core->nr);
+ dev_set_name(&sub->dev, "%s%d", name, core->nr);
err = device_register(&sub->dev);
if (0 != err) {
kfree(sub);
return err;
}
- printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id);
+ printk("bttv%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));
list_add_tail(&sub->list,&core->subs);
return 0;
}
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 46cb90e0985b..bc2c88499ab9 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -308,7 +308,7 @@ struct bttv_sub_device {
struct bttv_sub_driver {
struct device_driver drv;
- char wanted[BUS_ID_SIZE];
+ char wanted[20];
int (*probe)(struct bttv_sub_device *sub);
void (*remove)(struct bttv_sub_device *sub);
};
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index b4d940b2e447..199a4d225caf 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -459,7 +459,7 @@ struct bttv {
};
/* our devices */
-#define BTTV_MAX 16
+#define BTTV_MAX 32
extern unsigned int bttv_num;
extern struct bttv bttvs[BTTV_MAX];
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index ace4ff9ea023..17f80d03f38e 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -706,8 +706,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
* Video4linux interfacing
*/
-static int qcam_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam=(struct qcam_device *)dev;
@@ -867,7 +866,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
static int qcam_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
+ return video_usercopy(file, cmd, arg, qcam_do_ioctl);
}
static ssize_t qcam_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 0f930d351466..21c71eb085db 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -500,8 +500,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
* Video4linux interfacing
*/
-static int qcam_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam=(struct qcam_device *)dev;
@@ -667,9 +666,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
}
static int qcam_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
+ return video_usercopy(file, cmd, arg, qcam_do_ioctl);
}
static ssize_t qcam_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 16c094f77852..028a400d2453 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3333,8 +3333,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf,
return cam->decompressed_frame.count;
}
-static int cpia_do_ioctl(struct inode *inode, struct file *file,
- unsigned int ioctlnr, void *arg)
+static int cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *dev = file->private_data;
struct cam_data *cam = video_get_drvdata(dev);
@@ -3347,9 +3346,9 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
if (mutex_lock_interruptible(&cam->busy_lock))
return -EINTR;
- //DBG("cpia_ioctl: %u\n", ioctlnr);
+ /* DBG("cpia_ioctl: %u\n", cmd); */
- switch (ioctlnr) {
+ switch (cmd) {
/* query capabilities */
case VIDIOCGCAP:
{
@@ -3724,7 +3723,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
static int cpia_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, cpia_do_ioctl);
+ return video_usercopy(file, cmd, arg, cpia_do_ioctl);
}
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index 7e791b6923f9..1cc0df8befff 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -25,7 +25,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Stripped of 2.4 stuff ready for main kernel submit by
- * Alan Cox <alan@redhat.com>
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>
*
****************************************************************************/
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
index 73511a542077..dc5b07a20f69 100644
--- a/drivers/media/video/cpia2/cpia2_usb.c
+++ b/drivers/media/video/cpia2/cpia2_usb.c
@@ -25,7 +25,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Stripped of 2.4 stuff ready for main kernel submit by
- * Alan Cox <alan@redhat.com>
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>
****************************************************************************/
#include <linux/kernel.h>
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 1c6bd633f193..3c2d7eac1197 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Stripped of 2.4 stuff ready for main kernel submit by
- * Alan Cox <alan@redhat.com>
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>
****************************************************************************/
#include <linux/version.h>
@@ -1572,8 +1572,7 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
* cpia2_ioctl
*
*****************************************************************************/
-static int cpia2_do_ioctl(struct inode *inode, struct file *file,
- unsigned int ioctl_nr, void *arg)
+static int cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct camera_data *cam = video_drvdata(file);
int retval = 0;
@@ -1591,7 +1590,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
}
/* Priority check */
- switch (ioctl_nr) {
+ switch (cmd) {
case VIDIOCSWIN:
case VIDIOCMCAPTURE:
case VIDIOC_S_FMT:
@@ -1618,7 +1617,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
break;
}
- switch (ioctl_nr) {
+ switch (cmd) {
case VIDIOCGCAP: /* query capabilities */
retval = ioctl_cap_query(arg, cam);
break;
@@ -1683,7 +1682,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_ENUMINPUT:
case VIDIOC_G_INPUT:
case VIDIOC_S_INPUT:
- retval = ioctl_input(ioctl_nr, arg,cam);
+ retval = ioctl_input(cmd, arg, cam);
break;
case VIDIOC_ENUM_FMT:
@@ -1843,9 +1842,9 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
}
static int cpia2_ioctl(struct inode *inode, struct file *file,
- unsigned int ioctl_nr, unsigned long iarg)
+ unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, ioctl_nr, iarg, cpia2_do_ioctl);
+ return video_usercopy(file, cmd, arg, cpia2_do_ioctl);
}
/******************************************************************************
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index 0b55837880a7..486cad0c26e0 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -215,12 +215,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
void cx18_av_audio_set_path(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
+ u8 v;
/* stop microcontroller */
- cx18_av_and_or(cx, 0x803, ~0x10, 0);
+ v = cx18_av_read(cx, 0x803) & ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
/* assert soft reset */
- cx18_av_and_or(cx, 0x810, ~0x1, 0x01);
+ v = cx18_av_read(cx, 0x810) | 0x01;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
/* Mute everything to prevent the PFFT! */
cx18_av_write(cx, 0x8d3, 0x1f);
@@ -240,12 +243,14 @@ void cx18_av_audio_set_path(struct cx18 *cx)
set_audclk_freq(cx, state->audclk_freq);
/* deassert soft reset */
- cx18_av_and_or(cx, 0x810, ~0x1, 0x00);
+ v = cx18_av_read(cx, 0x810) & ~0x01;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
/* When the microcontroller detects the
* audio format, it will unmute the lines */
- cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
+ v = cx18_av_read(cx, 0x803) | 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
}
}
@@ -347,19 +352,23 @@ static int get_mute(struct cx18 *cx)
static void set_mute(struct cx18 *cx, int mute)
{
struct cx18_av_state *state = &cx->av_state;
+ u8 v;
if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
/* Must turn off microcontroller in order to mute sound.
* Not sure if this is the best method, but it does work.
* If the microcontroller is running, then it will undo any
* changes to the mute register. */
+ v = cx18_av_read(cx, 0x803);
if (mute) {
/* disable microcontroller */
- cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
+ v &= ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
cx18_av_write(cx, 0x8d3, 0x1f);
} else {
/* enable microcontroller */
- cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
+ v |= 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
}
} else {
/* SRC1_MUTE_EN */
@@ -375,16 +384,26 @@ int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
switch (cmd) {
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+ {
+ u8 v;
if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- cx18_av_and_or(cx, 0x803, ~0x10, 0);
+ v = cx18_av_read(cx, 0x803) & ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
cx18_av_write(cx, 0x8d3, 0x1f);
}
- cx18_av_and_or(cx, 0x810, ~0x1, 1);
+ v = cx18_av_read(cx, 0x810) | 0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+
retval = set_audclk_freq(cx, *(u32 *)arg);
- cx18_av_and_or(cx, 0x810, ~0x1, 0);
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2)
- cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
+
+ v = cx18_av_read(cx, 0x810) & ~0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) | 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+ }
return retval;
+ }
case VIDIOC_G_CTRL:
switch (ctrl->id) {
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 73f5141a42d1..518bd701d393 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -36,12 +36,31 @@ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
return 0;
}
+int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask)
+{
+ u32 reg = 0xc40000 + (addr & ~3);
+ int shift = (addr & 3) * 8;
+ u32 x = cx18_read_reg(cx, reg);
+
+ x = (x & ~((u32)0xff << shift)) | ((u32)value << shift);
+ cx18_write_reg_expect(cx, x, reg,
+ ((u32)eval << shift), ((u32)mask << shift));
+ return 0;
+}
+
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
{
cx18_write_reg(cx, value, 0xc40000 + addr);
return 0;
}
+int
+cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask)
+{
+ cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask);
+ return 0;
+}
+
int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value)
{
cx18_write_reg_noretry(cx, value, 0xc40000 + addr);
@@ -98,14 +117,16 @@ static void cx18_av_initialize(struct cx18 *cx)
cx18_av_loadfw(cx);
/* Stop 8051 code execution */
- cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000);
+ cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000,
+ 0x03000000, 0x13000000);
/* initallize the PLL by toggling sleep bit */
v = cx18_av_read4(cx, CXADEC_HOST_REG1);
- /* enable sleep mode */
- cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1);
+ /* enable sleep mode - register appears to be read only... */
+ cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe);
/* disable sleep mode */
- cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe);
+ cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe,
+ v & 0xfffe, 0xffff);
/* initialize DLLs */
v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
@@ -125,9 +146,10 @@ static void cx18_av_initialize(struct cx18 *cx)
v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
/* enable TUNE_FIL_RST */
- cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v);
+ cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F);
/* disable TUNE_FIL_RST */
- cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE);
+ cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3,
+ v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F);
/* enable 656 output */
cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
@@ -251,10 +273,9 @@ void cx18_av_std_setup(struct cx18 *cx)
pll_int, pll_frac, pll_post);
if (pll_post) {
- int fin, fsc;
- int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
+ int fin, fsc, pll;
- pll >>= 25;
+ pll = (28636364L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
pll /= pll_post;
CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
pll / 1000000, pll % 1000000);
@@ -324,6 +345,7 @@ static void input_change(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
v4l2_std_id std = state->std;
+ u8 v;
/* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
@@ -333,31 +355,34 @@ static void input_change(struct cx18 *cx)
if (std & V4L2_STD_525_60) {
if (std == V4L2_STD_NTSC_M_JP) {
/* Japan uses EIAJ audio standard */
- cx18_av_write(cx, 0x808, 0xf7);
- cx18_av_write(cx, 0x80b, 0x02);
+ cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff);
+ cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f);
} else if (std == V4L2_STD_NTSC_M_KR) {
/* South Korea uses A2 audio standard */
- cx18_av_write(cx, 0x808, 0xf8);
- cx18_av_write(cx, 0x80b, 0x03);
+ cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff);
+ cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
} else {
/* Others use the BTSC audio standard */
- cx18_av_write(cx, 0x808, 0xf6);
- cx18_av_write(cx, 0x80b, 0x01);
+ cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff);
+ cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f);
}
} else if (std & V4L2_STD_PAL) {
/* Follow tuner change procedure for PAL */
- cx18_av_write(cx, 0x808, 0xff);
- cx18_av_write(cx, 0x80b, 0x03);
+ cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
+ cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
} else if (std & V4L2_STD_SECAM) {
/* Select autodetect for SECAM */
- cx18_av_write(cx, 0x808, 0xff);
- cx18_av_write(cx, 0x80b, 0x03);
+ cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff);
+ cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
}
- if (cx18_av_read(cx, 0x803) & 0x10) {
+ v = cx18_av_read(cx, 0x803);
+ if (v & 0x10) {
/* restart audio decoder microcontroller */
- cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
- cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
+ v &= ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+ v |= 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
}
}
@@ -368,6 +393,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
vid_input <= CX18_AV_COMPOSITE8);
u8 reg;
+ u8 v;
CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
vid_input, aud_input);
@@ -413,16 +439,23 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
return -EINVAL;
}
- cx18_av_write(cx, 0x103, reg);
+ cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
+
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
- cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
+ v = cx18_av_read(cx, 0x102);
+ if (reg & 0x80)
+ v &= ~0x2;
+ else
+ v |= 0x2;
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
- cx18_av_and_or(cx, 0x102, ~0x4, 4);
+ v |= 0x4;
else
- cx18_av_and_or(cx, 0x102, ~0x4, 0);
+ v &= ~0x4;
+ cx18_av_write_expect(cx, 0x102, v, v, 0x17);
+
/*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
state->vid_input = vid_input;
@@ -799,40 +832,47 @@ int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
}
case VIDIOC_S_TUNER:
+ {
+ u8 v;
+
if (state->radio)
break;
+ v = cx18_av_read(cx, 0x809);
+ v &= ~0xf;
+
switch (vt->audmode) {
case V4L2_TUNER_MODE_MONO:
/* mono -> mono
stereo -> mono
bilingual -> lang1 */
- cx18_av_and_or(cx, 0x809, ~0xf, 0x00);
break;
case V4L2_TUNER_MODE_STEREO:
case V4L2_TUNER_MODE_LANG1:
/* mono -> mono
stereo -> stereo
bilingual -> lang1 */
- cx18_av_and_or(cx, 0x809, ~0xf, 0x04);
+ v |= 0x4;
break;
case V4L2_TUNER_MODE_LANG1_LANG2:
/* mono -> mono
stereo -> stereo
bilingual -> lang1/lang2 */
- cx18_av_and_or(cx, 0x809, ~0xf, 0x07);
+ v |= 0x7;
break;
case V4L2_TUNER_MODE_LANG2:
/* mono -> mono
stereo -> stereo
bilingual -> lang2 */
- cx18_av_and_or(cx, 0x809, ~0xf, 0x01);
+ v |= 0x1;
break;
default:
return -EINVAL;
}
+ cx18_av_write_expect(cx, 0x809, v, v, 0xff);
state->audmode = vt->audmode;
break;
+ }
case VIDIOC_G_FMT:
return get_v4lfmt(cx, (struct v4l2_format *)arg);
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index b67d8df20cc6..a07988c6f5cd 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -302,6 +302,9 @@ struct cx18_av_state {
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
+int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask);
+int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
+ u32 mask);
u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr);
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 522a035b2e8f..924691dcaeb7 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -43,11 +43,13 @@ int cx18_av_loadfw(struct cx18 *cx)
/* The firmware load often has byte errors, so allow for several
retries, both at byte level and at the firmware load level. */
while (retries1 < 5) {
- cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
- cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
+ cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000,
+ 0x00008430, 0xffffffff); /* cx25843 */
+ cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff);
- /* Reset the Mako core (Register is undocumented.) */
- cx18_av_write4(cx, 0x8100, 0x00010000);
+ /* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */
+ cx18_av_write4_expect(cx, 0x8100, 0x00010000,
+ 0x00008430, 0xffffffff); /* cx25843 */
/* Put the 8051 in reset and enable firmware upload */
cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000);
@@ -61,7 +63,7 @@ int cx18_av_loadfw(struct cx18 *cx)
int retries2;
int unrec_err = 0;
- for (retries2 = 0; retries2 < CX18_MAX_MMIO_RETRIES;
+ for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES;
retries2++) {
cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
dl_control);
@@ -80,7 +82,7 @@ int cx18_av_loadfw(struct cx18 *cx)
}
cx18_log_write_retries(cx, retries2,
cx->reg_mem + 0xc40000 + CXADEC_DL_CTL);
- if (unrec_err || retries2 >= CX18_MAX_MMIO_RETRIES)
+ if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
break;
}
if (i == size)
@@ -93,7 +95,8 @@ int cx18_av_loadfw(struct cx18 *cx)
return -EIO;
}
- cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);
+ cx18_av_write4_expect(cx, CXADEC_DL_CTL,
+ 0x13000000 | fw->size, 0x13000000, 0x13000000);
/* Output to the 416 */
cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
@@ -118,7 +121,8 @@ int cx18_av_loadfw(struct cx18 *cx)
passthrough */
cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
- cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6);
+ cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
+ 0x3F00FFFF);
/* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
/* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
@@ -136,7 +140,7 @@ int cx18_av_loadfw(struct cx18 *cx)
v |= 0xFF; /* Auto by default */
v |= 0x400; /* Stereo by default */
v |= 0x14000000;
- cx18_av_write4(cx, CXADEC_STD_DET_CTL, v);
+ cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
release_firmware(fw);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 7874d9790a51..d7879fb1d21f 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -739,8 +739,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx->std = V4L2_STD_NTSC_M;
if (cx->options.tuner == -1) {
- int i;
-
for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
if ((cx->std & cx->card->tuners[i].std) == 0)
continue;
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index bbdd5f25041d..fe9e5bb979e0 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -353,11 +353,12 @@ struct cx18_i2c_algo_callback_data {
int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
};
-#define CX18_MAX_MMIO_RETRIES 10
+#define CX18_MAX_MMIO_WR_RETRIES 10
+#define CX18_MAX_MMIO_RD_RETRIES 2
struct cx18_mmio_stats {
- atomic_t retried_write[CX18_MAX_MMIO_RETRIES+1];
- atomic_t retried_read[CX18_MAX_MMIO_RETRIES+1];
+ atomic_t retried_write[CX18_MAX_MMIO_WR_RETRIES+1];
+ atomic_t retried_read[CX18_MAX_MMIO_RD_RETRIES+1];
};
/* Struct to hold info about cx18 cards */
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 51534428cd00..7a7c89032caa 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -200,8 +200,10 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
void cx18_halt_firmware(struct cx18 *cx)
{
CX18_DEBUG_INFO("Preparing for firmware halt.\n");
- cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
- cx18_write_reg(cx, 0x00020002, CX18_ADEC_CONTROL);
+ cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
+ 0x0000000F, 0x000F000F);
+ cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
+ 0x00000002, 0x00020002);
}
void cx18_init_power(struct cx18 *cx, int lowpwr)
@@ -211,7 +213,8 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);
/* ADEC out of sleep */
- cx18_write_reg(cx, 0x00020000, CX18_ADEC_CONTROL);
+ cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
+ 0x00000000, 0x00020002);
/* The fast clock is at 200/245 MHz */
cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
@@ -248,22 +251,34 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
/* VFC = disabled */
/* USB = disabled */
- cx18_write_reg(cx, lowpwr ? 0xFFFF0020 : 0x00060004,
- CX18_CLOCK_SELECT1);
- cx18_write_reg(cx, lowpwr ? 0xFFFF0004 : 0x00060006,
- CX18_CLOCK_SELECT2);
-
- cx18_write_reg(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
- cx18_write_reg(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
+ if (lowpwr) {
+ cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
+ 0x00000020, 0xFFFFFFFF);
+ cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
+ 0x00000004, 0xFFFFFFFF);
+ } else {
+ /* This doesn't explicitly set every clock select */
+ cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
+ 0x00000004, 0x00060006);
+ cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
+ 0x00000006, 0x00060006);
+ }
- cx18_write_reg(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1);
- cx18_write_reg(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2);
+ cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
+ 0x00000002, 0xFFFFFFFF);
+ cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
+ 0x00000104, 0xFFFFFFFF);
+ cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
+ 0x00009026, 0xFFFFFFFF);
+ cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
+ 0x00003105, 0xFFFFFFFF);
}
void cx18_init_memory(struct cx18 *cx)
{
cx18_msleep_timeout(10, 0);
- cx18_write_reg(cx, 0x10000, CX18_DDR_SOFT_RESET);
+ cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
+ 0x00000000, 0x00010001);
cx18_msleep_timeout(10, 0);
cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
@@ -282,13 +297,15 @@ void cx18_init_memory(struct cx18 *cx)
cx18_msleep_timeout(10, 0);
- cx18_write_reg(cx, 0x20000, CX18_DDR_SOFT_RESET);
+ cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
+ 0x00000000, 0x00020002);
cx18_msleep_timeout(10, 0);
/* use power-down mode when idle */
cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);
- cx18_write_reg(cx, 0x10001, CX18_REG_BUS_TIMEOUT_EN);
+ cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
+ 0x00000001, 0x00010001);
cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);
@@ -310,7 +327,9 @@ int cx18_firmware_init(struct cx18 *cx)
/* Allow chip to control CLKRUN */
cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);
- cx18_write_reg(cx, 0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
+ /* Stop the firmware */
+ cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
+ 0x0000000F, 0x000F000F);
cx18_msleep_timeout(1, 0);
@@ -325,7 +344,8 @@ int cx18_firmware_init(struct cx18 *cx)
cx18_write_enc(cx, 0xE51FF004, 0);
cx18_write_enc(cx, 0xa00000, 4); /* todo: not hardcoded */
/* Start APU */
- cx18_write_reg(cx, 0x00010000, CX18_PROC_SOFT_RESET);
+ cx18_write_reg_expect(cx, 0x00010000, CX18_PROC_SOFT_RESET,
+ 0x00000000, 0x00010001);
cx18_msleep_timeout(500, 0);
sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
@@ -335,7 +355,9 @@ int cx18_firmware_init(struct cx18 *cx)
int retries = 0;
/* start the CPU */
- cx18_write_reg(cx, 0x00080000, CX18_PROC_SOFT_RESET);
+ cx18_write_reg_expect(cx,
+ 0x00080000, CX18_PROC_SOFT_RESET,
+ 0x00000000, 0x00080008);
while (retries++ < 50) { /* Loop for max 500mS */
if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET)
& 1) == 0)
@@ -352,6 +374,6 @@ int cx18_firmware_init(struct cx18 *cx)
return -EIO;
}
/* initialize GPIO */
- cx18_write_reg(cx, 0x14001400, 0xC78110);
+ cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 0e560421989e..17b7a32fcc31 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -47,15 +47,21 @@
static void gpio_write(struct cx18 *cx)
{
- u32 dir = cx->gpio_dir;
- u32 val = cx->gpio_val;
-
- cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
- cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff),
- CX18_REG_GPIO_OUT1);
- cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2);
- cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
- CX18_REG_GPIO_OUT2);
+ u32 dir_lo = cx->gpio_dir & 0xffff;
+ u32 val_lo = cx->gpio_val & 0xffff;
+ u32 dir_hi = cx->gpio_dir >> 16;
+ u32 val_hi = cx->gpio_val >> 16;
+
+ cx18_write_reg_expect(cx, dir_lo << 16,
+ CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
+ cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
+ CX18_REG_GPIO_OUT1, val_lo, dir_lo);
+ cx18_write_reg_expect(cx, dir_hi << 16,
+ CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
+ cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
+ CX18_REG_GPIO_OUT2, val_hi, dir_hi);
+ if (!cx18_retry_mmio)
+ (void) cx18_read_reg(cx, CX18_REG_GPIO_OUT2); /* sync */
}
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index aa09e557b195..824efbecb34c 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -27,6 +27,7 @@
#include "cx18-gpio.h"
#include "cx18-av-core.h"
#include "cx18-i2c.h"
+#include "cx18-irq.h"
#define CX18_REG_I2C_1_WR 0xf15000
#define CX18_REG_I2C_1_RD 0xf15008
@@ -396,22 +397,31 @@ int init_cx18_i2c(struct cx18 *cx)
if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
/* Reset/Unreset I2C hardware block */
/* Clock select 220MHz */
- cx18_write_reg(cx, 0x10000000, 0xc71004);
+ cx18_write_reg_expect(cx, 0x10000000, 0xc71004,
+ 0x00000000, 0x10001000);
/* Clock Enable */
- cx18_write_reg_sync(cx, 0x10001000, 0xc71024);
+ cx18_write_reg_expect(cx, 0x10001000, 0xc71024,
+ 0x00001000, 0x10001000);
}
/* courtesy of Steven Toth <stoth@hauppauge.com> */
- cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
+ cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
+ if (!cx18_retry_mmio)
+ (void) cx18_read_reg(cx, 0xc7001c); /* sync */
mdelay(10);
- cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c);
+ cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
+ if (!cx18_retry_mmio)
+ (void) cx18_read_reg(cx, 0xc7001c); /* sync */
mdelay(10);
- cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c);
+ cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
+ if (!cx18_retry_mmio)
+ (void) cx18_read_reg(cx, 0xc7001c); /* sync */
mdelay(10);
/* Set to edge-triggered intrs. */
- cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8);
+ cx18_write_reg(cx, 0x00c00000, 0xc730c8);
/* Clear any stale intrs */
- cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4);
+ cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS,
+ ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
/* Hw I2C1 Clock Freq ~100kHz */
cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
index 220fae8d4ad7..0ad8dea3e600 100644
--- a/drivers/media/video/cx18/cx18-io.c
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -31,10 +31,10 @@ void cx18_log_statistics(struct cx18 *cx)
if (!(cx18_debug & CX18_DBGFLG_INFO))
return;
- for (i = 0; i <= CX18_MAX_MMIO_RETRIES; i++)
+ for (i = 0; i <= CX18_MAX_MMIO_WR_RETRIES; i++)
CX18_DEBUG_INFO("retried_write[%d] = %d\n", i,
atomic_read(&cx->mmio_stats.retried_write[i]));
- for (i = 0; i <= CX18_MAX_MMIO_RETRIES; i++)
+ for (i = 0; i <= CX18_MAX_MMIO_RD_RETRIES; i++)
CX18_DEBUG_INFO("retried_read[%d] = %d\n", i,
atomic_read(&cx->mmio_stats.retried_read[i]));
return;
@@ -43,7 +43,7 @@ void cx18_log_statistics(struct cx18 *cx)
void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
{
int i;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_raw_writel_noretry(cx, val, addr);
if (val == cx18_raw_readl_noretry(cx, addr))
break;
@@ -55,7 +55,7 @@ u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u32 val;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_raw_readl_noretry(cx, addr);
if (val != 0xffffffff) /* PCI bus read error */
break;
@@ -68,7 +68,7 @@ u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u16 val;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_raw_readw_noretry(cx, addr);
if (val != 0xffff) /* PCI bus read error */
break;
@@ -80,7 +80,7 @@ u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr)
void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
{
int i;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writel_noretry(cx, val, addr);
if (val == cx18_readl_noretry(cx, addr))
break;
@@ -93,7 +93,7 @@ void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
{
int i;
eval &= mask;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writel_noretry(cx, val, addr);
if (eval == (cx18_readl_noretry(cx, addr) & mask))
break;
@@ -104,7 +104,7 @@ void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr)
{
int i;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writew_noretry(cx, val, addr);
if (val == cx18_readw_noretry(cx, addr))
break;
@@ -115,7 +115,7 @@ void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr)
void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr)
{
int i;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writeb_noretry(cx, val, addr);
if (val == cx18_readb_noretry(cx, addr))
break;
@@ -127,7 +127,7 @@ u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u32 val;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_readl_noretry(cx, addr);
if (val != 0xffffffff) /* PCI bus read error */
break;
@@ -140,7 +140,7 @@ u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u16 val;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_readw_noretry(cx, addr);
if (val != 0xffff) /* PCI bus read error */
break;
@@ -153,7 +153,7 @@ u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u8 val;
- for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) {
+ for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_readb_noretry(cx, addr);
if (val != 0xff) /* PCI bus read error */
break;
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
index 425244453ea7..cb695a59670d 100644
--- a/drivers/media/video/cx18/cx18-io.h
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -41,8 +41,8 @@ static inline void cx18_io_delay(struct cx18 *cx)
static inline
void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr)
{
- if (i > CX18_MAX_MMIO_RETRIES)
- i = CX18_MAX_MMIO_RETRIES;
+ if (i > CX18_MAX_MMIO_WR_RETRIES)
+ i = CX18_MAX_MMIO_WR_RETRIES;
atomic_inc(&cx->mmio_stats.retried_write[i]);
return;
}
@@ -50,8 +50,8 @@ void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr)
static inline
void cx18_log_read_retries(struct cx18 *cx, int i, const void __iomem *addr)
{
- if (i > CX18_MAX_MMIO_RETRIES)
- i = CX18_MAX_MMIO_RETRIES;
+ if (i > CX18_MAX_MMIO_RD_RETRIES)
+ i = CX18_MAX_MMIO_RD_RETRIES;
atomic_inc(&cx->mmio_stats.retried_read[i]);
return;
}
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index de515dadadc2..451133ad41ff 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_CX25840
tristate "Conexant CX2584x audio/video decoders"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Conexant CX2584x audio/video decoders.
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 5bcbb4cc7c2a..733ede34f93a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1237,7 +1237,6 @@ static const struct cx88_board cx88_boards[] = {
},
},
[CX88_BOARD_WINFAST_DTV2000H] = {
- /* video inputs and radio still in testing */
.name = "WinFast DTV2000 H",
.tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
.radio_type = UNSET,
@@ -1251,7 +1250,35 @@ static const struct cx88_board cx88_boards[] = {
.gpio1 = 0x00008203,
.gpio2 = 0x00017304,
.gpio3 = 0x02000000,
+ }, {
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x0001d701,
+ .gpio1 = 0x0000b207,
+ .gpio2 = 0x0001d701,
+ .gpio3 = 0x02000000,
+ }, {
+ .type = CX88_VMUX_COMPOSITE2,
+ .vmux = 2,
+ .gpio0 = 0x0001d503,
+ .gpio1 = 0x0000b207,
+ .gpio2 = 0x0001d503,
+ .gpio3 = 0x02000000,
+ }, {
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 3,
+ .gpio0 = 0x0001d701,
+ .gpio1 = 0x0000b207,
+ .gpio2 = 0x0001d701,
+ .gpio3 = 0x02000000,
}},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x00015702,
+ .gpio1 = 0x0000f207,
+ .gpio2 = 0x00015702,
+ .gpio3 = 0x02000000,
+ },
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_GENIATECH_DVBS] = {
@@ -1847,6 +1874,18 @@ static const struct cx88_board cx88_boards[] = {
} },
.mpeg = CX88_MPEG_DVB,
},
+ [CX88_BOARD_TBS_8910] = {
+ .name = "TBS 8910 DVB-S",
+ .tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ } },
+ .mpeg = CX88_MPEG_DVB,
+ },
[CX88_BOARD_TBS_8920] = {
.name = "TBS 8920 DVB-S/S2",
.tuner_type = TUNER_ABSENT,
@@ -1859,6 +1898,18 @@ static const struct cx88_board cx88_boards[] = {
} },
.mpeg = CX88_MPEG_DVB,
},
+ [CX88_BOARD_PROF_6200] = {
+ .name = "Prof 6200 DVB-S",
+ .tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ } },
+ .mpeg = CX88_MPEG_DVB,
+ },
[CX88_BOARD_PROF_7300] = {
.name = "PROF 7300 DVB-S/S2",
.tuner_type = UNSET,
@@ -1871,6 +1922,18 @@ static const struct cx88_board cx88_boards[] = {
} },
.mpeg = CX88_MPEG_DVB,
},
+ [CX88_BOARD_SATTRADE_ST4200] = {
+ .name = "SATTRADE ST4200 DVB-S/S2",
+ .tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_DVB,
+ .vmux = 0,
+ } },
+ .mpeg = CX88_MPEG_DVB,
+ },
};
/* ------------------------------------------------------------------ */
@@ -1897,7 +1960,11 @@ static const struct cx88_subid cx88_subids[] = {
.subvendor = PCI_VENDOR_ID_ATI,
.subdevice = 0x00f8,
.card = CX88_BOARD_ATI_WONDER_PRO,
- },{
+ }, {
+ .subvendor = PCI_VENDOR_ID_ATI,
+ .subdevice = 0x00f9,
+ .card = CX88_BOARD_ATI_WONDER_PRO,
+ }, {
.subvendor = 0x107d,
.subdevice = 0x6611,
.card = CX88_BOARD_WINFAST2000XP_EXPERT,
@@ -2257,13 +2324,25 @@ static const struct cx88_subid cx88_subids[] = {
.subdevice = 0x2011,
.card = CX88_BOARD_OMICOM_SS4_PCI,
}, {
+ .subvendor = 0x8910,
+ .subdevice = 0x8888,
+ .card = CX88_BOARD_TBS_8910,
+ }, {
.subvendor = 0x8920,
.subdevice = 0x8888,
.card = CX88_BOARD_TBS_8920,
}, {
+ .subvendor = 0xb022,
+ .subdevice = 0x3022,
+ .card = CX88_BOARD_PROF_6200,
+ }, {
.subvendor = 0xB033,
.subdevice = 0x3033,
.card = CX88_BOARD_PROF_7300,
+ }, {
+ .subvendor = 0xb200,
+ .subdevice = 0x4200,
+ .card = CX88_BOARD_SATTRADE_ST4200,
},
};
@@ -2874,8 +2953,11 @@ static void cx88_card_setup(struct cx88_core *core)
case CX88_BOARD_TEVII_S420:
case CX88_BOARD_TEVII_S460:
case CX88_BOARD_OMICOM_SS4_PCI:
+ case CX88_BOARD_TBS_8910:
case CX88_BOARD_TBS_8920:
+ case CX88_BOARD_PROF_6200:
case CX88_BOARD_PROF_7300:
+ case CX88_BOARD_SATTRADE_ST4200:
cx_write(MO_SRST_IO, 0);
msleep(100);
cx_write(MO_SRST_IO, 1);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 60705b08bfe8..b045874ad04f 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -844,6 +844,9 @@ static int set_tvaudio(struct cx88_core *core)
} else if (V4L2_STD_SECAM_L & norm) {
core->tvaudio = WW_L;
+ } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) {
+ core->tvaudio = WW_BG;
+
} else if (V4L2_STD_SECAM_DK & norm) {
core->tvaudio = WW_DK;
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 309ca5e68063..462947319dda 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -406,7 +406,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
cx_write(MO_GP0_IO, 0x00006060);
break;
case SEC_VOLTAGE_OFF:
- printk("LNB Voltage SEC_VOLTAGE_off\n");
+ printk("LNB Voltage SEC_VOLTAGE_off\n");
break;
}
@@ -1042,6 +1042,8 @@ static int dvb_register(struct cx8802_dev *dev)
0x08, ISL6421_DCL, 0x00);
}
break;
+ case CX88_BOARD_PROF_6200:
+ case CX88_BOARD_TBS_8910:
case CX88_BOARD_TEVII_S420:
fe0->dvb.frontend = dvb_attach(stv0299_attach,
&tevii_tuner_sharp_config,
@@ -1070,21 +1072,18 @@ static int dvb_register(struct cx8802_dev *dev)
fe0->dvb.frontend = dvb_attach(cx24116_attach,
&tevii_s460_config,
&core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ if (fe0->dvb.frontend != NULL)
fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
- }
break;
case CX88_BOARD_OMICOM_SS4_PCI:
case CX88_BOARD_TBS_8920:
case CX88_BOARD_PROF_7300:
+ case CX88_BOARD_SATTRADE_ST4200:
fe0->dvb.frontend = dvb_attach(cx24116_attach,
&hauppauge_hvr4000_config,
&core->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ if (fe0->dvb.frontend != NULL)
fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
- }
break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
@@ -1092,7 +1091,7 @@ static int dvb_register(struct cx8802_dev *dev)
break;
}
- if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
+ if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
printk(KERN_ERR
"%s/2: frontend initialization failed\n",
core->name);
@@ -1199,8 +1198,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
struct cx8802_dev *dev = drv->core->dvbdev;
- int err, i;
- struct videobuf_dvb_frontend *fe;
+ int err;
dprintk( 1, "%s\n", __func__);
dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1216,31 +1214,47 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
/* If vp3054 isn't enabled, a stub will just return 0 */
err = vp3054_i2c_probe(dev);
if (0 != err)
- goto fail_core;
+ goto fail_probe;
/* dvb stuff */
printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
dev->ts_gen_cntrl = 0x0c;
- for (i = 1; i <= core->board.num_frontends; i++) {
- fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
- if (!fe) {
- printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i);
- continue;
+ err = -ENODEV;
+ if (core->board.num_frontends) {
+ struct videobuf_dvb_frontend *fe;
+ int i;
+
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+ if (fe == NULL) {
+ printk(KERN_ERR "%s() failed to get frontend(%d)\n",
+ __func__, i);
+ goto fail_probe;
+ }
+ videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
+ &dev->pci->dev, &dev->slock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_TOP,
+ sizeof(struct cx88_buffer),
+ dev);
+ /* init struct videobuf_dvb */
+ fe->dvb.name = dev->core->name;
}
- videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_TOP,
- sizeof(struct cx88_buffer),
- dev);
- /* init struct videobuf_dvb */
- fe->dvb.name = dev->core->name;
+ } else {
+ /* no frontends allocated */
+ printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
+ core->name);
+ goto fail_core;
}
err = dvb_register(dev);
- if (err != 0)
+ if (err)
+ /* frontends/adapter de-allocated in dvb_register */
printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
core->name, err);
+ return err;
+fail_probe:
+ videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
fail_core:
return err;
}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f4240965be32..20649b25f7ba 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -53,12 +53,11 @@
/* ----------------------------------------------------------- */
/* defines and enums */
-/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
-#define CX88_NORMS (\
- V4L2_STD_NTSC_M| V4L2_STD_NTSC_M_JP| V4L2_STD_NTSC_443 | \
- V4L2_STD_PAL_BG| V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
- V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \
- V4L2_STD_PAL_60| V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK )
+/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM/LC */
+#define CX88_NORMS (V4L2_STD_ALL \
+ & ~V4L2_STD_PAL_H \
+ & ~V4L2_STD_NTSC_M_KR \
+ & ~V4L2_STD_SECAM_LC)
#define FORMAT_FLAGS_PACKED 0x01
#define FORMAT_FLAGS_PLANAR 0x02
@@ -229,6 +228,9 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_TEVII_S420 73
#define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74
#define CX88_BOARD_PROF_7300 75
+#define CX88_BOARD_SATTRADE_ST4200 76
+#define CX88_BOARD_TBS_8910 77
+#define CX88_BOARD_PROF_6200 78
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index ac3292d7646c..e1fa3bfd1def 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -429,7 +429,7 @@ static int em28xx_audio_init(struct em28xx *dev)
if (dev->has_audio_class) {
/* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module */
+ the device is expecting the snd-usb-audio module) */
return 0;
}
@@ -450,7 +450,12 @@ static int em28xx_audio_init(struct em28xx *dev)
}
spin_lock_init(&adev->slock);
- ret = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
+ err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
pcm->info_flags = 0;
pcm->private_data = dev;
@@ -462,7 +467,7 @@ static int em28xx_audio_init(struct em28xx *dev)
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
- return -ENOMEM;
+ return err;
}
adev->sndcard = card;
adev->udev = dev->udev;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index a1ab2ef45578..bbd59ded45e1 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1269,7 +1269,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info));
+ strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
@@ -1422,7 +1422,7 @@ static int radio_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info));
+ strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
cap->capabilities = V4L2_CAP_TUNER;
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 9d0ef96c23ff..83c07112c59d 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1581,7 +1581,7 @@ et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
+ strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
sizeof(cap.bus_info));
if (copy_to_user(arg, &cap, sizeof(cap)))
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 65d3cbfe6b27..d3e3f085b7bb 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -308,9 +308,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int ret;
int size_ret;
- /* Reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
-
/* Init the device */
memset(gspca_dev->usb_buf, 0, 12);
gspca_dev->usb_buf[0] = 0xc6;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index e48fbfc8ad05..2880f05b3d7e 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -45,7 +45,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0)
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
static int video_nr = -1;
@@ -150,8 +150,11 @@ static void fill_frame(struct gspca_dev *gspca_dev,
/* check the packet status and length */
len = urb->iso_frame_desc[i].actual_length;
- if (len == 0)
+ if (len == 0) {
+ if (gspca_dev->empty_packet == 0)
+ gspca_dev->empty_packet = 1;
continue;
+ }
st = urb->iso_frame_desc[i].status;
if (st) {
PDEBUG(D_ERR,
@@ -597,6 +600,12 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (ret < 0)
goto out;
+ /* clear the bulk endpoint */
+ if (gspca_dev->alt == 0) /* if bulk transfer */
+ usb_clear_halt(gspca_dev->dev,
+ usb_rcvintpipe(gspca_dev->dev,
+ gspca_dev->cam.epaddr));
+
/* start the cam */
ret = gspca_dev->sd_desc->start(gspca_dev);
if (ret < 0) {
@@ -1850,6 +1859,7 @@ int gspca_dev_probe(struct usb_interface *intf,
gspca_dev->nbalt = intf->num_altsetting;
gspca_dev->sd_desc = sd_desc;
gspca_dev->nbufread = 2;
+ gspca_dev->empty_packet = -1; /* don't check the empty packets */
/* configure the subdriver and initialize the USB device */
ret = gspca_dev->sd_desc->config(gspca_dev, id);
@@ -1988,7 +1998,7 @@ int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
desired lumination fast (with the risc of a slight overshoot) */
steps = abs(desired_avg_lum - avg_lum) / deadzone;
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n",
+ PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
avg_lum, desired_avg_lum, steps);
for (i = 0; i < steps; i++) {
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 1d9dc90b4791..6f097f4a1385 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -142,22 +142,21 @@ struct gspca_dev {
char fr_q; /* next frame to queue */
char fr_o; /* next frame to dequeue */
signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
- char last_packet_type;
+ __u8 last_packet_type;
+ __s8 empty_packet; /* if (-1) don't check empty packets */
+ __u8 streaming;
- __u8 iface; /* USB interface number */
- __u8 alt; /* USB alternate setting */
__u8 curr_mode; /* current camera mode */
__u32 pixfmt; /* current mode parameters */
__u16 width;
__u16 height;
+ __u32 sequence; /* frame sequence number */
atomic_t nevent; /* number of frames done */
wait_queue_head_t wq; /* wait queue */
struct mutex usb_lock; /* usb exchange protection */
struct mutex read_lock; /* read protection */
struct mutex queue_lock; /* ISOC queue protection */
- __u32 sequence; /* frame sequence number */
- char streaming;
#ifdef CONFIG_PM
char frozen; /* suspend - resume */
#endif
@@ -166,6 +165,8 @@ struct gspca_dev {
char nbufread; /* number of buffers for read() */
char nurbs; /* number of allocated URBs */
char memory; /* memory type (V4L2_MEMORY_xxx) */
+ __u8 iface; /* USB interface number */
+ __u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
};
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ca671194679e..27bf7480a2d4 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -40,22 +40,18 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
/* Determined by sensor type */
- char sif;
+ __u8 sif;
- unsigned char primary_i2c_slave; /* I2C write id of sensor */
-
- unsigned char brightness;
- unsigned char contrast;
- unsigned char colors;
+ __u8 brightness;
+ __u8 contrast;
+ __u8 colors;
__u8 hflip;
__u8 vflip;
- char compress; /* Should the next frame be compressed? */
- char compress_inited; /* Are compression params uploaded? */
- char stopped; /* Streaming is temporarily paused */
+ __u8 stopped; /* Streaming is temporarily paused */
- char frame_rate; /* current Framerate (OV519 only) */
- char clockdiv; /* clockdiv override for OV519 only */
+ __u8 frame_rate; /* current Framerate (OV519 only) */
+ __u8 clockdiv; /* clockdiv override for OV519 only */
char sensor; /* Type of image sensor chip (SEN_*) */
#define SEN_UNKNOWN 0
@@ -67,7 +63,6 @@ struct sd {
#define SEN_OV7670 6
#define SEN_OV76BE 7
#define SEN_OV8610 8
-
};
/* V4L2 controls supported by the driver */
@@ -184,15 +179,15 @@ static struct v4l2_pix_format sif_mode[] = {
};
/* OV519 Camera interface register numbers */
-#define OV519_CAM_H_SIZE 0x10
-#define OV519_CAM_V_SIZE 0x11
-#define OV519_CAM_X_OFFSETL 0x12
-#define OV519_CAM_X_OFFSETH 0x13
-#define OV519_CAM_Y_OFFSETL 0x14
-#define OV519_CAM_Y_OFFSETH 0x15
-#define OV519_CAM_DIVIDER 0x16
-#define OV519_CAM_DFR 0x20
-#define OV519_CAM_FORMAT 0x25
+#define OV519_R10_H_SIZE 0x10
+#define OV519_R11_V_SIZE 0x11
+#define OV519_R12_X_OFFSETL 0x12
+#define OV519_R13_X_OFFSETH 0x13
+#define OV519_R14_Y_OFFSETL 0x14
+#define OV519_R15_Y_OFFSETH 0x15
+#define OV519_R16_DIVIDER 0x16
+#define OV519_R20_DFR 0x20
+#define OV519_R25_FORMAT 0x25
/* OV519 System Controller register numbers */
#define OV519_SYS_RESET1 0x51
@@ -562,8 +557,8 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ OV7670_REG_VSTOP, 0x7a },
{ OV7670_REG_VREF, 0x0a },
- { OV7670_REG_COM3, 0 },
- { OV7670_REG_COM14, 0 },
+ { OV7670_REG_COM3, 0x00 },
+ { OV7670_REG_COM14, 0x00 },
/* Mystery scaling numbers */
{ 0x70, 0x3a },
{ 0x71, 0x35 },
@@ -595,8 +590,8 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ OV7670_REG_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT },
- { OV7670_REG_GAIN, 0 },
- { OV7670_REG_AECH, 0 },
+ { OV7670_REG_GAIN, 0x00 },
+ { OV7670_REG_AECH, 0x00 },
{ OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
{ OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
{ OV7670_REG_BD50MAX, 0x05 },
@@ -634,16 +629,16 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ OV7670_REG_COM12, 0x78 },
{ 0x4d, 0x40 },
{ 0x4e, 0x20 },
- { OV7670_REG_GFIX, 0 },
+ { OV7670_REG_GFIX, 0x00 },
{ 0x6b, 0x4a },
{ 0x74, 0x10 },
{ 0x8d, 0x4f },
- { 0x8e, 0 },
- { 0x8f, 0 },
- { 0x90, 0 },
- { 0x91, 0 },
- { 0x96, 0 },
- { 0x9a, 0 },
+ { 0x8e, 0x00 },
+ { 0x8f, 0x00 },
+ { 0x90, 0x00 },
+ { 0x91, 0x00 },
+ { 0x96, 0x00 },
+ { 0x9a, 0x00 },
{ 0xb0, 0x84 },
{ 0xb1, 0x0c },
{ 0xb2, 0x0e },
@@ -681,17 +676,17 @@ static const struct ov_i2c_regvals norm_7670[] = {
/* Matrix coefficients */
{ 0x4f, 0x80 },
{ 0x50, 0x80 },
- { 0x51, 0 },
+ { 0x51, 0x00 },
{ 0x52, 0x22 },
{ 0x53, 0x5e },
{ 0x54, 0x80 },
{ 0x58, 0x9e },
{ OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
- { OV7670_REG_EDGE, 0 },
+ { OV7670_REG_EDGE, 0x00 },
{ 0x75, 0x05 },
{ 0x76, 0xe1 },
- { 0x4c, 0 },
+ { 0x4c, 0x00 },
{ 0x77, 0x01 },
{ OV7670_REG_COM13, OV7670_COM13_GAMMA
| OV7670_COM13_UVSAT
@@ -704,7 +699,7 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x34, 0x11 },
{ OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
{ 0xa4, 0x88 },
- { 0x96, 0 },
+ { 0x96, 0x00 },
{ 0x97, 0x30 },
{ 0x98, 0x20 },
{ 0x99, 0x30 },
@@ -942,11 +937,11 @@ static int i2c_w(struct sd *sd,
/* Initiate 3-byte write cycle */
rc = reg_w(sd, R518_I2C_CTL, 0x01);
+ if (rc < 0)
+ return rc;
/* wait for write complete */
msleep(4);
- if (rc < 0)
- return rc;
return reg_r8(sd, R518_I2C_CTL);
}
@@ -1029,7 +1024,7 @@ static inline int ov51x_restart(struct sd *sd)
*/
static int init_ov_sensor(struct sd *sd)
{
- int i, success;
+ int i;
/* Reset the sensor */
if (i2c_w(sd, 0x12, 0x80) < 0)
@@ -1038,11 +1033,11 @@ static int init_ov_sensor(struct sd *sd)
/* Wait for it to initialize */
msleep(150);
- for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
+ for (i = 0; i < i2c_detect_tries; i++) {
if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
- success = 1;
- continue;
+ PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
+ return 0;
}
/* Reset the sensor */
@@ -1054,10 +1049,7 @@ static int init_ov_sensor(struct sd *sd)
if (i2c_r(sd, 0x00) < 0)
return -EIO;
}
- if (!success)
- return -EIO;
- PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
- return 0;
+ return -EIO;
}
/* Set the read and write slave IDs. The "slave" argument is the write slave,
@@ -1073,7 +1065,6 @@ static int ov51x_set_slave_ids(struct sd *sd,
rc = reg_w(sd, R51x_I2C_W_SID, slave);
if (rc < 0)
return rc;
- sd->primary_i2c_slave = slave;
return reg_w(sd, R51x_I2C_R_SID, slave + 1);
}
@@ -1285,7 +1276,6 @@ static int ov6xx0_configure(struct sd *sd)
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
static void ov51x_led_control(struct sd *sd, int on)
{
-/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
}
@@ -1352,7 +1342,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
if (ov8xx0_configure(sd) < 0) {
PDEBUG(D_ERR,
- "Failed to configure OV8xx0 sensor");
+ "Failed to configure OV8xx0 sensor");
goto error;
}
}
@@ -1482,7 +1472,7 @@ static int ov519_mode_init_regs(struct sd *sd)
return -EIO;
if (sd->sensor == SEN_OV7640) {
/* Select 8-bit input mode */
- reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
+ reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
}
} else {
if (write_regvals(sd, mode_init_519_ov7670,
@@ -1490,14 +1480,14 @@ static int ov519_mode_init_regs(struct sd *sd)
return -EIO;
}
- reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4);
- reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3);
- reg_w(sd, OV519_CAM_X_OFFSETL, 0x00);
- reg_w(sd, OV519_CAM_X_OFFSETH, 0x00);
- reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00);
- reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00);
- reg_w(sd, OV519_CAM_DIVIDER, 0x00);
- reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */
+ reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
+ reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
+ reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
+ reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
+ reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
+ reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
+ reg_w(sd, OV519_R16_DIVIDER, 0x00);
+ reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
reg_w(sd, 0x26, 0x00); /* Undocumented */
/******** Set the framerate ********/
@@ -1509,8 +1499,8 @@ static int ov519_mode_init_regs(struct sd *sd)
switch (sd->sensor) {
case SEN_OV7640:
switch (sd->frame_rate) {
-/*fixme: default was 30 fps */
- case 30:
+ default:
+/* case 30: */
reg_w(sd, 0xa4, 0x0c);
reg_w(sd, 0x23, 0xff);
break;
@@ -1522,8 +1512,7 @@ static int ov519_mode_init_regs(struct sd *sd)
reg_w(sd, 0xa4, 0x0c);
reg_w(sd, 0x23, 0x1b);
break;
- default:
-/* case 15: */
+ case 15:
reg_w(sd, 0xa4, 0x04);
reg_w(sd, 0x23, 0xff);
sd->clockdiv = 1;
@@ -1576,7 +1565,6 @@ static int ov519_mode_init_regs(struct sd *sd)
}
break;
}
-
return 0;
}
@@ -1667,7 +1655,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
* the gain or the contrast. The "reserved" bits seem
* to have some effect in this case. */
i2c_w(sd, 0x2d, 0x85);
- } else if (sd->clockdiv >= 0) {
+ } else {
i2c_w(sd, 0x11, sd->clockdiv);
}
@@ -1869,7 +1857,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
ret = ov51x_restart(sd);
if (ret < 0)
goto out;
- PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
ov51x_led_control(sd, 1);
return 0;
out:
@@ -1879,8 +1866,10 @@ out:
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- ov51x_stop((struct sd *) gspca_dev);
- ov51x_led_control((struct sd *) gspca_dev, 0);
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ ov51x_stop(sd);
+ ov51x_led_control(sd, 0);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -1935,9 +1924,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
int val;
val = sd->brightness;
- PDEBUG(D_CONF, "brightness:%d", val);
-/* if (gspca_dev->streaming)
- * ov51x_stop(sd); */
switch (sd->sensor) {
case SEN_OV8610:
case SEN_OV7610:
@@ -1959,8 +1945,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
break;
}
-/* if (gspca_dev->streaming)
- * ov51x_restart(sd); */
}
static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1969,9 +1953,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
int val;
val = sd->contrast;
- PDEBUG(D_CONF, "contrast:%d", val);
-/* if (gspca_dev->streaming)
- ov51x_stop(sd); */
switch (sd->sensor) {
case SEN_OV7610:
case SEN_OV6620:
@@ -2007,8 +1988,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
break;
}
-/* if (gspca_dev->streaming)
- ov51x_restart(sd); */
}
static void setcolors(struct gspca_dev *gspca_dev)
@@ -2017,9 +1996,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
int val;
val = sd->colors;
- PDEBUG(D_CONF, "saturation:%d", val);
-/* if (gspca_dev->streaming)
- ov51x_stop(sd); */
switch (sd->sensor) {
case SEN_OV8610:
case SEN_OV7610:
@@ -2044,8 +2020,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
/* set REG_COM13 values for UV sat auto mode */
break;
}
-/* if (gspca_dev->streaming)
- ov51x_restart(sd); */
}
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2053,7 +2027,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
struct sd *sd = (struct sd *) gspca_dev;
sd->brightness = val;
- setbrightness(gspca_dev);
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
return 0;
}
@@ -2070,7 +2045,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
struct sd *sd = (struct sd *) gspca_dev;
sd->contrast = val;
- setcontrast(gspca_dev);
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
return 0;
}
@@ -2087,7 +2063,8 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
struct sd *sd = (struct sd *) gspca_dev;
sd->colors = val;
- setcolors(gspca_dev);
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
return 0;
}
@@ -2104,7 +2081,8 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
struct sd *sd = (struct sd *) gspca_dev;
sd->hflip = val;
- sethvflip(sd);
+ if (gspca_dev->streaming)
+ sethvflip(sd);
return 0;
}
@@ -2121,7 +2099,8 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
struct sd *sd = (struct sd *) gspca_dev;
sd->vflip = val;
- sethvflip(sd);
+ if (gspca_dev->streaming)
+ sethvflip(sd);
return 0;
}
@@ -2162,7 +2141,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x05a9, 0x8519)},
{}
};
-#undef DVNAME
+
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 0b0c573d06da..39473e6b9140 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -536,6 +536,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2471)},
{USB_DEVICE(0x093a, 0x2472)},
{USB_DEVICE(0x093a, 0x2476)},
+ {USB_DEVICE(0x145f, 0x013a)},
{USB_DEVICE(0x2001, 0xf115)},
{}
};
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 6c69bc7778fc..ffa714fde85c 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -132,8 +132,6 @@ struct sensor_data {
ignore atleast the 2 next frames for the new settings to come into effect
before doing any other adjustments */
#define AUTOGAIN_IGNORE_FRAMES 3
-#define AUTOGAIN_DEADZONE 1000
-#define DESIRED_AVG_LUM 7000
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -827,18 +825,29 @@ static void setfreq(struct gspca_dev *gspca_dev)
static void do_autogain(struct gspca_dev *gspca_dev)
{
+ int deadzone, desired_avg_lum;
struct sd *sd = (struct sd *) gspca_dev;
int avg_lum = atomic_read(&sd->avg_lum);
if (avg_lum == -1)
return;
+ /* SIF / VGA sensors have a different autoexposure area and thus
+ different avg_lum values for the same picture brightness */
+ if (sensor_data[sd->sensor].flags & F_SIF) {
+ deadzone = 1000;
+ desired_avg_lum = 7000;
+ } else {
+ deadzone = 3000;
+ desired_avg_lum = 23000;
+ }
+
if (sd->autogain_ignore_frames > 0)
sd->autogain_ignore_frames--;
else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
- sd->brightness * DESIRED_AVG_LUM / 127,
- AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
- PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
+ sd->brightness * desired_avg_lum / 127,
+ deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
+ PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
(int)sd->gain, (int)sd->exposure);
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
}
@@ -1226,8 +1235,8 @@ static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
- {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
#endif
+ {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 53cb82d9e7c6..a7954a72e4b9 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -24,6 +24,8 @@
#include "gspca.h"
#include "jpeg.h"
+#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
+
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -40,6 +42,7 @@ struct sd {
unsigned char colors;
unsigned char autogain;
__u8 vflip; /* ov7630 only */
+ __u8 infrared; /* mi0360 only */
signed char ag_cnt;
#define AG_CNT_START 13
@@ -73,6 +76,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
{
@@ -150,6 +155,22 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setvflip,
.get = sd_getvflip,
},
+/* mi0360 only */
+#define INFRARED_IDX 5
+ {
+ {
+ .id = V4L2_CID_INFRARED,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Infrared",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define INFRARED_DEF 0
+ .default_value = INFRARED_DEF,
+ },
+ .set = sd_setinfrared,
+ .get = sd_getinfrared,
+ },
};
static struct v4l2_pix_format vga_mode[] = {
@@ -963,6 +984,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->colors = COLOR_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->ag_cnt = -1;
+ sd->vflip = VFLIP_DEF;
+ sd->infrared = INFRARED_DEF;
switch (sd->sensor) {
case SENSOR_OV7630:
@@ -973,7 +996,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
if (sd->sensor != SENSOR_OV7630)
gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
-
+ if (sd->sensor != SENSOR_MI0360)
+ gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
return 0;
}
@@ -1195,12 +1219,18 @@ static void setautogain(struct gspca_dev *gspca_dev)
static void setvflip(struct sd *sd)
{
- if (sd->sensor != SENSOR_OV7630)
- return;
i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
sd->vflip ? 0x82 : 0x02);
}
+static void setinfrared(struct sd *sd)
+{
+/*fixme: different sequence for StarCam Clip and StarCam 370i */
+/* Clip */
+ i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
+ sd->infrared ? 0x66 : 0x64);
+}
+
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
@@ -1343,8 +1373,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x17, reg17);
switch (sd->sensor) {
- case SENSOR_HV7131R:
case SENSOR_MI0360:
+ setinfrared(sd);
+ /* fall thru */
+ case SENSOR_HV7131R:
case SENSOR_MO4000:
case SENSOR_OM6802:
setbrightness(gspca_dev);
@@ -1598,6 +1630,24 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->infrared = val;
+ if (gspca_dev->streaming)
+ setinfrared(sd);
+ return 0;
+}
+
+static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->infrared;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1623,8 +1673,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
- {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
#endif
+ {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
/* bw600.inf:
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 968a5911704f..3eac1cb88520 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -30,15 +30,10 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- int buflen; /* current length of tmpbuf */
- __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */
- __u8 tmpbuf2[352 * 288]; /* no protection... */
+ __u16 brightness;
+ __u16 contrast;
- unsigned short brightness;
- unsigned short contrast;
-
- char packet;
- char synchro;
+ __u8 packet;
};
/* V4L2 controls supported by the driver */
@@ -392,6 +387,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
tv_8532ReadRegisters(gspca_dev);
@@ -443,6 +440,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
/************************************************/
tv_8532_PollReg(gspca_dev);
reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+
+ gspca_dev->empty_packet = 0; /* check the empty packets */
+ sd->packet = 0; /* ignore the first packets */
+
return 0;
}
@@ -451,111 +452,36 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
}
-static void tv8532_preprocess(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-/* we should received a whole frame with header and EOL marker
- * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2
- * sequence 2bytes header the Alternate pixels bayer GB 4 bytes
- * Alternate pixels bayer RG 4 bytes EOL */
- int width = gspca_dev->width;
- int height = gspca_dev->height;
- unsigned char *dst = sd->tmpbuf2;
- unsigned char *data = sd->tmpbuf;
- int i;
-
- /* precompute where is the good bayer line */
- if (((data[3] + data[width + 7]) >> 1)
- + (data[4] >> 2)
- + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)
- + (data[3] >> 2)
- + (data[width + 5] >> 1))
- data += 3;
- else
- data += 2;
- for (i = 0; i < height / 2; i++) {
- memcpy(dst, data, width);
- data += width + 3;
- dst += width;
- memcpy(dst, data, width);
- data += width + 7;
- dst += width;
- }
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
-
- if (data[0] != 0x80) {
- sd->packet++;
- if (sd->buflen + len > sizeof sd->tmpbuf) {
- if (gspca_dev->last_packet_type != DISCARD_PACKET) {
- PDEBUG(D_PACK, "buffer overflow");
- gspca_dev->last_packet_type = DISCARD_PACKET;
- }
- return;
- }
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
- return;
- }
-
- /* here we detect 0x80 */
- /* counter is limited so we need few header for a frame :) */
-
- /* header 0x80 0x80 0x80 0x80 0x80 */
- /* packet 00 63 127 145 00 */
- /* sof 0 1 1 0 0 */
-
- /* update sequence */
- if (sd->packet == 63 || sd->packet == 127)
- sd->synchro = 1;
-
- /* is there a frame start ? */
- if (sd->packet >= (gspca_dev->height >> 1) - 1) {
- PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro,
- sd->packet);
- if (!sd->synchro) { /* start of frame */
- if (gspca_dev->last_packet_type == FIRST_PACKET) {
- tv8532_preprocess(gspca_dev);
- frame = gspca_frame_add(gspca_dev,
- LAST_PACKET,
- frame, sd->tmpbuf2,
- gspca_dev->width *
- gspca_dev->width);
- }
- gspca_frame_add(gspca_dev, FIRST_PACKET,
- frame, data, 0);
- memcpy(sd->tmpbuf, data, len);
- sd->buflen = len;
- sd->packet = 0;
- return;
- }
- if (gspca_dev->last_packet_type != DISCARD_PACKET) {
- PDEBUG(D_PACK,
- "Warning wrong TV8532 frame detection %d",
- sd->packet);
- gspca_dev->last_packet_type = DISCARD_PACKET;
- }
- return;
- }
-
- if (!sd->synchro) {
- /* Drop packet frame corrupt */
- PDEBUG(D_PACK, "DROP SOF %d packet %d",
- sd->synchro, sd->packet);
- sd->packet = 0;
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- sd->synchro = 1;
- sd->packet++;
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
+ int packet_type0, packet_type1;
+
+ packet_type0 = packet_type1 = INTER_PACKET;
+ if (gspca_dev->empty_packet) {
+ gspca_dev->empty_packet = 0;
+ sd->packet = gspca_dev->height / 2;
+ packet_type0 = FIRST_PACKET;
+ } else if (sd->packet == 0)
+ return; /* 2 more lines in 352x288 ! */
+ sd->packet--;
+ if (sd->packet == 0)
+ packet_type1 = LAST_PACKET;
+
+ /* each packet contains:
+ * - header 2 bytes
+ * - RG line
+ * - 4 bytes
+ * - GB line
+ * - 4 bytes
+ */
+ gspca_frame_add(gspca_dev, packet_type0,
+ frame, data + 2, gspca_dev->width);
+ gspca_frame_add(gspca_dev, packet_type1,
+ frame, data + gspca_dev->width + 6, gspca_dev->width);
}
static void setcontrast(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 8b3101d347c3..c7d098b625c6 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -2310,67 +2310,6 @@ static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
{0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
- {0xa1, 0x01, 0x0002},
- {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
- {0xa1, 0x01, 0x0091},
- {0xa1, 0x01, 0x0095},
- {0xa1, 0x01, 0x0096},
-
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
-
- {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf8, ZC3XX_R10B_RGB01},
- {0xa0, 0xf8, ZC3XX_R10C_RGB02},
- {0xa0, 0xf8, ZC3XX_R10D_RGB10},
- {0xa0, 0x50, ZC3XX_R10E_RGB11},
- {0xa0, 0xf8, ZC3XX_R10F_RGB12},
- {0xa0, 0xf8, ZC3XX_R110_RGB20},
- {0xa0, 0xf8, ZC3XX_R111_RGB21},
- {0xa0, 0x50, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x25, 0x0007},
- {0xaa, 0x26, 0x00a1},
- {0xaa, 0x27, 0x0020},
- {0xaa, 0x20, 0x0000},
- {0xaa, 0x21, 0x00a0},
- {0xaa, 0x22, 0x0016},
- {0xaa, 0x23, 0x0040},
-
- {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
- {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x07, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x16, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x40, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa1, 0x01, 0x001d},
- {0xa1, 0x01, 0x001e},
- {0xa1, 0x01, 0x001f},
- {0xa1, 0x01, 0x0020},
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
-/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
{}
};
@@ -2418,65 +2357,156 @@ static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
{0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */
- {0xa1, 0x01, 0x0002},
- {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
- {0xa1, 0x01, 0x0091},
- {0xa1, 0x01, 0x0095},
- {0xa1, 0x01, 0x0096},
- {0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa1, 0x01, 0x01c8},
- {0xa1, 0x01, 0x01c9},
- {0xa1, 0x01, 0x01ca},
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
-
- {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf8, ZC3XX_R10B_RGB01},
- {0xa0, 0xf8, ZC3XX_R10C_RGB02},
- {0xa0, 0xf8, ZC3XX_R10D_RGB10},
- {0xa0, 0x50, ZC3XX_R10E_RGB11},
- {0xa0, 0xf8, ZC3XX_R10F_RGB12},
- {0xa0, 0xf8, ZC3XX_R110_RGB20},
- {0xa0, 0xf8, ZC3XX_R111_RGB21},
- {0xa0, 0x50, ZC3XX_R112_RGB22},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xaa, 0x25, 0x0007},
- {0xaa, 0x26, 0x00a1},
- {0xaa, 0x27, 0x0020},
- {0xaa, 0x20, 0x0000},
- {0xaa, 0x21, 0x0040},
- {0xaa, 0x22, 0x0013},
- {0xaa, 0x23, 0x004c},
- {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */
- {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
- {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x13, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x4c, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa1, 0x01, 0x001d},
- {0xa1, 0x01, 0x001e},
- {0xa1, 0x01, 0x001f},
- {0xa1, 0x01, 0x0020},
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa1, 0x01, 0x0180},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x40, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x40, ZC3XX_R118_BGAIN},
-/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {}
+};
+static const struct usb_action hv7131b_50HZ[] = { /* 640x480*/
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
+ {0xaa, 0x22, 0x001b}, /* 00,22,1b,aa */
+ {0xaa, 0x23, 0x00fc}, /* 00,23,fc,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x9b, ZC3XX_R191_SYNC00MID}, /* 01,91,9b,cc */
+ {0xa0, 0x80, ZC3XX_R192_SYNC00HIGH}, /* 01,92,80,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0xea, ZC3XX_R196_SYNC01MID}, /* 01,96,ea,cc */
+ {0xa0, 0x60, ZC3XX_R197_SYNC01HIGH}, /* 01,97,60,cc */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
+ {0xa0, 0x1b, ZC3XX_R01F_HSYNC_2}, /* 00,1f,1b,cc */
+ {0xa0, 0xfc, ZC3XX_R020_HSYNC_3}, /* 00,20,fc,cc */
+ {}
+};
+static const struct usb_action hv7131b_50HZScale[] = { /* 320x240 */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x0053}, /* 00,26,53,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0050}, /* 00,21,50,aa */
+ {0xaa, 0x22, 0x0012}, /* 00,22,12,aa */
+ {0xaa, 0x23, 0x0080}, /* 00,23,80,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x9b, ZC3XX_R191_SYNC00MID}, /* 01,91,9b,cc */
+ {0xa0, 0x80, ZC3XX_R192_SYNC00HIGH}, /* 01,92,80,cc */
+ {0xa0, 0x01, ZC3XX_R195_SYNC01LOW}, /* 01,95,01,cc */
+ {0xa0, 0xd4, ZC3XX_R196_SYNC01MID}, /* 01,96,d4,cc */
+ {0xa0, 0xc0, ZC3XX_R197_SYNC01HIGH}, /* 01,97,c0,cc */
+ {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
+ {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
+ {0xa0, 0x12, ZC3XX_R01F_HSYNC_2}, /* 00,1f,12,cc */
+ {0xa0, 0x80, ZC3XX_R020_HSYNC_3}, /* 00,20,80,cc */
+ {}
+};
+static const struct usb_action hv7131b_60HZ[] = { /* 640x480*/
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
+ {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0040}, /* 00,21,40,aa */
+ {0xaa, 0x22, 0x0013}, /* 00,22,13,aa */
+ {0xaa, 0x23, 0x004c}, /* 00,23,4c,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x4d, ZC3XX_R191_SYNC00MID}, /* 01,91,4d,cc */
+ {0xa0, 0x60, ZC3XX_R192_SYNC00HIGH}, /* 01,92,60,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0xc3, ZC3XX_R196_SYNC01MID}, /* 01,96,c3,cc */
+ {0xa0, 0x50, ZC3XX_R197_SYNC01HIGH}, /* 01,97,50,cc */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
+ {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, /* 00,1f,13,cc */
+ {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, /* 00,20,4c,cc */
+ {}
+};
+static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0007}, /* 00,25,07,aa */
+ {0xaa, 0x26, 0x00a1}, /* 00,26,a1,aa */
+ {0xaa, 0x27, 0x0020}, /* 00,27,20,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
+ {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
+ {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0x4d, ZC3XX_R191_SYNC00MID}, /* 01,91,4d,cc */
+ {0xa0, 0x60, ZC3XX_R192_SYNC00HIGH}, /* 01,92,60,cc */
+ {0xa0, 0x01, ZC3XX_R195_SYNC01LOW}, /* 01,95,01,cc */
+ {0xa0, 0x86, ZC3XX_R196_SYNC01MID}, /* 01,96,86,cc */
+ {0xa0, 0xa0, ZC3XX_R197_SYNC01HIGH}, /* 01,97,a0,cc */
+ {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, /* 01,8c,07,cc */
+ {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,0f,cc */
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,18,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
+ {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
+ {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
+ {}
+};
+static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
+ {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x0010}, /* 00,21,10,aa */
+ {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
+ {0xaa, 0x23, 0x0003}, /* 00,23,03,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0xf8, ZC3XX_R191_SYNC00MID}, /* 01,91,f8,cc */
+ {0xa0, 0x00, ZC3XX_R192_SYNC00HIGH}, /* 01,92,00,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0x02, ZC3XX_R196_SYNC01MID}, /* 01,96,02,cc */
+ {0xa0, 0x00, ZC3XX_R197_SYNC01HIGH}, /* 01,97,00,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0x10, ZC3XX_R01E_HSYNC_1}, /* 00,1e,10,cc */
+ {0xa0, 0x00, ZC3XX_R01F_HSYNC_2}, /* 00,1f,00,cc */
+ {0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
+ {}
+};
+static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
+ {0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
+ {0xaa, 0x27, 0x0000}, /* 00,27,00,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x21, 0x00a0}, /* 00,21,a0,aa */
+ {0xaa, 0x22, 0x0016}, /* 00,22,16,aa */
+ {0xaa, 0x23, 0x0040}, /* 00,23,40,aa */
+ {0xa0, 0x2f, ZC3XX_R190_SYNC00LOW}, /* 01,90,2f,cc */
+ {0xa0, 0xf8, ZC3XX_R191_SYNC00MID}, /* 01,91,f8,cc */
+ {0xa0, 0x00, ZC3XX_R192_SYNC00HIGH}, /* 01,92,00,cc */
+ {0xa0, 0x00, ZC3XX_R195_SYNC01LOW}, /* 01,95,00,cc */
+ {0xa0, 0x02, ZC3XX_R196_SYNC01MID}, /* 01,96,02,cc */
+ {0xa0, 0x00, ZC3XX_R197_SYNC01HIGH}, /* 01,97,00,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, /* 00,1d,00,cc */
+ {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,a0,cc */
+ {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, /* 00,1f,16,cc */
+ {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
{}
};
@@ -6353,6 +6383,7 @@ static void setmatrix(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_GC0305:
+ case SENSOR_HV7131B:
matrix = gc0305_matrix;
break;
case SENSOR_MC501CB:
@@ -6594,9 +6625,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
hdcs2020b_50HZ, hdcs2020b_50HZ,
hdcs2020b_60HZ, hdcs2020b_60HZ},
/* SENSOR_HV7131B 5 */
- {NULL, NULL,
- NULL, NULL,
- NULL, NULL},
+ {hv7131b_NoFlikerScale, hv7131b_NoFliker,
+ hv7131b_50HZScale, hv7131b_50HZ,
+ hv7131b_60HZScale, hv7131b_60HZ},
/* SENSOR_HV7131C 6 */
{NULL, NULL,
NULL, NULL,
@@ -7153,7 +7184,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->gamma = gamma[(int) sd->sensor];
sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
- sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
switch (sd->sensor) {
case SENSOR_GC0305:
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index efe849981ab7..d4658c56eddc 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -385,10 +385,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
goto err_out_detach;
}
- /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
+ /* Phys addr can only be set after attaching (for ir->c.dev) */
snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
- ir->c.adapter->dev.bus_id,
- ir->c.dev.bus_id);
+ dev_name(&ir->c.adapter->dev),
+ dev_name(&ir->c.dev));
/* init + register input device */
ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 4e05f91a9100..2883c8780760 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -877,20 +877,28 @@ static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
static const struct ivtv_card ivtv_card_pg600v2 = {
.type = IVTV_CARD_PG600V2,
.name = "Yuan PG600-2, GotView PCI DVD Lite",
- .comment = "only Composite and S-Video inputs are supported, not the tuner\n",
.v4l2_capabilities = IVTV_CAP_ENCODER,
.hw_video = IVTV_HW_CX25840,
.hw_audio = IVTV_HW_CX25840,
.hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840,
+ .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
+ /* XC2028 support apparently works for the Yuan, it's still
+ uncertain whether it also works with the GotView. */
.video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0,
+ { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
+ { IVTV_CARD_INPUT_SVIDEO1, 1,
CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
+ { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
},
.audio_inputs = {
+ { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
{ IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
},
+ .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
+ .xceive_pin = 12,
+ .tuners = {
+ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
+ },
.pci_list = ivtv_pci_pg600v2,
.i2c = &ivtv_i2c_std,
};
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 210f1240b331..6ee9b69cc4a9 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4011,8 +4011,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
/* Do not call this function directly! */
static int
-ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl_internal(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = file->private_data;
struct usb_ov511 *ov = video_get_drvdata(vdev);
@@ -4461,7 +4460,7 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
if (mutex_lock_interruptible(&ov->lock))
return -EINTR;
- rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal);
+ rc = video_usercopy(file, cmd, arg, ov51x_v4l1_ioctl_internal);
mutex_unlock(&ov->lock);
return rc;
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
new file mode 100644
index 000000000000..0af2ca6a98f7
--- /dev/null
+++ b/drivers/media/video/ov772x.c
@@ -0,0 +1,964 @@
+/*
+ * ov772x Camera Driver
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov7670 and soc_camera_platform driver,
+ *
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-common.h>
+#include <media/soc_camera.h>
+#include <media/ov772x.h>
+
+/*
+ * register offset
+ */
+#define GAIN 0x00 /* AGC - Gain control gain setting */
+#define BLUE 0x01 /* AWB - Blue channel gain setting */
+#define RED 0x02 /* AWB - Red channel gain setting */
+#define GREEN 0x03 /* AWB - Green channel gain setting */
+#define COM1 0x04 /* Common control 1 */
+#define BAVG 0x05 /* U/B Average Level */
+#define GAVG 0x06 /* Y/Gb Average Level */
+#define RAVG 0x07 /* V/R Average Level */
+#define AECH 0x08 /* Exposure Value - AEC MSBs */
+#define COM2 0x09 /* Common control 2 */
+#define PID 0x0A /* Product ID Number MSB */
+#define VER 0x0B /* Product ID Number LSB */
+#define COM3 0x0C /* Common control 3 */
+#define COM4 0x0D /* Common control 4 */
+#define COM5 0x0E /* Common control 5 */
+#define COM6 0x0F /* Common control 6 */
+#define AEC 0x10 /* Exposure Value */
+#define CLKRC 0x11 /* Internal clock */
+#define COM7 0x12 /* Common control 7 */
+#define COM8 0x13 /* Common control 8 */
+#define COM9 0x14 /* Common control 9 */
+#define COM10 0x15 /* Common control 10 */
+#define HSTART 0x17 /* Horizontal sensor size */
+#define HSIZE 0x18 /* Horizontal frame (HREF column) end high 8-bit */
+#define VSTART 0x19 /* Vertical frame (row) start high 8-bit */
+#define VSIZE 0x1A /* Vertical sensor size */
+#define PSHFT 0x1B /* Data format - pixel delay select */
+#define MIDH 0x1C /* Manufacturer ID byte - high */
+#define MIDL 0x1D /* Manufacturer ID byte - low */
+#define LAEC 0x1F /* Fine AEC value */
+#define COM11 0x20 /* Common control 11 */
+#define BDBASE 0x22 /* Banding filter Minimum AEC value */
+#define DBSTEP 0x23 /* Banding filter Maximum Setp */
+#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */
+#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */
+#define VPT 0x26 /* AGC/AEC Fast mode operating region */
+#define HOUTSIZE 0x29 /* Horizontal data output size MSBs */
+#define EXHCH 0x2A /* Dummy pixel insert MSB */
+#define EXHCL 0x2B /* Dummy pixel insert LSB */
+#define VOUTSIZE 0x2C /* Vertical data output size MSBs */
+#define ADVFL 0x2D /* LSB of insert dummy lines in Vertical direction */
+#define ADVFH 0x2E /* MSG of insert dummy lines in Vertical direction */
+#define YAVE 0x2F /* Y/G Channel Average value */
+#define LUMHTH 0x30 /* Histogram AEC/AGC Luminance high level threshold */
+#define LUMLTH 0x31 /* Histogram AEC/AGC Luminance low level threshold */
+#define HREF 0x32 /* Image start and size control */
+#define DM_LNL 0x33 /* Dummy line low 8 bits */
+#define DM_LNH 0x34 /* Dummy line high 8 bits */
+#define ADOFF_B 0x35 /* AD offset compensation value for B channel */
+#define ADOFF_R 0x36 /* AD offset compensation value for R channel */
+#define ADOFF_GB 0x37 /* AD offset compensation value for Gb channel */
+#define ADOFF_GR 0x38 /* AD offset compensation value for Gr channel */
+#define OFF_B 0x39 /* Analog process B channel offset value */
+#define OFF_R 0x3A /* Analog process R channel offset value */
+#define OFF_GB 0x3B /* Analog process Gb channel offset value */
+#define OFF_GR 0x3C /* Analog process Gr channel offset value */
+#define COM12 0x3D /* Common control 12 */
+#define COM13 0x3E /* Common control 13 */
+#define COM14 0x3F /* Common control 14 */
+#define COM15 0x40 /* Common control 15*/
+#define COM16 0x41 /* Common control 16 */
+#define TGT_B 0x42 /* BLC blue channel target value */
+#define TGT_R 0x43 /* BLC red channel target value */
+#define TGT_GB 0x44 /* BLC Gb channel target value */
+#define TGT_GR 0x45 /* BLC Gr channel target value */
+#define LCC0 0x46 /* Lens correction control 0 */
+#define LCC1 0x47 /* Lens correction option 1 - X coordinate */
+#define LCC2 0x48 /* Lens correction option 2 - Y coordinate */
+#define LCC3 0x49 /* Lens correction option 3 */
+#define LCC4 0x4A /* Lens correction option 4 - radius of the circular */
+#define LCC5 0x4B /* Lens correction option 5 */
+#define LCC6 0x4C /* Lens correction option 6 */
+#define FIXGAIN 0x4D /* Analog fix gain amplifer */
+#define AREF0 0x4E /* Sensor reference control */
+#define AREF1 0x4F /* Sensor reference current control */
+#define AREF2 0x50 /* Analog reference control */
+#define AREF3 0x51 /* ADC reference control */
+#define AREF4 0x52 /* ADC reference control */
+#define AREF5 0x53 /* ADC reference control */
+#define AREF6 0x54 /* Analog reference control */
+#define AREF7 0x55 /* Analog reference control */
+#define UFIX 0x60 /* U channel fixed value output */
+#define VFIX 0x61 /* V channel fixed value output */
+#define AW_BB_BLK 0x62 /* AWB option for advanced AWB */
+#define AW_B_CTRL0 0x63 /* AWB control byte 0 */
+#define DSP_CTRL1 0x64 /* DSP control byte 1 */
+#define DSP_CTRL2 0x65 /* DSP control byte 2 */
+#define DSP_CTRL3 0x66 /* DSP control byte 3 */
+#define DSP_CTRL4 0x67 /* DSP control byte 4 */
+#define AW_B_BIAS 0x68 /* AWB BLC level clip */
+#define AW_BCTRL1 0x69 /* AWB control 1 */
+#define AW_BCTRL2 0x6A /* AWB control 2 */
+#define AW_BCTRL3 0x6B /* AWB control 3 */
+#define AW_BCTRL4 0x6C /* AWB control 4 */
+#define AW_BCTRL5 0x6D /* AWB control 5 */
+#define AW_BCTRL6 0x6E /* AWB control 6 */
+#define AW_BCTRL7 0x6F /* AWB control 7 */
+#define AW_BCTRL8 0x70 /* AWB control 8 */
+#define AW_BCTRL9 0x71 /* AWB control 9 */
+#define AW_BCTRL10 0x72 /* AWB control 10 */
+#define AW_BCTRL11 0x73 /* AWB control 11 */
+#define AW_BCTRL12 0x74 /* AWB control 12 */
+#define AW_BCTRL13 0x75 /* AWB control 13 */
+#define AW_BCTRL14 0x76 /* AWB control 14 */
+#define AW_BCTRL15 0x77 /* AWB control 15 */
+#define AW_BCTRL16 0x78 /* AWB control 16 */
+#define AW_BCTRL17 0x79 /* AWB control 17 */
+#define AW_BCTRL18 0x7A /* AWB control 18 */
+#define AW_BCTRL19 0x7B /* AWB control 19 */
+#define AW_BCTRL20 0x7C /* AWB control 20 */
+#define AW_BCTRL21 0x7D /* AWB control 21 */
+#define GAM1 0x7E /* Gamma Curve 1st segment input end point */
+#define GAM2 0x7F /* Gamma Curve 2nd segment input end point */
+#define GAM3 0x80 /* Gamma Curve 3rd segment input end point */
+#define GAM4 0x81 /* Gamma Curve 4th segment input end point */
+#define GAM5 0x82 /* Gamma Curve 5th segment input end point */
+#define GAM6 0x83 /* Gamma Curve 6th segment input end point */
+#define GAM7 0x84 /* Gamma Curve 7th segment input end point */
+#define GAM8 0x85 /* Gamma Curve 8th segment input end point */
+#define GAM9 0x86 /* Gamma Curve 9th segment input end point */
+#define GAM10 0x87 /* Gamma Curve 10th segment input end point */
+#define GAM11 0x88 /* Gamma Curve 11th segment input end point */
+#define GAM12 0x89 /* Gamma Curve 12th segment input end point */
+#define GAM13 0x8A /* Gamma Curve 13th segment input end point */
+#define GAM14 0x8B /* Gamma Curve 14th segment input end point */
+#define GAM15 0x8C /* Gamma Curve 15th segment input end point */
+#define SLOP 0x8D /* Gamma curve highest segment slope */
+#define DNSTH 0x8E /* De-noise threshold */
+#define EDGE0 0x8F /* Edge enhancement control 0 */
+#define EDGE1 0x90 /* Edge enhancement control 1 */
+#define DNSOFF 0x91 /* Auto De-noise threshold control */
+#define EDGE2 0x92 /* Edge enhancement strength low point control */
+#define EDGE3 0x93 /* Edge enhancement strength high point control */
+#define MTX1 0x94 /* Matrix coefficient 1 */
+#define MTX2 0x95 /* Matrix coefficient 2 */
+#define MTX3 0x96 /* Matrix coefficient 3 */
+#define MTX4 0x97 /* Matrix coefficient 4 */
+#define MTX5 0x98 /* Matrix coefficient 5 */
+#define MTX6 0x99 /* Matrix coefficient 6 */
+#define MTX_CTRL 0x9A /* Matrix control */
+#define BRIGHT 0x9B /* Brightness control */
+#define CNTRST 0x9C /* Contrast contrast */
+#define CNTRST_CTRL 0x9D /* Contrast contrast center */
+#define UVAD_J0 0x9E /* Auto UV adjust contrast 0 */
+#define UVAD_J1 0x9F /* Auto UV adjust contrast 1 */
+#define SCAL0 0xA0 /* Scaling control 0 */
+#define SCAL1 0xA1 /* Scaling control 1 */
+#define SCAL2 0xA2 /* Scaling control 2 */
+#define FIFODLYM 0xA3 /* FIFO manual mode delay control */
+#define FIFODLYA 0xA4 /* FIFO auto mode delay control */
+#define SDE 0xA6 /* Special digital effect control */
+#define USAT 0xA7 /* U component saturation control */
+#define VSAT 0xA8 /* V component saturation control */
+#define HUE0 0xA9 /* Hue control 0 */
+#define HUE1 0xAA /* Hue control 1 */
+#define SIGN 0xAB /* Sign bit for Hue and contrast */
+#define DSPAUTO 0xAC /* DSP auto function ON/OFF control */
+
+/*
+ * register detail
+ */
+
+/* COM2 */
+#define SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */
+ /* Output drive capability */
+#define OCAP_1x 0x00 /* 1x */
+#define OCAP_2x 0x01 /* 2x */
+#define OCAP_3x 0x02 /* 3x */
+#define OCAP_4x 0x03 /* 4x */
+
+/* COM3 */
+#define SWAP_MASK 0x38
+
+#define VFIMG_ON_OFF 0x80 /* Vertical flip image ON/OFF selection */
+#define HMIMG_ON_OFF 0x40 /* Horizontal mirror image ON/OFF selection */
+#define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */
+#define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */
+#define SWAP_ML 0x08 /* Swap output MSB/LSB */
+ /* Tri-state option for output clock */
+#define NOTRI_CLOCK 0x04 /* 0: Tri-state at this period */
+ /* 1: No tri-state at this period */
+ /* Tri-state option for output data */
+#define NOTRI_DATA 0x02 /* 0: Tri-state at this period */
+ /* 1: No tri-state at this period */
+#define SCOLOR_TEST 0x01 /* Sensor color bar test pattern */
+
+/* COM4 */
+ /* PLL frequency control */
+#define PLL_BYPASS 0x00 /* 00: Bypass PLL */
+#define PLL_4x 0x40 /* 01: PLL 4x */
+#define PLL_6x 0x80 /* 10: PLL 6x */
+#define PLL_8x 0xc0 /* 11: PLL 8x */
+ /* AEC evaluate window */
+#define AEC_FULL 0x00 /* 00: Full window */
+#define AEC_1p2 0x10 /* 01: 1/2 window */
+#define AEC_1p4 0x20 /* 10: 1/4 window */
+#define AEC_2p3 0x30 /* 11: Low 2/3 window */
+
+/* COM5 */
+#define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */
+#define AFR_SPPED 0x40 /* Auto frame rate control speed slection */
+ /* Auto frame rate max rate control */
+#define AFR_NO_RATE 0x00 /* No reduction of frame rate */
+#define AFR_1p2 0x10 /* Max reduction to 1/2 frame rate */
+#define AFR_1p4 0x20 /* Max reduction to 1/4 frame rate */
+#define AFR_1p8 0x30 /* Max reduction to 1/8 frame rate */
+ /* Auto frame rate active point control */
+#define AF_2x 0x00 /* Add frame when AGC reaches 2x gain */
+#define AF_4x 0x04 /* Add frame when AGC reaches 4x gain */
+#define AF_8x 0x08 /* Add frame when AGC reaches 8x gain */
+#define AF_16x 0x0c /* Add frame when AGC reaches 16x gain */
+ /* AEC max step control */
+#define AEC_NO_LIMIT 0x01 /* 0 : AEC incease step has limit */
+ /* 1 : No limit to AEC increase step */
+
+/* COM7 */
+ /* SCCB Register Reset */
+#define SCCB_RESET 0x80 /* 0 : No change */
+ /* 1 : Resets all registers to default */
+ /* Resolution selection */
+#define SLCT_MASK 0x40 /* Mask of VGA or QVGA */
+#define SLCT_VGA 0x00 /* 0 : VGA */
+#define SLCT_QVGA 0x40 /* 1 : QVGA */
+#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
+ /* RGB output format control */
+#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
+#define FMT_RGB565 0x04 /* 01 : RGB 565 */
+#define FMT_RGB555 0x08 /* 10 : RGB 555 */
+#define FMT_RGB444 0x0c /* 11 : RGB 444 */
+ /* Output format control */
+#define OFMT_YUV 0x00 /* 00 : YUV */
+#define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */
+#define OFMT_RGB 0x02 /* 10 : RGB */
+#define OFMT_BRAW 0x03 /* 11 : Bayer RAW */
+
+/* COM8 */
+#define FAST_ALGO 0x80 /* Enable fast AGC/AEC algorithm */
+ /* AEC Setp size limit */
+#define UNLMT_STEP 0x40 /* 0 : Step size is limited */
+ /* 1 : Unlimited step size */
+#define BNDF_ON_OFF 0x20 /* Banding filter ON/OFF */
+#define AEC_BND 0x10 /* Enable AEC below banding value */
+#define AEC_ON_OFF 0x08 /* Fine AEC ON/OFF control */
+#define AGC_ON 0x04 /* AGC Enable */
+#define AWB_ON 0x02 /* AWB Enable */
+#define AEC_ON 0x01 /* AEC Enable */
+
+/* COM9 */
+#define BASE_AECAGC 0x80 /* Histogram or average based AEC/AGC */
+ /* Automatic gain ceiling - maximum AGC value */
+#define GAIN_2x 0x00 /* 000 : 2x */
+#define GAIN_4x 0x10 /* 001 : 4x */
+#define GAIN_8x 0x20 /* 010 : 8x */
+#define GAIN_16x 0x30 /* 011 : 16x */
+#define GAIN_32x 0x40 /* 100 : 32x */
+#define GAIN_64x 0x50 /* 101 : 64x */
+#define GAIN_128x 0x60 /* 110 : 128x */
+#define DROP_VSYNC 0x04 /* Drop VSYNC output of corrupt frame */
+#define DROP_HREF 0x02 /* Drop HREF output of corrupt frame */
+
+/* COM11 */
+#define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */
+#define SGLF_TRIG 0x01 /* Single frame transfer trigger */
+
+/* EXHCH */
+#define VSIZE_LSB 0x04 /* Vertical data output size LSB */
+
+/* DSP_CTRL1 */
+#define FIFO_ON 0x80 /* FIFO enable/disable selection */
+#define UV_ON_OFF 0x40 /* UV adjust function ON/OFF selection */
+#define YUV444_2_422 0x20 /* YUV444 to 422 UV channel option selection */
+#define CLR_MTRX_ON_OFF 0x10 /* Color matrix ON/OFF selection */
+#define INTPLT_ON_OFF 0x08 /* Interpolation ON/OFF selection */
+#define GMM_ON_OFF 0x04 /* Gamma function ON/OFF selection */
+#define AUTO_BLK_ON_OFF 0x02 /* Black defect auto correction ON/OFF */
+#define AUTO_WHT_ON_OFF 0x01 /* White define auto correction ON/OFF */
+
+/* DSP_CTRL3 */
+#define UV_MASK 0x80 /* UV output sequence option */
+#define UV_ON 0x80 /* ON */
+#define UV_OFF 0x00 /* OFF */
+#define CBAR_MASK 0x20 /* DSP Color bar mask */
+#define CBAR_ON 0x20 /* ON */
+#define CBAR_OFF 0x00 /* OFF */
+
+/* HSTART */
+#define HST_VGA 0x23
+#define HST_QVGA 0x3F
+
+/* HSIZE */
+#define HSZ_VGA 0xA0
+#define HSZ_QVGA 0x50
+
+/* VSTART */
+#define VST_VGA 0x07
+#define VST_QVGA 0x03
+
+/* VSIZE */
+#define VSZ_VGA 0xF0
+#define VSZ_QVGA 0x78
+
+/* HOUTSIZE */
+#define HOSZ_VGA 0xA0
+#define HOSZ_QVGA 0x50
+
+/* VOUTSIZE */
+#define VOSZ_VGA 0xF0
+#define VOSZ_QVGA 0x78
+
+/*
+ * bit configure (32 bit)
+ * this is used in struct ov772x_color_format :: option
+ */
+#define OP_UV 0x00000001
+#define OP_SWAP_RGB 0x00000002
+
+/*
+ * struct
+ */
+struct regval_list {
+ unsigned char reg_num;
+ unsigned char value;
+};
+
+struct ov772x_color_format {
+ char *name;
+ __u32 fourcc;
+ const struct regval_list *regs;
+ unsigned int option;
+};
+
+struct ov772x_win_size {
+ char *name;
+ __u32 width;
+ __u32 height;
+ unsigned char com7_bit;
+ const struct regval_list *regs;
+};
+
+struct ov772x_priv {
+ struct ov772x_camera_info *info;
+ struct i2c_client *client;
+ struct soc_camera_device icd;
+ const struct ov772x_color_format *fmt;
+ const struct ov772x_win_size *win;
+};
+
+#define ENDMARKER { 0xff, 0xff }
+
+static const struct regval_list ov772x_default_regs[] =
+{
+ { COM3, 0x00 },
+ { COM4, PLL_4x | 0x01 },
+ { 0x16, 0x00 }, /* Mystery */
+ { COM11, 0x10 }, /* Mystery */
+ { 0x28, 0x00 }, /* Mystery */
+ { HREF, 0x00 },
+ { COM13, 0xe2 }, /* Mystery */
+ { AREF0, 0xef },
+ { AREF2, 0x60 },
+ { AREF6, 0x7a },
+ ENDMARKER,
+};
+
+/*
+ * register setting for color format
+ */
+static const struct regval_list ov772x_RGB555_regs[] = {
+ { COM7, FMT_RGB555 | OFMT_RGB },
+ ENDMARKER,
+};
+
+static const struct regval_list ov772x_RGB565_regs[] = {
+ { COM7, FMT_RGB565 | OFMT_RGB },
+ ENDMARKER,
+};
+
+static const struct regval_list ov772x_YYUV_regs[] = {
+ { COM3, SWAP_YUV },
+ { COM7, OFMT_YUV },
+ ENDMARKER,
+};
+
+static const struct regval_list ov772x_UVYY_regs[] = {
+ { COM7, OFMT_YUV },
+ ENDMARKER,
+};
+
+
+/*
+ * register setting for window size
+ */
+static const struct regval_list ov772x_qvga_regs[] = {
+ { HSTART, HST_QVGA },
+ { HSIZE, HSZ_QVGA },
+ { VSTART, VST_QVGA },
+ { VSIZE, VSZ_QVGA },
+ { HOUTSIZE, HOSZ_QVGA },
+ { VOUTSIZE, VOSZ_QVGA },
+ ENDMARKER,
+};
+
+static const struct regval_list ov772x_vga_regs[] = {
+ { HSTART, HST_VGA },
+ { HSIZE, HSZ_VGA },
+ { VSTART, VST_VGA },
+ { VSIZE, VSZ_VGA },
+ { HOUTSIZE, HOSZ_VGA },
+ { VOUTSIZE, VOSZ_VGA },
+ ENDMARKER,
+};
+
+/*
+ * supported format list
+ */
+
+#define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type)
+static const struct soc_camera_data_format ov772x_fmt_lists[] = {
+ {
+ SETFOURCC(YUYV),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ SETFOURCC(YVYU),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ SETFOURCC(UYVY),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ SETFOURCC(RGB555),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+ {
+ SETFOURCC(RGB555X),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+ {
+ SETFOURCC(RGB565),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+ {
+ SETFOURCC(RGB565X),
+ .depth = 16,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ },
+};
+
+/*
+ * color format list
+ */
+#define T_YUYV 0
+static const struct ov772x_color_format ov772x_cfmts[] = {
+ [T_YUYV] = {
+ SETFOURCC(YUYV),
+ .regs = ov772x_YYUV_regs,
+ },
+ {
+ SETFOURCC(YVYU),
+ .regs = ov772x_YYUV_regs,
+ .option = OP_UV,
+ },
+ {
+ SETFOURCC(UYVY),
+ .regs = ov772x_UVYY_regs,
+ },
+ {
+ SETFOURCC(RGB555),
+ .regs = ov772x_RGB555_regs,
+ .option = OP_SWAP_RGB,
+ },
+ {
+ SETFOURCC(RGB555X),
+ .regs = ov772x_RGB555_regs,
+ },
+ {
+ SETFOURCC(RGB565),
+ .regs = ov772x_RGB565_regs,
+ .option = OP_SWAP_RGB,
+ },
+ {
+ SETFOURCC(RGB565X),
+ .regs = ov772x_RGB565_regs,
+ },
+};
+
+
+/*
+ * window size list
+ */
+#define VGA_WIDTH 640
+#define VGA_HEIGHT 480
+#define QVGA_WIDTH 320
+#define QVGA_HEIGHT 240
+#define MAX_WIDTH VGA_WIDTH
+#define MAX_HEIGHT VGA_HEIGHT
+
+static const struct ov772x_win_size ov772x_win_vga = {
+ .name = "VGA",
+ .width = VGA_WIDTH,
+ .height = VGA_HEIGHT,
+ .com7_bit = SLCT_VGA,
+ .regs = ov772x_vga_regs,
+};
+
+static const struct ov772x_win_size ov772x_win_qvga = {
+ .name = "QVGA",
+ .width = QVGA_WIDTH,
+ .height = QVGA_HEIGHT,
+ .com7_bit = SLCT_QVGA,
+ .regs = ov772x_qvga_regs,
+};
+
+
+/*
+ * general function
+ */
+
+static int ov772x_write_array(struct i2c_client *client,
+ const struct regval_list *vals)
+{
+ while (vals->reg_num != 0xff) {
+ int ret = i2c_smbus_write_byte_data(client,
+ vals->reg_num,
+ vals->value);
+ if (ret < 0)
+ return ret;
+ vals++;
+ }
+ return 0;
+}
+
+static int ov772x_mask_set(struct i2c_client *client,
+ u8 command,
+ u8 mask,
+ u8 set)
+{
+ s32 val = i2c_smbus_read_byte_data(client, command);
+ val &= ~mask;
+ val |= set;
+
+ return i2c_smbus_write_byte_data(client, command, val);
+}
+
+static int ov772x_reset(struct i2c_client *client)
+{
+ int ret = i2c_smbus_write_byte_data(client, COM7, SCCB_RESET);
+ msleep(1);
+ return ret;
+}
+
+/*
+ * soc_camera_ops function
+ */
+
+static int ov772x_init(struct soc_camera_device *icd)
+{
+ return 0;
+}
+
+static int ov772x_release(struct soc_camera_device *icd)
+{
+ return 0;
+}
+
+static int ov772x_start_capture(struct soc_camera_device *icd)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ int ret;
+
+
+ if (!priv->win)
+ priv->win = &ov772x_win_vga;
+ if (!priv->fmt)
+ priv->fmt = &ov772x_cfmts[T_YUYV];
+
+ /*
+ * reset hardware
+ */
+ ov772x_reset(priv->client);
+ ret = ov772x_write_array(priv->client, ov772x_default_regs);
+ if (ret < 0)
+ goto start_end;
+
+ /*
+ * set color format
+ */
+ ret = ov772x_write_array(priv->client, priv->fmt->regs);
+ if (ret < 0)
+ goto start_end;
+
+ /*
+ * set size format
+ */
+ ret = ov772x_write_array(priv->client, priv->win->regs);
+ if (ret < 0)
+ goto start_end;
+
+ /*
+ * set COM7 bit ( QVGA or VGA )
+ */
+ ret = ov772x_mask_set(priv->client,
+ COM7, SLCT_MASK, priv->win->com7_bit);
+ if (ret < 0)
+ goto start_end;
+
+ /*
+ * set UV setting
+ */
+ if (priv->fmt->option & OP_UV) {
+ ret = ov772x_mask_set(priv->client,
+ DSP_CTRL3, UV_MASK, UV_ON);
+ if (ret < 0)
+ goto start_end;
+ }
+
+ /*
+ * set SWAP setting
+ */
+ if (priv->fmt->option & OP_SWAP_RGB) {
+ ret = ov772x_mask_set(priv->client,
+ COM3, SWAP_MASK, SWAP_RGB);
+ if (ret < 0)
+ goto start_end;
+ }
+
+ dev_info(&icd->dev,
+ "format %s, win %s\n", priv->fmt->name, priv->win->name);
+
+start_end:
+ priv->fmt = NULL;
+ priv->win = NULL;
+
+ return ret;
+}
+
+static int ov772x_stop_capture(struct soc_camera_device *icd)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ ov772x_reset(priv->client);
+ return 0;
+}
+
+static int ov772x_set_bus_param(struct soc_camera_device *icd,
+ unsigned long flags)
+{
+ return 0;
+}
+
+static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ return SOCAM_PCLK_SAMPLE_RISING |
+ SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_VSYNC_ACTIVE_HIGH |
+ SOCAM_MASTER |
+ priv->info->buswidth;
+}
+
+static int ov772x_get_chip_id(struct soc_camera_device *icd,
+ struct v4l2_chip_ident *id)
+{
+ id->ident = V4L2_IDENT_OV772X;
+ id->revision = 0;
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov772x_get_register(struct soc_camera_device *icd,
+ struct v4l2_register *reg)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ int ret;
+
+ if (reg->reg > 0xff)
+ return -EINVAL;
+
+ ret = i2c_smbus_read_byte_data(priv->client, reg->reg);
+ if (ret < 0)
+ return ret;
+
+ reg->val = (__u64)ret;
+
+ return 0;
+}
+
+static int ov772x_set_register(struct soc_camera_device *icd,
+ struct v4l2_register *reg)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ if (reg->reg > 0xff ||
+ reg->val > 0xff)
+ return -EINVAL;
+
+ return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val);
+}
+#endif
+
+static int ov772x_set_fmt_cap(struct soc_camera_device *icd,
+ __u32 pixfmt,
+ struct v4l2_rect *rect)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ int ret = -EINVAL;
+ int i;
+
+ /*
+ * select format
+ */
+ priv->fmt = NULL;
+ for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
+ if (pixfmt == ov772x_cfmts[i].fourcc) {
+ priv->fmt = ov772x_cfmts + i;
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int ov772x_try_fmt_cap(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct ov772x_priv *priv;
+
+ priv = container_of(icd, struct ov772x_priv, icd);
+
+ /* QVGA */
+ if (pix->width <= ov772x_win_qvga.width ||
+ pix->height <= ov772x_win_qvga.height) {
+ priv->win = &ov772x_win_qvga;
+ pix->width = ov772x_win_qvga.width;
+ pix->height = ov772x_win_qvga.height;
+ }
+
+ /* VGA */
+ else if (pix->width <= ov772x_win_vga.width ||
+ pix->height <= ov772x_win_vga.height) {
+ priv->win = &ov772x_win_vga;
+ pix->width = ov772x_win_vga.width;
+ pix->height = ov772x_win_vga.height;
+ }
+
+ pix->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static int ov772x_video_probe(struct soc_camera_device *icd)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ u8 pid, ver;
+
+ /*
+ * We must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant.
+ */
+ if (!icd->dev.parent ||
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+ return -ENODEV;
+
+ /*
+ * ov772x only use 8 or 10 bit bus width
+ */
+ if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
+ SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
+ dev_err(&icd->dev, "bus width error\n");
+ return -ENODEV;
+ }
+
+ icd->formats = ov772x_fmt_lists;
+ icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
+
+ if (priv->info->link.power)
+ priv->info->link.power(&priv->client->dev, 1);
+
+ /*
+ * check and show product ID and manufacturer ID
+ */
+ pid = i2c_smbus_read_byte_data(priv->client, PID);
+ ver = i2c_smbus_read_byte_data(priv->client, VER);
+ if (pid != 0x77 ||
+ ver != 0x21) {
+ if (priv->info->link.power)
+ priv->info->link.power(&priv->client->dev, 0);
+ return -ENODEV;
+ }
+
+ dev_info(&icd->dev,
+ "ov772x Product ID %0x:%0x Manufacturer ID %x:%x\n",
+ pid,
+ ver,
+ i2c_smbus_read_byte_data(priv->client, MIDH),
+ i2c_smbus_read_byte_data(priv->client, MIDL));
+
+
+ return soc_camera_video_start(icd);
+}
+
+static void ov772x_video_remove(struct soc_camera_device *icd)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ soc_camera_video_stop(icd);
+
+ if (priv->info->link.power)
+ priv->info->link.power(&priv->client->dev, 0);
+
+}
+
+static struct soc_camera_ops ov772x_ops = {
+ .owner = THIS_MODULE,
+ .probe = ov772x_video_probe,
+ .remove = ov772x_video_remove,
+ .init = ov772x_init,
+ .release = ov772x_release,
+ .start_capture = ov772x_start_capture,
+ .stop_capture = ov772x_stop_capture,
+ .set_fmt_cap = ov772x_set_fmt_cap,
+ .try_fmt_cap = ov772x_try_fmt_cap,
+ .set_bus_param = ov772x_set_bus_param,
+ .query_bus_param = ov772x_query_bus_param,
+ .get_chip_id = ov772x_get_chip_id,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .get_register = ov772x_get_register,
+ .set_register = ov772x_set_register,
+#endif
+};
+
+/*
+ * i2c_driver function
+ */
+
+static int ov772x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct ov772x_priv *priv;
+ struct ov772x_camera_info *info;
+ struct soc_camera_device *icd;
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ int ret;
+
+ info = client->dev.platform_data;
+ if (!info)
+ return -EINVAL;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_err(&adapter->dev,
+ "I2C-Adapter doesn't support "
+ "I2C_FUNC_SMBUS_BYTE_DATA\n");
+ return -EIO;
+ }
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->info = info;
+ priv->client = client;
+ i2c_set_clientdata(client, priv);
+
+ icd = &priv->icd;
+ icd->ops = &ov772x_ops;
+ icd->control = &client->dev;
+ icd->width_max = MAX_WIDTH;
+ icd->height_max = MAX_HEIGHT;
+ icd->iface = priv->info->link.bus_id;
+
+ ret = soc_camera_device_register(icd);
+
+ if (ret)
+ kfree(priv);
+
+ return ret;
+}
+
+static int ov772x_remove(struct i2c_client *client)
+{
+ struct ov772x_priv *priv = i2c_get_clientdata(client);
+
+ soc_camera_device_unregister(&priv->icd);
+ kfree(priv);
+ return 0;
+}
+
+static const struct i2c_device_id ov772x_id[] = {
+ {"ov772x", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ov772x_id);
+
+static struct i2c_driver ov772x_i2c_driver = {
+ .driver = {
+ .name = "ov772x",
+ },
+ .probe = ov772x_probe,
+ .remove = ov772x_remove,
+ .id_table = ov772x_id,
+};
+
+/*
+ * module function
+ */
+
+static int __init ov772x_module_init(void)
+{
+ printk(KERN_INFO "ov772x driver\n");
+ return i2c_add_driver(&ov772x_i2c_driver);
+}
+
+static void __exit ov772x_module_exit(void)
+{
+ i2c_del_driver(&ov772x_i2c_driver);
+}
+
+module_init(ov772x_module_init);
+module_exit(ov772x_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for ov772x");
+MODULE_AUTHOR("Kuninori Morimoto");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 994807818aa2..45730fac1570 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -10,8 +10,8 @@
* 14478 Potsdam, Germany
*
* Most of this code is directly derived from his userspace driver.
- * His driver works so send any reports to alan@redhat.com unless the
- * userspace driver also doesn't work for you...
+ * His driver works so send any reports to alan@lxorguk.ukuu.org.uk
+ * unless the userspace driver also doesn't work for you...
*
* Changes:
* 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
@@ -680,8 +680,7 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
* Video4linux interfacing
*/
-static int pms_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int pms_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *dev = video_devdata(file);
struct pms_device *pd=(struct pms_device *)dev;
@@ -866,7 +865,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
static int pms_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, pms_do_ioctl);
+ return video_usercopy(file, cmd, arg, pms_do_ioctl);
}
static ssize_t pms_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 5b81ba469641..4358079f1966 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2395,7 +2395,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
"usb %s address %d",
- hdw->usb_dev->dev.bus_id,
+ dev_name(&hdw->usb_dev->dev),
hdw->usb_dev->devnum);
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 733680f21317..e641cd971453 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -628,10 +628,10 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
class_dev->class = &class_ptr->class;
if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
- snprintf(class_dev->bus_id, BUS_ID_SIZE, "sn-%lu",
+ dev_set_name(class_dev, "sn-%lu",
pvr2_hdw_get_sn(sfp->channel.hdw));
} else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
- snprintf(class_dev->bus_id, BUS_ID_SIZE, "unit-%c",
+ dev_set_name(class_dev, "unit-%c",
pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
} else {
kfree(class_dev);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 97ed95957992..52af1c435965 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -168,8 +168,7 @@ static const char *get_v4l_name(int v4l_type)
* This is part of Video 4 Linux API. The procedure handles ioctl() calls.
*
*/
-static int __pvr2_v4l2_do_ioctl(struct file *file,
- unsigned int cmd, void *arg)
+static int pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct pvr2_v4l2_fh *fh = file->private_data;
struct pvr2_v4l2 *vp = fh->vhead;
@@ -864,7 +863,7 @@ static int __pvr2_v4l2_do_ioctl(struct file *file,
default :
ret = v4l_compat_translate_ioctl(file, cmd,
- arg, __pvr2_v4l2_do_ioctl);
+ arg, pvr2_v4l2_do_ioctl);
}
pvr2_hdw_commit_ctl(hdw);
@@ -890,12 +889,6 @@ static int __pvr2_v4l2_do_ioctl(struct file *file,
return ret;
}
-static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
-{
- return __pvr2_v4l2_do_ioctl(file, cmd, arg);
-}
-
static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
{
int num = dip->devbase.num;
@@ -963,7 +956,7 @@ static int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
#define IVTV_IOC_G_CODEC 0xFFEE7703
#define IVTV_IOC_S_CODEC 0xFFEE7704
if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
- return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
+ return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
}
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f3897a3fdb75..1ce9da167b7e 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1412,7 +1412,7 @@ static int pwc_video_ioctl(struct inode *inode, struct file *file,
mutex_lock(&pdev->modlock);
if (!pdev->unplugged)
- r = video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
+ r = video_usercopy(file, cmd, arg, pwc_video_do_ioctl);
mutex_unlock(&pdev->modlock);
out:
return r;
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 76a1376c9751..d7c147328e35 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -337,8 +337,7 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
}
-int pwc_video_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = video_devdata(file);
struct pwc_device *pdev;
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 74178754b39b..c046a2535668 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -340,8 +340,7 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power);
extern int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
/** Functions in pwc-v4l.c */
-extern int pwc_video_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg);
+extern int pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
/** pwc-uncompress.c */
/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 4a21b8a6a709..f159441e9375 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -15,7 +15,7 @@
* <richard.guenther@student.uni-tuebingen.de>
*
* with changes by
- * Alan Cox <Alan.Cox@linux.org>
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* and
*
@@ -804,8 +804,7 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t,
*
* Returns 0 if successful
*/
-static int do_saa5246a_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int do_saa5246a_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct saa5246a_device *t = video_drvdata(file);
@@ -953,7 +952,7 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file,
cmd = vtx_fix_command(cmd);
mutex_lock(&t->lock);
- err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl);
+ err = video_usercopy(file, cmd, arg, do_saa5246a_ioctl);
mutex_unlock(&t->lock);
return err;
}
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 3bb959c25d9d..6ef3affb97f1 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -8,7 +8,7 @@
* you can add arbitary multiple teletext devices to Linux video4linux
* now (well 32 anyway).
*
- * Alan Cox <Alan.Cox@linux.org>
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* The original driver was heavily modified to match the i2c interface
* It was truncated to use the WinTV boards, too.
@@ -190,8 +190,7 @@ static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
* Standard character-device-driver functions
*/
-static int do_saa5249_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int do_saa5249_ioctl(struct file *file, unsigned int cmd, void *arg)
{
static int virtual_mode = false;
struct saa5249_device *t = video_drvdata(file);
@@ -488,7 +487,7 @@ static int saa5249_ioctl(struct inode *inode, struct file *file,
cmd = vtx_fix_command(cmd);
mutex_lock(&t->lock);
- err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl);
+ err = video_usercopy(file, cmd, arg, do_saa5249_ioctl);
mutex_unlock(&t->lock);
return err;
}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 24096d6e1ef8..9070efe4a4d0 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -276,7 +276,7 @@ struct saa7134_format {
#define SAA7134_BOARD_ADS_INSTANT_HDTV_PCI 151
#define SAA7134_BOARD_ASUSTeK_TIGER 152
-#define SAA7134_MAXBOARDS 8
+#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 044a2e94c34d..d652f25eef0e 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -975,8 +975,7 @@ static int se401_close(struct inode *inode, struct file *file)
return 0;
}
-static int se401_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = file->private_data;
struct usb_se401 *se401 = (struct usb_se401 *)vdev;
@@ -1142,7 +1141,7 @@ static int se401_do_ioctl(struct inode *inode, struct file *file,
static int se401_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
+ return video_usercopy(file, cmd, arg, se401_do_ioctl);
}
static ssize_t se401_read(struct file *file, char __user *buf,
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 2407607f2eff..4677e2ce0cac 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -609,7 +609,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
/* request irq */
err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
- pdev->dev.bus_id, pcdev);
+ dev_name(&pdev->dev), pcdev);
if (err) {
dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
goto exit_release_mem;
@@ -618,8 +618,8 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
pcdev->ici.priv = pcdev;
pcdev->ici.dev.parent = &pdev->dev;
pcdev->ici.nr = pdev->id;
- pcdev->ici.drv_name = pdev->dev.bus_id,
- pcdev->ici.ops = &sh_mobile_ceu_host_ops,
+ pcdev->ici.drv_name = dev_name(&pdev->dev);
+ pcdev->ici.ops = &sh_mobile_ceu_host_ops;
err = soc_camera_host_register(&pcdev->ici);
if (err)
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index fcd2b62f92c4..01a8efb8deb1 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -2162,7 +2162,7 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
+ strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
sizeof(cap.bus_info));
if (copy_to_user(arg, &cap, sizeof(cap)))
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index e23734f6d6e2..390722003260 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -55,7 +55,9 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
+#endif
/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
{ SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
@@ -94,7 +96,9 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
+#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), },
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 66ebe5956a87..28cf5c94bd61 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -783,7 +783,7 @@ int soc_camera_host_register(struct soc_camera_host *ici)
return -EINVAL;
/* Number might be equal to the platform device ID */
- sprintf(ici->dev.bus_id, "camera_host%d", ici->nr);
+ dev_set_name(&ici->dev, "camera_host%d", ici->nr);
mutex_lock(&list_lock);
list_for_each_entry(ix, &hosts, list) {
@@ -867,8 +867,7 @@ int soc_camera_device_register(struct soc_camera_device *icd)
icd->devnum = num;
icd->dev.bus = &soc_camera_bus_type;
- snprintf(icd->dev.bus_id, sizeof(icd->dev.bus_id),
- "%u-%u", icd->iface, icd->devnum);
+ dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
icd->dev.release = dummy_release;
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 328c41b1517d..42acc92c182d 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1132,8 +1132,7 @@ static int stv_close (struct inode *inode, struct file *file)
return 0;
}
-static int stv680_do_ioctl (struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = file->private_data;
struct usb_stv *stv680 = video_get_drvdata(vdev);
@@ -1303,7 +1302,7 @@ static int stv680_do_ioctl (struct inode *inode, struct file *file,
static int stv680_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, stv680_do_ioctl);
+ return video_usercopy(file, cmd, arg, stv680_do_ioctl);
}
static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 28af5ce5560d..e8f701a412ab 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -912,6 +912,21 @@ static int tvp5150_command(struct i2c_client *c,
int i;
fmt = arg;
+ /* raw vbi */
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* this is for capturing 36 raw vbi lines
+ if there's a way to cut off the beginning 2 vbi lines
+ with the tvp5150 then the vbi line count could be lowered
+ to 17 lines/field again, although I couldn't find a register
+ which could do that cropping */
+ if (fmt->fmt.vbi.sample_format == V4L2_PIX_FMT_GREY)
+ tvp5150_write(c, TVP5150_LUMA_PROC_CTL_1, 0x70);
+ if (fmt->fmt.vbi.count[0] == 18 && fmt->fmt.vbi.count[1] == 18) {
+ tvp5150_write(c, TVP5150_VERT_BLANKING_START, 0x00);
+ tvp5150_write(c, TVP5150_VERT_BLANKING_STOP, 0x01);
+ }
+ break;
+ }
if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
return -EINVAL;
svbi = &fmt->fmt.sliced;
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 7c575bb8184f..a42049de2bb6 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -1281,8 +1281,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file)
* History:
* 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
*/
-static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct uvd *uvd = file->private_data;
@@ -1505,7 +1504,7 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
static int usbvideo_v4l_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, usbvideo_v4l_do_ioctl);
+ return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl);
}
/*
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index d185b57fdcd0..48c8c4399eb8 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -523,7 +523,7 @@ static int vidioc_querycap (struct file *file, void *priv,
strlcpy(vc->card,
usbvision_device_data[usbvision->DevModel].ModelString,
sizeof(vc->card));
- strlcpy(vc->bus_info, usbvision->dev->dev.bus_id,
+ strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
sizeof(vc->bus_info));
vc->version = USBVISION_DRIVER_VERSION;
vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
@@ -1278,7 +1278,7 @@ static int usbvision_vbi_close(struct inode *inode, struct file *file)
return -ENODEV;
}
-static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file,
+static int usbvision_do_vbi_ioctl(struct file *file,
unsigned int cmd, void *arg)
{
/* TODO */
@@ -1288,7 +1288,7 @@ static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file,
static int usbvision_vbi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, usbvision_do_vbi_ioctl);
+ return video_usercopy(file, cmd, arg, usbvision_do_vbi_ioctl);
}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index d7ad060640bc..1e3b4fe5ae93 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -288,8 +288,10 @@ static int uvc_parse_format(struct uvc_device *dev,
struct uvc_format_desc *fmtdesc;
struct uvc_frame *frame;
const unsigned char *start = buffer;
+ unsigned char *_buffer;
unsigned int interval;
unsigned int i, n;
+ int _buflen;
__u8 ftype;
format->type = buffer[2];
@@ -410,12 +412,20 @@ static int uvc_parse_format(struct uvc_device *dev,
buflen -= buffer[0];
buffer += buffer[0];
+ /* Count the number of frame descriptors to test the bFrameIndex
+ * field when parsing the descriptors. We can't rely on the
+ * bNumFrameDescriptors field as some cameras don't initialize it
+ * properly.
+ */
+ for (_buflen = buflen, _buffer = buffer;
+ _buflen > 2 && _buffer[2] == ftype;
+ _buflen -= _buffer[0], _buffer += _buffer[0])
+ format->nframes++;
+
/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
* based formats have frame descriptors.
*/
while (buflen > 2 && buffer[2] == ftype) {
- frame = &format->frame[format->nframes];
-
if (ftype != VS_FRAME_FRAME_BASED)
n = buflen > 25 ? buffer[25] : 0;
else
@@ -430,6 +440,16 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
+ if (buffer[3] - 1 >= format->nframes) {
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ "interface %d frame index %u out of range\n",
+ dev->udev->devnum, alts->desc.bInterfaceNumber,
+ buffer[3]);
+ return -EINVAL;
+ }
+
+ frame = &format->frame[buffer[3] - 1];
+
frame->bFrameIndex = buffer[3];
frame->bmCapabilities = buffer[4];
frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]);
@@ -486,7 +506,6 @@ static int uvc_parse_format(struct uvc_device *dev,
10000000/frame->dwDefaultFrameInterval,
(100000000/frame->dwDefaultFrameInterval)%10);
- format->nframes++;
buflen -= buffer[0];
buffer += buffer[0];
}
@@ -1707,24 +1726,6 @@ static int uvc_reset_resume(struct usb_interface *intf)
* though they are compliant.
*/
static struct usb_device_id uvc_ids[] = {
- /* ALi M5606 (Clevo M540SR) */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x0402,
- .idProduct = 0x5606,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Creative Live! Optia */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x041e,
- .idProduct = 0x4057,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Microsoft Lifecam NX-6000 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1810,15 +1811,6 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Silicon Motion SM371 */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x090c,
- .idProduct = 0xb371,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1837,6 +1829,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Syntek (Samsung Q310) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x5931,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Asus F9SG */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1855,6 +1856,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Lenovo Thinkpad SL500 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x17ef,
+ .idProduct = 0x480b,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Ecamm Pico iMage */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1885,105 +1895,6 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_IGNORE_SELECTOR_UNIT},
- /* Acer OEM Webcam - Unknown vendor */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0100,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Packard Bell OEM Webcam - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0101,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Acer Crystal Eye webcam - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0102,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Compaq Presario B1200 - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0104,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Acer Travelmate 7720 - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0105,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Medion Akoya Mini E1210 - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0141,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Acer OrbiCam - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0200,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Fujitsu Amilo SI2636 - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0202,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Advent 4211 - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0203,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0300,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
- /* Clevo M570TU - Bison Electronics */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
- | USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x5986,
- .idProduct = 0x0303,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
{}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 758dfefaba8d..624bf74de673 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -252,7 +252,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
if (ret < 0)
return ret;
- if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
+ if ((ret = uvc_commit_video(video, &probe)) < 0)
return ret;
memcpy(&video->streaming->ctrl, &probe, sizeof probe);
@@ -316,7 +316,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
return ret;
/* Commit the new settings. */
- if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
+ if ((ret = uvc_commit_video(video, &probe)) < 0)
return ret;
memcpy(&video->streaming->ctrl, &probe, sizeof probe);
@@ -464,8 +464,7 @@ static int uvc_v4l2_release(struct inode *inode, struct file *file)
return 0;
}
-static int __uvc_v4l2_do_ioctl(struct file *file,
- unsigned int cmd, void *arg)
+static int uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = video_devdata(file);
struct uvc_video_device *video = video_get_drvdata(vdev);
@@ -979,7 +978,7 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
default:
if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
- __uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
+ uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n",
cmd);
return ret;
@@ -988,17 +987,11 @@ static int __uvc_v4l2_do_ioctl(struct file *file,
return ret;
}
-static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
-{
- return __uvc_v4l2_do_ioctl(file, cmd, arg);
-}
-
static int uvc_v4l2_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_ioctl\n");
- return video_usercopy(inode, file, cmd, arg, uvc_v4l2_do_ioctl);
+ return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
}
static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index b7bb23820d80..4af94707ef69 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -36,15 +36,22 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
{
__u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
unsigned int pipe;
- int ret;
pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
: usb_sndctrlpipe(dev->udev, 0);
type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
- ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8,
+ return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
unit << 8 | intfnum, data, size, timeout);
+}
+
+int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
+ __u8 intfnum, __u8 cs, void *data, __u16 size)
+{
+ int ret;
+ ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
+ UVC_CTRL_CONTROL_TIMEOUT);
if (ret != size) {
uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
"(unit %u) : %d (exp. %u).\n", query, cs, unit, ret,
@@ -55,13 +62,6 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
return 0;
}
-int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
- __u8 intfnum, __u8 cs, void *data, __u16 size)
-{
- return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
- UVC_CTRL_CONTROL_TIMEOUT);
-}
-
static void uvc_fixup_buffer_size(struct uvc_video_device *video,
struct uvc_streaming_control *ctrl)
{
@@ -102,8 +102,36 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
UVC_CTRL_STREAMING_TIMEOUT);
- if (ret < 0)
+
+ if ((query == GET_MIN || query == GET_MAX) && ret == 2) {
+ /* Some cameras, mostly based on Bison Electronics chipsets,
+ * answer a GET_MIN or GET_MAX request with the wCompQuality
+ * field only.
+ */
+ uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non "
+ "compliance - GET_MIN/MAX(PROBE) incorrectly "
+ "supported. Enabling workaround.\n");
+ memset(ctrl, 0, sizeof ctrl);
+ ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
+ ret = 0;
goto out;
+ } else if (query == GET_DEF && probe == 1) {
+ /* Many cameras don't support the GET_DEF request on their
+ * video probe control. Warn once and return, the caller will
+ * fall back to GET_CUR.
+ */
+ uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non "
+ "compliance - GET_DEF(PROBE) not supported. "
+ "Enabling workaround.\n");
+ ret = -EIO;
+ goto out;
+ } else if (ret != size) {
+ uvc_printk(KERN_ERR, "Failed to query (%u) UVC %s control : "
+ "%d (exp. %u).\n", query, probe ? "probe" : "commit",
+ ret, size);
+ ret = -EIO;
+ goto out;
+ }
ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
ctrl->bFormatIndex = data[2];
@@ -138,13 +166,14 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
* Try to get the value from the format and frame descriptor.
*/
uvc_fixup_buffer_size(video, ctrl);
+ ret = 0;
out:
kfree(data);
return ret;
}
-int uvc_set_video_ctrl(struct uvc_video_device *video,
+static int uvc_set_video_ctrl(struct uvc_video_device *video,
struct uvc_streaming_control *ctrl, int probe)
{
__u8 *data;
@@ -186,6 +215,12 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
video->streaming->intfnum,
probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
UVC_CTRL_STREAMING_TIMEOUT);
+ if (ret != size) {
+ uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
+ "%d (exp. %u).\n", probe ? "probe" : "commit",
+ ret, size);
+ ret = -EIO;
+ }
kfree(data);
return ret;
@@ -252,6 +287,12 @@ done:
return ret;
}
+int uvc_commit_video(struct uvc_video_device *video,
+ struct uvc_streaming_control *probe)
+{
+ return uvc_set_video_ctrl(video, probe, 0);
+}
+
/* ------------------------------------------------------------------------
* Video codecs
*/
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 9a6bc1aafb16..595b90ee6528 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -617,6 +617,7 @@ enum uvc_device_state {
struct uvc_device {
struct usb_device *udev;
struct usb_interface *intf;
+ unsigned long warnings;
__u32 quirks;
int intfnum;
char name[32];
@@ -679,6 +680,9 @@ struct uvc_driver {
#define UVC_TRACE_SUSPEND (1 << 8)
#define UVC_TRACE_STATUS (1 << 9)
+#define UVC_WARN_MINMAX 0
+#define UVC_WARN_PROBE_DEF 1
+
extern unsigned int uvc_trace_param;
#define uvc_trace(flag, msg...) \
@@ -687,6 +691,12 @@ extern unsigned int uvc_trace_param;
printk(KERN_DEBUG "uvcvideo: " msg); \
} while (0)
+#define uvc_warn_once(dev, warn, msg...) \
+ do { \
+ if (!test_and_set_bit(warn, &dev->warnings)) \
+ printk(KERN_INFO "uvcvideo: " msg); \
+ } while (0)
+
#define uvc_printk(level, msg...) \
printk(level "uvcvideo: " msg)
@@ -740,10 +750,10 @@ extern int uvc_video_resume(struct uvc_video_device *video);
extern int uvc_video_enable(struct uvc_video_device *video, int enable);
extern int uvc_probe_video(struct uvc_video_device *video,
struct uvc_streaming_control *probe);
+extern int uvc_commit_video(struct uvc_video_device *video,
+ struct uvc_streaming_control *ctrl);
extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
__u8 intfnum, __u8 cs, void *data, __u16 size);
-extern int uvc_set_video_ctrl(struct uvc_video_device *video,
- struct uvc_streaming_control *ctrl, int probe);
/* Status */
extern int uvc_status_init(struct uvc_device *dev);
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 846763d7349e..fdc8871f631e 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -28,7 +28,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Author: Alan Cox, <alan@redhat.com>
+ * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
*
* Fixes:
*/
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index e6ca4012b5f0..012f8bedddd6 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -32,7 +32,7 @@ struct video_tuner32 {
static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
{
- if(!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) ||
+ if (!access_ok(VERIFY_READ, up, sizeof(struct video_tuner32)) ||
get_user(kp->tuner, &up->tuner) ||
copy_from_user(kp->name, up->name, 32) ||
get_user(kp->rangelow, &up->rangelow) ||
@@ -46,7 +46,7 @@ static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user
static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
{
- if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) ||
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_tuner32)) ||
put_user(kp->tuner, &up->tuner) ||
copy_to_user(up->name, kp->name, 32) ||
put_user(kp->rangelow, &up->rangelow) ||
@@ -88,7 +88,7 @@ static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __u
{
u32 tmp = (u32)((unsigned long)kp->base);
- if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) ||
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_buffer32)) ||
put_user(tmp, &up->base) ||
put_user(kp->height, &up->height) ||
put_user(kp->width, &up->width) ||
@@ -130,7 +130,7 @@ static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
/* You get back everything except the clips... */
static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
{
- if(!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) ||
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct video_window32)) ||
put_user(kp->x, &up->x) ||
put_user(kp->y, &up->y) ||
put_user(kp->width, &up->width) ||
@@ -143,14 +143,12 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u
}
#endif
-struct v4l2_clip32
-{
+struct v4l2_clip32 {
struct v4l2_rect c;
compat_caddr_t next;
};
-struct v4l2_window32
-{
+struct v4l2_window32 {
struct v4l2_rect w;
enum v4l2_field field;
__u32 chromakey;
@@ -231,15 +229,13 @@ static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vb
return 0;
}
-struct v4l2_format32
-{
+struct v4l2_format32 {
enum v4l2_buf_type type;
- union
- {
- struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
- struct v4l2_window32 win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
- struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
- __u8 raw_data[200]; // user-defined
+ union {
+ struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
+ struct v4l2_window32 win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
+ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
+ __u8 raw_data[200]; /* user-defined */
} fmt;
};
@@ -256,7 +252,7 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
case V4L2_BUF_TYPE_VBI_CAPTURE:
return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
default:
- printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n",
+ printk(KERN_INFO "compat_ioctl: unexpected VIDIOC_FMT type %d\n",
kp->type);
return -ENXIO;
}
@@ -264,7 +260,7 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
{
- if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
put_user(kp->type, &up->type))
return -EFAULT;
switch (kp->type) {
@@ -294,8 +290,7 @@ static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standa
return 0;
}
-struct v4l2_standard32
-{
+struct v4l2_standard32 {
__u32 index;
__u32 id[2]; /* __u64 would get the alignment wrong */
__u8 name[24];
@@ -315,7 +310,7 @@ static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
{
- if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
put_user(kp->index, &up->index) ||
copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
copy_to_user(up->name, kp->name, 24) ||
@@ -341,8 +336,7 @@ static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user
return 0;
}
-struct v4l2_buffer32
-{
+struct v4l2_buffer32 {
__u32 index;
enum v4l2_buf_type type;
__u32 bytesused;
@@ -373,7 +367,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
get_user(kp->memory, &up->memory) ||
get_user(kp->input, &up->input))
return -EFAULT;
- switch(kp->memory) {
+ switch (kp->memory) {
case V4L2_MEMORY_MMAP:
break;
case V4L2_MEMORY_USERPTR:
@@ -388,7 +382,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
}
break;
case V4L2_MEMORY_OVERLAY:
- if(get_user(kp->m.offset, &up->m.offset))
+ if (get_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
}
@@ -404,7 +398,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
put_user(kp->memory, &up->memory) ||
put_user(kp->input, &up->input))
return -EFAULT;
- switch(kp->memory) {
+ switch (kp->memory) {
case V4L2_MEMORY_MMAP:
if (put_user(kp->length, &up->length) ||
put_user(kp->m.offset, &up->m.offset))
@@ -431,8 +425,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
return 0;
}
-struct v4l2_framebuffer32
-{
+struct v4l2_framebuffer32 {
__u32 capability;
__u32 flags;
compat_caddr_t base;
@@ -457,7 +450,7 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
{
u32 tmp = (u32)((unsigned long)kp->base);
- if(!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
put_user(tmp, &up->base) ||
put_user(kp->capability, &up->capability) ||
put_user(kp->flags, &up->flags))
@@ -495,8 +488,7 @@ static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user
}
#ifdef CONFIG_VIDEO_V4L1_COMPAT
-struct video_code32
-{
+struct video_code32 {
char loadwhat[16]; /* name or tag of file being passed */
compat_int_t datasize;
unsigned char *data;
@@ -504,28 +496,28 @@ struct video_code32
static inline int microcode32(struct video_code *kp, struct video_code32 __user *up)
{
- if(!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) ||
- copy_from_user(kp->loadwhat, up->loadwhat, sizeof (up->loadwhat)) ||
+ if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) ||
+ copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) ||
get_user(kp->datasize, &up->datasize) ||
copy_from_user(kp->data, up->data, up->datasize))
return -EFAULT;
return 0;
}
-#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
-#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
-#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
-#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
-#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
-#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
-#define VIDIOCGFREQ32 _IOR('v',14, u32)
-#define VIDIOCSFREQ32 _IOW('v',15, u32)
-#define VIDIOCSMICROCODE32 _IOW('v',27, struct video_code32)
+#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32)
+#define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32)
+#define VIDIOCGWIN32 _IOR('v', 9, struct video_window32)
+#define VIDIOCSWIN32 _IOW('v', 10, struct video_window32)
+#define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32)
+#define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32)
+#define VIDIOCGFREQ32 _IOR('v', 14, u32)
+#define VIDIOCSFREQ32 _IOW('v', 15, u32)
+#define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32)
#endif
/* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */
-#define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4)
+#define VIDIOC_ENUMINPUT32 (VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4))
#define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32)
#define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32)
#define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32)
@@ -635,7 +627,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
int realcmd = cmd;
/* First, convert the command. */
- switch(cmd) {
+ switch (cmd) {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
case VIDIOCGTUNER32: realcmd = cmd = VIDIOCGTUNER; break;
case VIDIOCSTUNER32: realcmd = cmd = VIDIOCSTUNER; break;
@@ -664,7 +656,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case VIDIOC_TRY_FMT32: realcmd = cmd = VIDIOC_TRY_FMT; break;
};
- switch(cmd) {
+ switch (cmd) {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
case VIDIOCSTUNER:
case VIDIOCGTUNER:
@@ -750,20 +742,20 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg
break;
#endif
};
- if(err)
+ if (err)
goto out;
- if(compatible_arg)
+ if (compatible_arg)
err = native_ioctl(file, realcmd, (unsigned long)up);
else {
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- err = native_ioctl(file, realcmd, (unsigned long) &karg);
+ err = native_ioctl(file, realcmd, (unsigned long)&karg);
set_fs(old_fs);
}
- if(err == 0) {
- switch(cmd) {
+ if (err == 0) {
+ switch (cmd) {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
case VIDIOCGTUNER:
err = put_video_tuner32(&karg.vt, up);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index ccd6566a515e..682f48aadcac 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -9,7 +9,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Authors: Alan Cox, <alan@redhat.com> (version 1)
+ * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
* Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
*
* Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
@@ -339,7 +339,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
if (vfd->parent)
vfd->dev.parent = vfd->parent;
- sprintf(vfd->dev.bus_id, "%s%d", name_base, nr);
+ dev_set_name(&vfd->dev, "%s%d", name_base, nr);
ret = device_register(&vfd->dev);
if (ret < 0) {
printk(KERN_ERR "%s: device_register failed\n", __func__);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 710e1a40c422..0e648cb3b399 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Authors: Alan Cox, <alan@redhat.com> (version 1)
+ * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
* Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
*/
@@ -393,10 +393,8 @@ video_fix_command(unsigned int cmd)
* Obsolete usercopy function - Should be removed soon
*/
int
-video_usercopy(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- int (*func)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg))
+video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
+ v4l2_kioctl func)
{
char sbuf[128];
void *mbuf = NULL;
@@ -458,7 +456,7 @@ video_usercopy(struct inode *inode, struct file *file,
}
/* call driver */
- err = func(inode, file, cmd, parg);
+ err = func(file, cmd, parg);
if (err == -ENOIOCTLCMD)
err = -EINVAL;
if (is_ext_ctrl) {
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 1efc5f3462c6..a72a361daade 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4237,8 +4237,7 @@ error:
return ret;
}
-static int vino_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vino_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct vino_channel_settings *vcs = video_drvdata(file);
@@ -4353,7 +4352,7 @@ static int vino_ioctl(struct inode *inode, struct file *file,
if (mutex_lock_interruptible(&vcs->mutex))
return -EINTR;
- ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
+ ret = video_usercopy(file, cmd, arg, vino_do_ioctl);
mutex_unlock(&vcs->mutex);
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index b2dbe48a92bb..56c570c267ea 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -727,8 +727,7 @@ static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
* Video4linux interfacing
*/
-static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct w9966_dev *cam = video_drvdata(file);
@@ -881,7 +880,7 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl);
+ return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl);
}
// Capture data
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 9fc581707638..9d00e6056491 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1020,7 +1020,7 @@ zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg)
strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
+ strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
sizeof(cap.bus_info));
if (copy_to_user(arg, &cap, sizeof(cap)))
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index db11ab9e60da..00b97d97aeaa 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1940,11 +1940,7 @@ zoran_set_input (struct zoran *zr,
* ioctl routine
*/
-static int
-zoran_do_ioctl (struct inode *inode,
- struct file *file,
- unsigned int cmd,
- void *arg)
+static int zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
@@ -4201,7 +4197,7 @@ zoran_ioctl (struct inode *inode,
unsigned int cmd,
unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, zoran_do_ioctl);
+ return video_usercopy(file, cmd, arg, zoran_do_ioctl);
}
static unsigned int
diff --git a/firmware/Makefile b/firmware/Makefile
index ca8cd305ff93..bc3dc8100009 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -147,27 +147,15 @@ $(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/%
$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
$(call cmd,ihex)
-# Don't depend on ihex2fw if we're installing and it already exists.
-# Putting it after | in the dependencies doesn't seem sufficient when
-# we're installing after a cross-compile, because ihex2fw has dependencies
-# on stuff like /usr/lib/gcc/ppc64-redhat-linux/4.3.0/include/stddef.h and
-# thus wants to be rebuilt. Which it can't be, if the prebuilt kernel tree
-# is exported read-only for someone to run 'make install'.
-ifeq ($(INSTALL):$(wildcard $(obj)/ihex2fw),install:$(obj)/ihex2fw)
-ihex2fw_dep :=
-else
-ihex2fw_dep := $(obj)/ihex2fw
-endif
-
# .HEX is also Intel HEX, but where the offset and length in each record
# is actually meaningful, because the firmware has to be loaded in a certain
# order rather than as a single binary blob. Thus, we convert them into our
# more compact binary representation of ihex records (<linux/ihex.h>)
-$(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %)
+$(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %)
$(call cmd,ihex2fw)
# .H16 is our own modified form of Intel HEX, with 16-bit length for records.
-$(obj)/%.fw: $(obj)/%.H16 $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %)
+$(obj)/%.fw: $(obj)/%.H16 $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %)
$(call cmd,h16tofw)
$(firmware-dirs):
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 4669d7e72e75..ec311d4616cd 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -293,6 +293,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */
#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */
#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */
diff --git a/include/media/ov772x.h b/include/media/ov772x.h
new file mode 100644
index 000000000000..e391d55edb95
--- /dev/null
+++ b/include/media/ov772x.h
@@ -0,0 +1,21 @@
+/* ov772x Camera
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __OV772X_H__
+#define __OV772X_H__
+
+#include <media/soc_camera.h>
+
+struct ov772x_camera_info {
+ unsigned long buswidth;
+ struct soc_camera_link link;
+};
+
+#endif /* __OV772X_H__ */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 1d104096619c..6bbb0d93bb5f 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -216,8 +216,7 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
extern struct saa7146_use_ops saa7146_video_uops;
int saa7146_start_preview(struct saa7146_fh *fh);
int saa7146_stop_preview(struct saa7146_fh *fh);
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg);
+int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
/* from saa7146_vbi.c */
extern struct saa7146_use_ops saa7146_vbi_uops;
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index c5de7bb19fda..9231e2d908f2 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -56,7 +56,7 @@ struct soc_camera_host {
struct device dev;
unsigned char nr; /* Host number */
void *priv;
- char *drv_name;
+ const char *drv_name;
struct soc_camera_host_ops *ops;
};
@@ -107,7 +107,7 @@ extern int soc_camera_video_start(struct soc_camera_device *icd);
extern void soc_camera_video_stop(struct soc_camera_device *icd);
struct soc_camera_data_format {
- char *name;
+ const char *name;
unsigned int depth;
__u32 fourcc;
enum v4l2_colorspace colorspace;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index d73a8e9028a5..bfe5142e6672 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -60,6 +60,7 @@ enum {
/* OmniVision sensors: reserved range 250-299 */
V4L2_IDENT_OV7670 = 250,
+ V4L2_IDENT_OV772X = 251,
/* Conexant MPEG encoder/decoders: reserved range 410-420 */
V4L2_IDENT_CX23415 = 415,
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index e6ba25b3d7c8..f5985724c456 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -285,10 +285,8 @@ extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
unsigned long arg);
/* Include support for obsoleted stuff */
-extern int video_usercopy(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- int (*func)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg));
+extern int video_usercopy(struct file *file, unsigned int cmd,
+ unsigned long arg, v4l2_kioctl func);
/* Standard handlers for V4L ioctl's */
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index c13a178383ba..549b4eba1496 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- */
+ */
#include <asm/io.h>
#include <linux/delay.h>
@@ -89,7 +89,7 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
{
struct snd_tea575x *tea = video_drvdata(file);
void __user *arg = (void __user *)data;
-
+
switch(cmd) {
case VIDIOCGCAP:
{
@@ -110,9 +110,9 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
case VIDIOCGTUNER:
{
struct video_tuner v;
- if (copy_from_user(&v, arg,sizeof(v))!=0)
+ if (copy_from_user(&v, arg,sizeof(v))!=0)
return -EFAULT;
- if (v.tuner) /* Only 1 tuner */
+ if (v.tuner) /* Only 1 tuner */
return -EINVAL;
v.rangelow = (87*16000);
v.rangehigh = (108*16000);
@@ -144,24 +144,24 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
snd_tea575x_set_freq(tea);
return 0;
case VIDIOCGAUDIO:
- {
+ {
struct video_audio v;
memset(&v, 0, sizeof(v));
strcpy(v.name, "Radio");
if(copy_to_user(arg,&v, sizeof(v)))
return -EFAULT;
- return 0;
+ return 0;
}
case VIDIOCSAUDIO:
{
struct video_audio v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
if (tea->ops->mute)
tea->ops->mute(tea,
(v.flags &
VIDEO_AUDIO_MUTE) ? 1 : 0);
- if(v.audio)
+ if(v.audio)
return -EINVAL;
return 0;
}
@@ -240,11 +240,11 @@ static int __init alsa_tea575x_module_init(void)
{
return 0;
}
-
+
static void __exit alsa_tea575x_module_exit(void)
{
}
-
+
module_init(alsa_tea575x_module_init)
module_exit(alsa_tea575x_module_exit)