aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 00:12:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 00:12:49 -0400
commitdf462b3dbeeaae7141f1b63cbfcc1e1bae6a85fc (patch)
treebca52fce066159f136d75c69e79016422212cb1d /drivers
parent343800e7d20944aead238c2c6e3f7789f8b6587c (diff)
parentcf25220677b3f10468a74278130fe224f73632a6 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (247 commits) [media] gspca - sunplus: Fix some warnings and simplify code [media] gspca: Fix some warnings tied to 'no debug' [media] gspca: Unset debug by default [media] gspca - cpia1: Remove a bad conditional compilation instruction [media] gspca - main: Remove USB traces [media] gspca - main: Version change to 2.13 [media] gspca - stk014 / t613: Accept the index 0 in querymenu [media] gspca - kinect: Remove __devinitdata [media] gspca - cpia1: Fix some warnings [media] video/Kconfig: Fix mis-classified devices [media] support for medion dvb stick 1660:1921 [media] tm6000: fix uninitialized field, change prink to dprintk [media] cx231xx: Add support for Iconbit U100 [media] saa7134 add new TV cards [media] Use a more consistent value for RC repeat period [media] cx18: Move spinlock and vb_type initialisation into stream_init [media] tm6000: remove tm6010 sif audio start and stop [media] tm6000: remove unused exports [media] tm6000: add pts logging [media] tm6000: change from ioctl to unlocked_ioctl ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/common/saa7146_core.c7
-rw-r--r--drivers/media/common/tuners/Kconfig8
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/mxl5005s.c2
-rw-r--r--drivers/media/common/tuners/tda18212.c265
-rw-r--r--drivers/media/common/tuners/tda18212.h48
-rw-r--r--drivers/media/common/tuners/tda18212_priv.h44
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c4
-rw-r--r--drivers/media/common/tuners/xc5000.c32
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c4
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c117
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c365
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h3
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig5
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c17
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c620
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.h23
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.c22
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c11
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c220
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c31
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c10
-rw-r--r--drivers/media/dvb/dvb-usb/ec168.c18
-rw-r--r--drivers/media/dvb/dvb-usb/friio.c23
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c165
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.h5
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c49
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c33
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c80
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c213
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.h7
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c47
-rw-r--r--drivers/media/dvb/frontends/Kconfig19
-rw-r--r--drivers/media/dvb/frontends/Makefile6
-rw-r--r--drivers/media/dvb/frontends/bsbe1-d01a.h146
-rw-r--r--drivers/media/dvb/frontends/bsru6.h2
-rw-r--r--drivers/media/dvb/frontends/cx24116.c21
-rw-r--r--drivers/media/dvb/frontends/cx24116.h3
-rw-r--r--drivers/media/dvb/frontends/cxd2820r.h118
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_c.c338
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_core.c915
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_priv.h166
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t.c449
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t2.c423
-rw-r--r--drivers/media/dvb/frontends/dib0070.c40
-rw-r--r--drivers/media/dvb/frontends/dib0090.c71
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c49
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c72
-rw-r--r--drivers/media/dvb/frontends/dib8000.c126
-rw-r--r--drivers/media/dvb/frontends/dib9000.c176
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c109
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h5
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c1511
-rw-r--r--drivers/media/dvb/frontends/drx397xD.h130
-rw-r--r--drivers/media/dvb/frontends/drx397xD_fw.h40
-rw-r--r--drivers/media/dvb/frontends/drxd.h61
-rw-r--r--drivers/media/dvb/frontends/drxd_firm.c929
-rw-r--r--drivers/media/dvb/frontends/drxd_firm.h115
-rw-r--r--drivers/media/dvb/frontends/drxd_hard.c3001
-rw-r--r--drivers/media/dvb/frontends/drxd_map_firm.h1013
-rw-r--r--drivers/media/dvb/frontends/eds1547.h2
-rw-r--r--drivers/media/dvb/frontends/ix2505v.c10
-rw-r--r--drivers/media/dvb/frontends/stv0288.c2
-rw-r--r--drivers/media/dvb/frontends/stv0299.c10
-rw-r--r--drivers/media/dvb/frontends/z0194a.h2
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_pci.c5
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1033.c2
-rw-r--r--drivers/media/dvb/pt1/pt1.c5
-rw-r--r--drivers/media/dvb/siano/smsusb.c3
-rw-r--r--drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c21
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c60
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c60
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c63
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h4
-rw-r--r--drivers/media/radio/wl128x/fmdrv.h2
-rw-r--r--drivers/media/rc/Kconfig11
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/imon.c36
-rw-r--r--drivers/media/rc/ite-cir.c60
-rw-r--r--drivers/media/rc/keymaps/Makefile1
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-cardbus.c2
-rw-r--r--drivers/media/rc/keymaps/rc-imon-mce.c2
-rw-r--r--drivers/media/rc/keymaps/rc-imon-pad.c6
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c2
-rw-r--r--drivers/media/rc/keymaps/rc-rc6-mce.c4
-rw-r--r--drivers/media/rc/keymaps/rc-tivo.c98
-rw-r--r--drivers/media/rc/keymaps/rc-winfast.c4
-rw-r--r--drivers/media/rc/mceusb.c34
-rw-r--r--drivers/media/rc/nuvoton-cir.c75
-rw-r--r--drivers/media/rc/nuvoton-cir.h17
-rw-r--r--drivers/media/rc/rc-loopback.c6
-rw-r--r--drivers/media/rc/rc-main.c54
-rw-r--r--drivers/media/rc/redrat3.c1344
-rw-r--r--drivers/media/rc/winbond-cir.c447
-rw-r--r--drivers/media/video/Kconfig149
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c2
-rw-r--r--drivers/media/video/cx18/Kconfig4
-rw-r--r--drivers/media/video/cx18/cx18-cards.c18
-rw-r--r--drivers/media/video/cx18/cx18-cards.h2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c27
-rw-r--r--drivers/media/video/cx18/cx18-driver.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c70
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c144
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c58
-rw-r--r--drivers/media/video/cx18/cx18-streams.c177
-rw-r--r--drivers/media/video/cx18/cx18-version.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h6
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c67
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c2
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c41
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c42
-rw-r--r--drivers/media/video/cx88/cx88-video.c7
-rw-r--r--drivers/media/video/cx88/cx88.h11
-rw-r--r--drivers/media/video/em28xx/Kconfig2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c49
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c9
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c160
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/video/em28xx/em28xx.h3
-rw-r--r--drivers/media/video/fsl-viu.c56
-rw-r--r--drivers/media/video/gspca/Kconfig9
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/cpia1.c6
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c15
-rw-r--r--drivers/media/video/gspca/gspca.c4
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/jeilinj.c581
-rw-r--r--drivers/media/video/gspca/kinect.c429
-rw-r--r--drivers/media/video/gspca/spca508.c5
-rw-r--r--drivers/media/video/gspca/stk014.c15
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c2
-rw-r--r--drivers/media/video/gspca/sunplus.c99
-rw-r--r--drivers/media/video/gspca/t613.c17
-rw-r--r--drivers/media/video/gspca/zc3xx.c47
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c4
-rw-r--r--drivers/media/video/mt9m111.c14
-rw-r--r--drivers/media/video/mt9v022.c2
-rw-r--r--drivers/media/video/mt9v032.c773
-rw-r--r--drivers/media/video/mx3_camera.c60
-rw-r--r--drivers/media/video/omap1_camera.c43
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.c10
-rw-r--r--drivers/media/video/pwc/pwc-if.c2
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c23
-rw-r--r--drivers/media/video/pxa_camera.c8
-rw-r--r--drivers/media/video/s2255drv.c27
-rw-r--r--drivers/media/video/s5p-fimc/Makefile6
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.c724
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.h22
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c125
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c34
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c8
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c148
-rw-r--r--drivers/media/video/soc_camera.c29
-rw-r--r--drivers/media/video/soc_mediabus.c265
-rw-r--r--drivers/media/video/tveeprom.c32
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c33
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.h2
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c165
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c3
-rw-r--r--drivers/media/video/usbvision/usbvision.h6
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c367
-rw-r--r--drivers/media/video/uvc/uvc_driver.c28
-rw-r--r--drivers/media/video/uvc/uvc_queue.c34
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c68
-rw-r--r--drivers/media/video/uvc/uvcvideo.h64
-rw-r--r--drivers/media/video/v4l2-dev.c18
-rw-r--r--drivers/media/video/via-camera.c1
-rw-r--r--drivers/media/video/zoran/zoran_card.c10
-rw-r--r--drivers/staging/lirc/lirc_sasem.c13
-rw-r--r--drivers/staging/tm6000/CARDLIST16
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c3
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c381
-rw-r--r--drivers/staging/tm6000/tm6000-core.c109
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c33
-rw-r--r--drivers/staging/tm6000/tm6000-stds.c923
-rw-r--r--drivers/staging/tm6000/tm6000-usb-isoc.h2
-rw-r--r--drivers/staging/tm6000/tm6000-video.c212
-rw-r--r--drivers/staging/tm6000/tm6000.h46
199 files changed, 17643 insertions, 4681 deletions
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 9f47e383c57a..9af2140b57a4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -378,12 +378,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
378 dev->pci = pci; 378 dev->pci = pci;
379 379
380 /* get chip-revision; this is needed to enable bug-fixes */ 380 /* get chip-revision; this is needed to enable bug-fixes */
381 err = pci_read_config_dword(pci, PCI_CLASS_REVISION, &dev->revision); 381 dev->revision = pci->revision;
382 if (err < 0) {
383 ERR(("pci_read_config_dword() failed.\n"));
384 goto err_disable;
385 }
386 dev->revision &= 0xf;
387 382
388 /* remap the memory from virtual to physical address */ 383 /* remap the memory from virtual to physical address */
389 384
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 6fc79f15dcbc..22d3ca36370e 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -186,4 +186,12 @@ config MEDIA_TUNER_TDA18218
186 default m if MEDIA_TUNER_CUSTOMISE 186 default m if MEDIA_TUNER_CUSTOMISE
187 help 187 help
188 NXP TDA18218 silicon tuner driver. 188 NXP TDA18218 silicon tuner driver.
189
190config MEDIA_TUNER_TDA18212
191 tristate "NXP TDA18212 silicon tuner"
192 depends on VIDEO_MEDIA && I2C
193 default m if MEDIA_TUNER_CUSTOMISE
194 help
195 NXP TDA18212 silicon tuner driver.
196
189endmenu 197endmenu
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 96da03d349ca..2cb4f5327843 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o 25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
26obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o 26obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
27obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o 27obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
28obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
28 29
29EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 30EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
30EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 31EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0d6e09419044..56fe75c94deb 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -4024,6 +4024,8 @@ static int mxl5005s_set_params(struct dvb_frontend *fe,
4024 case BANDWIDTH_8_MHZ: 4024 case BANDWIDTH_8_MHZ:
4025 req_bw = MXL5005S_BANDWIDTH_8MHZ; 4025 req_bw = MXL5005S_BANDWIDTH_8MHZ;
4026 break; 4026 break;
4027 default:
4028 return -EINVAL;
4027 } 4029 }
4028 } 4030 }
4029 4031
diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c
new file mode 100644
index 000000000000..1f1db20d46b1
--- /dev/null
+++ b/drivers/media/common/tuners/tda18212.c
@@ -0,0 +1,265 @@
1/*
2 * NXP TDA18212HN silicon tuner driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include "tda18212_priv.h"
22
23static int debug;
24module_param(debug, int, 0644);
25MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
26
27/* write multiple registers */
28static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
29 int len)
30{
31 int ret;
32 u8 buf[len+1];
33 struct i2c_msg msg[1] = {
34 {
35 .addr = priv->cfg->i2c_address,
36 .flags = 0,
37 .len = sizeof(buf),
38 .buf = buf,
39 }
40 };
41
42 buf[0] = reg;
43 memcpy(&buf[1], val, len);
44
45 ret = i2c_transfer(priv->i2c, msg, 1);
46 if (ret == 1) {
47 ret = 0;
48 } else {
49 warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
50 ret = -EREMOTEIO;
51 }
52 return ret;
53}
54
55/* read multiple registers */
56static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
57 int len)
58{
59 int ret;
60 u8 buf[len];
61 struct i2c_msg msg[2] = {
62 {
63 .addr = priv->cfg->i2c_address,
64 .flags = 0,
65 .len = 1,
66 .buf = &reg,
67 }, {
68 .addr = priv->cfg->i2c_address,
69 .flags = I2C_M_RD,
70 .len = sizeof(buf),
71 .buf = buf,
72 }
73 };
74
75 ret = i2c_transfer(priv->i2c, msg, 2);
76 if (ret == 2) {
77 memcpy(val, buf, len);
78 ret = 0;
79 } else {
80 warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
81 ret = -EREMOTEIO;
82 }
83
84 return ret;
85}
86
87/* write single register */
88static int tda18212_wr_reg(struct tda18212_priv *priv, u8 reg, u8 val)
89{
90 return tda18212_wr_regs(priv, reg, &val, 1);
91}
92
93/* read single register */
94static int tda18212_rd_reg(struct tda18212_priv *priv, u8 reg, u8 *val)
95{
96 return tda18212_rd_regs(priv, reg, val, 1);
97}
98
99#if 0 /* keep, useful when developing driver */
100static void tda18212_dump_regs(struct tda18212_priv *priv)
101{
102 int i;
103 u8 buf[256];
104
105 #define TDA18212_RD_LEN 32
106 for (i = 0; i < sizeof(buf); i += TDA18212_RD_LEN)
107 tda18212_rd_regs(priv, i, &buf[i], TDA18212_RD_LEN);
108
109 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 32, 1, buf,
110 sizeof(buf), true);
111
112 return;
113}
114#endif
115
116static int tda18212_set_params(struct dvb_frontend *fe,
117 struct dvb_frontend_parameters *p)
118{
119 struct tda18212_priv *priv = fe->tuner_priv;
120 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
121 int ret, i;
122 u32 if_khz;
123 u8 buf[9];
124 static const u8 bw_params[][3] = {
125 /* 0f 13 23 */
126 { 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */
127 { 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */
128 { 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */
129 { 0x92, 0x53, 0x03 }, /* DVB-C */
130 };
131
132 dbg("%s: delsys=%d RF=%d BW=%d", __func__,
133 c->delivery_system, c->frequency, c->bandwidth_hz);
134
135 if (fe->ops.i2c_gate_ctrl)
136 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
137
138 switch (c->delivery_system) {
139 case SYS_DVBT:
140 switch (c->bandwidth_hz) {
141 case 6000000:
142 if_khz = priv->cfg->if_dvbt_6;
143 i = 0;
144 break;
145 case 7000000:
146 if_khz = priv->cfg->if_dvbt_7;
147 i = 1;
148 break;
149 case 8000000:
150 if_khz = priv->cfg->if_dvbt_8;
151 i = 2;
152 break;
153 default:
154 ret = -EINVAL;
155 goto error;
156 }
157 break;
158 case SYS_DVBC_ANNEX_AC:
159 if_khz = priv->cfg->if_dvbc;
160 i = 3;
161 break;
162 default:
163 ret = -EINVAL;
164 goto error;
165 }
166
167 ret = tda18212_wr_reg(priv, 0x23, bw_params[i][2]);
168 if (ret)
169 goto error;
170
171 ret = tda18212_wr_reg(priv, 0x06, 0x00);
172 if (ret)
173 goto error;
174
175 ret = tda18212_wr_reg(priv, 0x0f, bw_params[i][0]);
176 if (ret)
177 goto error;
178
179 buf[0] = 0x02;
180 buf[1] = bw_params[i][1];
181 buf[2] = 0x03; /* default value */
182 buf[3] = if_khz / 50;
183 buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
184 buf[5] = ((c->frequency / 1000) >> 8) & 0xff;
185 buf[6] = ((c->frequency / 1000) >> 0) & 0xff;
186 buf[7] = 0xc1;
187 buf[8] = 0x01;
188 ret = tda18212_wr_regs(priv, 0x12, buf, sizeof(buf));
189 if (ret)
190 goto error;
191
192exit:
193 if (fe->ops.i2c_gate_ctrl)
194 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
195
196 return ret;
197
198error:
199 dbg("%s: failed:%d", __func__, ret);
200 goto exit;
201}
202
203static int tda18212_release(struct dvb_frontend *fe)
204{
205 kfree(fe->tuner_priv);
206 fe->tuner_priv = NULL;
207 return 0;
208}
209
210static const struct dvb_tuner_ops tda18212_tuner_ops = {
211 .info = {
212 .name = "NXP TDA18212",
213
214 .frequency_min = 48000000,
215 .frequency_max = 864000000,
216 .frequency_step = 1000,
217 },
218
219 .release = tda18212_release,
220
221 .set_params = tda18212_set_params,
222};
223
224struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
225 struct i2c_adapter *i2c, struct tda18212_config *cfg)
226{
227 struct tda18212_priv *priv = NULL;
228 int ret;
229 u8 val;
230
231 priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
232 if (priv == NULL)
233 return NULL;
234
235 priv->cfg = cfg;
236 priv->i2c = i2c;
237 fe->tuner_priv = priv;
238
239 if (fe->ops.i2c_gate_ctrl)
240 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
241
242 /* check if the tuner is there */
243 ret = tda18212_rd_reg(priv, 0x00, &val);
244
245 if (fe->ops.i2c_gate_ctrl)
246 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
247
248 dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
249 if (ret || val != 0xc7) {
250 kfree(priv);
251 return NULL;
252 }
253
254 info("NXP TDA18212HN successfully identified.");
255
256 memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
257 sizeof(struct dvb_tuner_ops));
258
259 return fe;
260}
261EXPORT_SYMBOL(tda18212_attach);
262
263MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
264MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
265MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tda18212.h b/drivers/media/common/tuners/tda18212.h
new file mode 100644
index 000000000000..83b497f59e1b
--- /dev/null
+++ b/drivers/media/common/tuners/tda18212.h
@@ -0,0 +1,48 @@
1/*
2 * NXP TDA18212HN silicon tuner driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TDA18212_H
22#define TDA18212_H
23
24#include "dvb_frontend.h"
25
26struct tda18212_config {
27 u8 i2c_address;
28
29 u16 if_dvbt_6;
30 u16 if_dvbt_7;
31 u16 if_dvbt_8;
32 u16 if_dvbc;
33};
34
35#if defined(CONFIG_MEDIA_TUNER_TDA18212) || \
36 (defined(CONFIG_MEDIA_TUNER_TDA18212_MODULE) && defined(MODULE))
37extern struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
38 struct i2c_adapter *i2c, struct tda18212_config *cfg);
39#else
40static inline struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
41 struct i2c_adapter *i2c, struct tda18212_config *cfg)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46#endif
47
48#endif
diff --git a/drivers/media/common/tuners/tda18212_priv.h b/drivers/media/common/tuners/tda18212_priv.h
new file mode 100644
index 000000000000..9adff9356b73
--- /dev/null
+++ b/drivers/media/common/tuners/tda18212_priv.h
@@ -0,0 +1,44 @@
1/*
2 * NXP TDA18212HN silicon tuner driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TDA18212_PRIV_H
22#define TDA18212_PRIV_H
23
24#include "tda18212.h"
25
26#define LOG_PREFIX "tda18212"
27
28#undef dbg
29#define dbg(f, arg...) \
30 if (debug) \
31 printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
32#undef err
33#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
34#undef info
35#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
36#undef warn
37#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
38
39struct tda18212_priv {
40 struct tda18212_config *cfg;
41 struct i2c_adapter *i2c;
42};
43
44#endif
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index d884f5eee73c..57022e88e338 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -976,6 +976,10 @@ static int tda18271_set_params(struct dvb_frontend *fe,
976 tda_warn("bandwidth not set!\n"); 976 tda_warn("bandwidth not set!\n");
977 return -EINVAL; 977 return -EINVAL;
978 } 978 }
979 } else if (fe->ops.info.type == FE_QAM) {
980 /* DVB-C */
981 map = &std_map->qam_8;
982 bw = 8000000;
979 } else { 983 } else {
980 tda_warn("modulation type not supported!\n"); 984 tda_warn("modulation type not supported!\n");
981 return -EINVAL; 985 return -EINVAL;
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 1e28f7dcb26b..aa1b2e844d32 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -628,6 +628,15 @@ static void xc_debug_dump(struct xc5000_priv *priv)
628 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); 628 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
629} 629}
630 630
631/*
632 * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
633 * So, the amount of the needed bandwith is given by:
634 * Bw = Symbol_rate * (1 + 0.15)
635 * As such, the maximum symbol rate supported by 6 MHz is given by:
636 * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
637 */
638#define MAX_SYMBOL_RATE_6MHz 5217391
639
631static int xc5000_set_params(struct dvb_frontend *fe, 640static int xc5000_set_params(struct dvb_frontend *fe,
632 struct dvb_frontend_parameters *params) 641 struct dvb_frontend_parameters *params)
633{ 642{
@@ -688,21 +697,32 @@ static int xc5000_set_params(struct dvb_frontend *fe,
688 } 697 }
689 priv->rf_mode = XC_RF_MODE_AIR; 698 priv->rf_mode = XC_RF_MODE_AIR;
690 } else if (fe->ops.info.type == FE_QAM) { 699 } else if (fe->ops.info.type == FE_QAM) {
691 dprintk(1, "%s() QAM\n", __func__);
692 switch (params->u.qam.modulation) { 700 switch (params->u.qam.modulation) {
701 case QAM_256:
702 case QAM_AUTO:
693 case QAM_16: 703 case QAM_16:
694 case QAM_32: 704 case QAM_32:
695 case QAM_64: 705 case QAM_64:
696 case QAM_128: 706 case QAM_128:
697 case QAM_256:
698 case QAM_AUTO:
699 dprintk(1, "%s() QAM modulation\n", __func__); 707 dprintk(1, "%s() QAM modulation\n", __func__);
700 priv->bandwidth = BANDWIDTH_8_MHZ;
701 priv->video_standard = DTV7_8;
702 priv->freq_hz = params->frequency - 2750000;
703 priv->rf_mode = XC_RF_MODE_CABLE; 708 priv->rf_mode = XC_RF_MODE_CABLE;
709 /*
710 * Using a 8MHz bandwidth sometimes fail
711 * with 6MHz-spaced channels, due to inter-carrier
712 * interference. So, use DTV6 firmware
713 */
714 if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) {
715 priv->bandwidth = BANDWIDTH_6_MHZ;
716 priv->video_standard = DTV6;
717 priv->freq_hz = params->frequency - 1750000;
718 } else {
719 priv->bandwidth = BANDWIDTH_8_MHZ;
720 priv->video_standard = DTV7_8;
721 priv->freq_hz = params->frequency - 2750000;
722 }
704 break; 723 break;
705 default: 724 default:
725 dprintk(1, "%s() Unsupported QAM type\n", __func__);
706 return -EINVAL; 726 return -EINVAL;
707 } 727 }
708 } else { 728 } else {
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 03f96d6ca894..44f8fb5f17ff 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -290,10 +290,8 @@ static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
290static int flexcop_pci_init(struct flexcop_pci *fc_pci) 290static int flexcop_pci_init(struct flexcop_pci *fc_pci)
291{ 291{
292 int ret; 292 int ret;
293 u8 card_rev;
294 293
295 pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev); 294 info("card revision %x", fc_pci->pdev->revision);
296 info("card revision %x", card_rev);
297 295
298 if ((ret = pci_enable_device(fc_pci->pdev)) != 0) 296 if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
299 return ret; 297 return ret;
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 99d62094f908..b34fa95185e4 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -460,7 +460,7 @@ static int __devinit bt878_probe(struct pci_dev *dev,
460 goto fail0; 460 goto fail0;
461 } 461 }
462 462
463 pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); 463 bt->revision = dev->revision;
464 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 464 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
465 465
466 466
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 4a88a3e4db2b..faa3671b649e 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -478,97 +478,94 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
478 478
479EXPORT_SYMBOL(dvb_dmx_swfilter_packets); 479EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
480 480
481void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) 481static inline int find_next_packet(const u8 *buf, int pos, size_t count,
482 const int pktsize)
482{ 483{
483 int p = 0, i, j; 484 int start = pos, lost;
484 485
485 spin_lock(&demux->lock); 486 while (pos < count) {
486 487 if (buf[pos] == 0x47 ||
487 if (demux->tsbufp) { 488 (pktsize == 204 && buf[pos] == 0xB8))
488 i = demux->tsbufp; 489 break;
489 j = 188 - i; 490 pos++;
490 if (count < j) {
491 memcpy(&demux->tsbuf[i], buf, count);
492 demux->tsbufp += count;
493 goto bailout;
494 }
495 memcpy(&demux->tsbuf[i], buf, j);
496 if (demux->tsbuf[0] == 0x47)
497 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
498 demux->tsbufp = 0;
499 p += j;
500 } 491 }
501 492
502 while (p < count) { 493 lost = pos - start;
503 if (buf[p] == 0x47) { 494 if (lost) {
504 if (count - p >= 188) { 495 /* This garbage is part of a valid packet? */
505 dvb_dmx_swfilter_packet(demux, &buf[p]); 496 int backtrack = pos - pktsize;
506 p += 188; 497 if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
507 } else { 498 (pktsize == 204 && buf[backtrack] == 0xB8)))
508 i = count - p; 499 return backtrack;
509 memcpy(demux->tsbuf, &buf[p], i);
510 demux->tsbufp = i;
511 goto bailout;
512 }
513 } else
514 p++;
515 } 500 }
516 501
517bailout: 502 return pos;
518 spin_unlock(&demux->lock);
519} 503}
520 504
521EXPORT_SYMBOL(dvb_dmx_swfilter); 505/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
522 506static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
523void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) 507 size_t count, const int pktsize)
524{ 508{
525 int p = 0, i, j; 509 int p = 0, i, j;
526 u8 tmppack[188]; 510 const u8 *q;
527 511
528 spin_lock(&demux->lock); 512 spin_lock(&demux->lock);
529 513
530 if (demux->tsbufp) { 514 if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
531 i = demux->tsbufp; 515 i = demux->tsbufp;
532 j = 204 - i; 516 j = pktsize - i;
533 if (count < j) { 517 if (count < j) {
534 memcpy(&demux->tsbuf[i], buf, count); 518 memcpy(&demux->tsbuf[i], buf, count);
535 demux->tsbufp += count; 519 demux->tsbufp += count;
536 goto bailout; 520 goto bailout;
537 } 521 }
538 memcpy(&demux->tsbuf[i], buf, j); 522 memcpy(&demux->tsbuf[i], buf, j);
539 if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) { 523 if (demux->tsbuf[0] == 0x47) /* double check */
540 memcpy(tmppack, demux->tsbuf, 188); 524 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
541 if (tmppack[0] == 0xB8)
542 tmppack[0] = 0x47;
543 dvb_dmx_swfilter_packet(demux, tmppack);
544 }
545 demux->tsbufp = 0; 525 demux->tsbufp = 0;
546 p += j; 526 p += j;
547 } 527 }
548 528
549 while (p < count) { 529 while (1) {
550 if ((buf[p] == 0x47) || (buf[p] == 0xB8)) { 530 p = find_next_packet(buf, p, count, pktsize);
551 if (count - p >= 204) { 531 if (p >= count)
552 memcpy(tmppack, &buf[p], 188); 532 break;
553 if (tmppack[0] == 0xB8) 533 if (count - p < pktsize)
554 tmppack[0] = 0x47; 534 break;
555 dvb_dmx_swfilter_packet(demux, tmppack); 535
556 p += 204; 536 q = &buf[p];
557 } else { 537
558 i = count - p; 538 if (pktsize == 204 && (*q == 0xB8)) {
559 memcpy(demux->tsbuf, &buf[p], i); 539 memcpy(demux->tsbuf, q, 188);
560 demux->tsbufp = i; 540 demux->tsbuf[0] = 0x47;
561 goto bailout; 541 q = demux->tsbuf;
562 }
563 } else {
564 p++;
565 } 542 }
543 dvb_dmx_swfilter_packet(demux, q);
544 p += pktsize;
545 }
546
547 i = count - p;
548 if (i) {
549 memcpy(demux->tsbuf, &buf[p], i);
550 demux->tsbufp = i;
551 if (pktsize == 204 && demux->tsbuf[0] == 0xB8)
552 demux->tsbuf[0] = 0x47;
566 } 553 }
567 554
568bailout: 555bailout:
569 spin_unlock(&demux->lock); 556 spin_unlock(&demux->lock);
570} 557}
571 558
559void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
560{
561 _dvb_dmx_swfilter(demux, buf, count, 188);
562}
563EXPORT_SYMBOL(dvb_dmx_swfilter);
564
565void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
566{
567 _dvb_dmx_swfilter(demux, buf, count, 204);
568}
572EXPORT_SYMBOL(dvb_dmx_swfilter_204); 569EXPORT_SYMBOL(dvb_dmx_swfilter_204);
573 570
574static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) 571static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 31e2c0d45db3..98278041d75f 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -105,7 +105,8 @@ struct dvb_frontend_private {
105 105
106 /* thread/frontend values */ 106 /* thread/frontend values */
107 struct dvb_device *dvbdev; 107 struct dvb_device *dvbdev;
108 struct dvb_frontend_parameters parameters; 108 struct dvb_frontend_parameters parameters_in;
109 struct dvb_frontend_parameters parameters_out;
109 struct dvb_fe_events events; 110 struct dvb_fe_events events;
110 struct semaphore sem; 111 struct semaphore sem;
111 struct list_head list_head; 112 struct list_head list_head;
@@ -160,12 +161,11 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
160 161
161 e = &events->events[events->eventw]; 162 e = &events->events[events->eventw];
162 163
163 memcpy (&e->parameters, &fepriv->parameters,
164 sizeof (struct dvb_frontend_parameters));
165
166 if (status & FE_HAS_LOCK) 164 if (status & FE_HAS_LOCK)
167 if (fe->ops.get_frontend) 165 if (fe->ops.get_frontend)
168 fe->ops.get_frontend(fe, &e->parameters); 166 fe->ops.get_frontend(fe, &fepriv->parameters_out);
167
168 e->parameters = fepriv->parameters_out;
169 169
170 events->eventw = wp; 170 events->eventw = wp;
171 171
@@ -277,12 +277,12 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
277 int ready = 0; 277 int ready = 0;
278 int fe_set_err = 0; 278 int fe_set_err = 0;
279 struct dvb_frontend_private *fepriv = fe->frontend_priv; 279 struct dvb_frontend_private *fepriv = fe->frontend_priv;
280 int original_inversion = fepriv->parameters.inversion; 280 int original_inversion = fepriv->parameters_in.inversion;
281 u32 original_frequency = fepriv->parameters.frequency; 281 u32 original_frequency = fepriv->parameters_in.frequency;
282 282
283 /* are we using autoinversion? */ 283 /* are we using autoinversion? */
284 autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && 284 autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
285 (fepriv->parameters.inversion == INVERSION_AUTO)); 285 (fepriv->parameters_in.inversion == INVERSION_AUTO));
286 286
287 /* setup parameters correctly */ 287 /* setup parameters correctly */
288 while(!ready) { 288 while(!ready) {
@@ -348,18 +348,19 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
348 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step); 348 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
349 349
350 /* set the frontend itself */ 350 /* set the frontend itself */
351 fepriv->parameters.frequency += fepriv->lnb_drift; 351 fepriv->parameters_in.frequency += fepriv->lnb_drift;
352 if (autoinversion) 352 if (autoinversion)
353 fepriv->parameters.inversion = fepriv->inversion; 353 fepriv->parameters_in.inversion = fepriv->inversion;
354 if (fe->ops.set_frontend) 354 if (fe->ops.set_frontend)
355 fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters); 355 fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters_in);
356 fepriv->parameters_out = fepriv->parameters_in;
356 if (fe_set_err < 0) { 357 if (fe_set_err < 0) {
357 fepriv->state = FESTATE_ERROR; 358 fepriv->state = FESTATE_ERROR;
358 return fe_set_err; 359 return fe_set_err;
359 } 360 }
360 361
361 fepriv->parameters.frequency = original_frequency; 362 fepriv->parameters_in.frequency = original_frequency;
362 fepriv->parameters.inversion = original_inversion; 363 fepriv->parameters_in.inversion = original_inversion;
363 364
364 fepriv->auto_sub_step++; 365 fepriv->auto_sub_step++;
365 return 0; 366 return 0;
@@ -383,7 +384,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
383 if (fepriv->state & FESTATE_RETUNE) { 384 if (fepriv->state & FESTATE_RETUNE) {
384 if (fe->ops.set_frontend) 385 if (fe->ops.set_frontend)
385 retval = fe->ops.set_frontend(fe, 386 retval = fe->ops.set_frontend(fe,
386 &fepriv->parameters); 387 &fepriv->parameters_in);
388 fepriv->parameters_out = fepriv->parameters_in;
387 if (retval < 0) 389 if (retval < 0)
388 fepriv->state = FESTATE_ERROR; 390 fepriv->state = FESTATE_ERROR;
389 else 391 else
@@ -413,8 +415,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
413 415
414 /* if we're tuned, then we have determined the correct inversion */ 416 /* if we're tuned, then we have determined the correct inversion */
415 if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && 417 if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
416 (fepriv->parameters.inversion == INVERSION_AUTO)) { 418 (fepriv->parameters_in.inversion == INVERSION_AUTO)) {
417 fepriv->parameters.inversion = fepriv->inversion; 419 fepriv->parameters_in.inversion = fepriv->inversion;
418 } 420 }
419 return; 421 return;
420 } 422 }
@@ -594,12 +596,14 @@ restart:
594 596
595 if (fepriv->state & FESTATE_RETUNE) { 597 if (fepriv->state & FESTATE_RETUNE) {
596 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__); 598 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
597 params = &fepriv->parameters; 599 params = &fepriv->parameters_in;
598 fepriv->state = FESTATE_TUNED; 600 fepriv->state = FESTATE_TUNED;
599 } 601 }
600 602
601 if (fe->ops.tune) 603 if (fe->ops.tune)
602 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); 604 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
605 if (params)
606 fepriv->parameters_out = *params;
603 607
604 if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) { 608 if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
605 dprintk("%s: state changed, adding current state\n", __func__); 609 dprintk("%s: state changed, adding current state\n", __func__);
@@ -612,11 +616,9 @@ restart:
612 dvb_frontend_swzigzag(fe); 616 dvb_frontend_swzigzag(fe);
613 break; 617 break;
614 case DVBFE_ALGO_CUSTOM: 618 case DVBFE_ALGO_CUSTOM:
615 params = NULL; /* have we been asked to RETUNE ? */
616 dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state); 619 dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
617 if (fepriv->state & FESTATE_RETUNE) { 620 if (fepriv->state & FESTATE_RETUNE) {
618 dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__); 621 dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
619 params = &fepriv->parameters;
620 fepriv->state = FESTATE_TUNED; 622 fepriv->state = FESTATE_TUNED;
621 } 623 }
622 /* Case where we are going to search for a carrier 624 /* Case where we are going to search for a carrier
@@ -625,7 +627,7 @@ restart:
625 */ 627 */
626 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) { 628 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
627 if (fe->ops.search) { 629 if (fe->ops.search) {
628 fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters); 630 fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters_in);
629 /* We did do a search as was requested, the flags are 631 /* We did do a search as was requested, the flags are
630 * now unset as well and has the flags wrt to search. 632 * now unset as well and has the flags wrt to search.
631 */ 633 */
@@ -636,11 +638,12 @@ restart:
636 /* Track the carrier if the search was successful */ 638 /* Track the carrier if the search was successful */
637 if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) { 639 if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
638 if (fe->ops.track) 640 if (fe->ops.track)
639 fe->ops.track(fe, &fepriv->parameters); 641 fe->ops.track(fe, &fepriv->parameters_in);
640 } else { 642 } else {
641 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; 643 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
642 fepriv->delay = HZ / 2; 644 fepriv->delay = HZ / 2;
643 } 645 }
646 fepriv->parameters_out = fepriv->parameters_in;
644 fe->ops.read_status(fe, &s); 647 fe->ops.read_status(fe, &s);
645 if (s != fepriv->status) { 648 if (s != fepriv->status) {
646 dvb_frontend_add_event(fe, s); /* update event list */ 649 dvb_frontend_add_event(fe, s); /* update event list */
@@ -860,34 +863,34 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
860 863
861static int dvb_frontend_clear_cache(struct dvb_frontend *fe) 864static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
862{ 865{
866 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
863 int i; 867 int i;
864 868
865 memset(&(fe->dtv_property_cache), 0, 869 memset(c, 0, sizeof(struct dtv_frontend_properties));
866 sizeof(struct dtv_frontend_properties)); 870
867 871 c->state = DTV_CLEAR;
868 fe->dtv_property_cache.state = DTV_CLEAR; 872 c->delivery_system = SYS_UNDEFINED;
869 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; 873 c->inversion = INVERSION_AUTO;
870 fe->dtv_property_cache.inversion = INVERSION_AUTO; 874 c->fec_inner = FEC_AUTO;
871 fe->dtv_property_cache.fec_inner = FEC_AUTO; 875 c->transmission_mode = TRANSMISSION_MODE_AUTO;
872 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO; 876 c->bandwidth_hz = BANDWIDTH_AUTO;
873 fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO; 877 c->guard_interval = GUARD_INTERVAL_AUTO;
874 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO; 878 c->hierarchy = HIERARCHY_AUTO;
875 fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO; 879 c->symbol_rate = QAM_AUTO;
876 fe->dtv_property_cache.symbol_rate = QAM_AUTO; 880 c->code_rate_HP = FEC_AUTO;
877 fe->dtv_property_cache.code_rate_HP = FEC_AUTO; 881 c->code_rate_LP = FEC_AUTO;
878 fe->dtv_property_cache.code_rate_LP = FEC_AUTO; 882
879 883 c->isdbt_partial_reception = -1;
880 fe->dtv_property_cache.isdbt_partial_reception = -1; 884 c->isdbt_sb_mode = -1;
881 fe->dtv_property_cache.isdbt_sb_mode = -1; 885 c->isdbt_sb_subchannel = -1;
882 fe->dtv_property_cache.isdbt_sb_subchannel = -1; 886 c->isdbt_sb_segment_idx = -1;
883 fe->dtv_property_cache.isdbt_sb_segment_idx = -1; 887 c->isdbt_sb_segment_count = -1;
884 fe->dtv_property_cache.isdbt_sb_segment_count = -1; 888 c->isdbt_layer_enabled = 0x7;
885 fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
886 for (i = 0; i < 3; i++) { 889 for (i = 0; i < 3; i++) {
887 fe->dtv_property_cache.layer[i].fec = FEC_AUTO; 890 c->layer[i].fec = FEC_AUTO;
888 fe->dtv_property_cache.layer[i].modulation = QAM_AUTO; 891 c->layer[i].modulation = QAM_AUTO;
889 fe->dtv_property_cache.layer[i].interleaving = -1; 892 c->layer[i].interleaving = -1;
890 fe->dtv_property_cache.layer[i].segment_count = -1; 893 c->layer[i].segment_count = -1;
891 } 894 }
892 895
893 return 0; 896 return 0;
@@ -1020,10 +1023,9 @@ static int is_legacy_delivery_system(fe_delivery_system_t s)
1020 * it's being used for the legacy or new API, reducing code and complexity. 1023 * it's being used for the legacy or new API, reducing code and complexity.
1021 */ 1024 */
1022static void dtv_property_cache_sync(struct dvb_frontend *fe, 1025static void dtv_property_cache_sync(struct dvb_frontend *fe,
1023 struct dvb_frontend_parameters *p) 1026 struct dtv_frontend_properties *c,
1027 const struct dvb_frontend_parameters *p)
1024{ 1028{
1025 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1026
1027 c->frequency = p->frequency; 1029 c->frequency = p->frequency;
1028 c->inversion = p->inversion; 1030 c->inversion = p->inversion;
1029 1031
@@ -1074,9 +1076,9 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe,
1074 */ 1076 */
1075static void dtv_property_legacy_params_sync(struct dvb_frontend *fe) 1077static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
1076{ 1078{
1077 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1079 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1078 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1080 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1079 struct dvb_frontend_parameters *p = &fepriv->parameters; 1081 struct dvb_frontend_parameters *p = &fepriv->parameters_in;
1080 1082
1081 p->frequency = c->frequency; 1083 p->frequency = c->frequency;
1082 p->inversion = c->inversion; 1084 p->inversion = c->inversion;
@@ -1086,14 +1088,12 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
1086 dprintk("%s() Preparing QPSK req\n", __func__); 1088 dprintk("%s() Preparing QPSK req\n", __func__);
1087 p->u.qpsk.symbol_rate = c->symbol_rate; 1089 p->u.qpsk.symbol_rate = c->symbol_rate;
1088 p->u.qpsk.fec_inner = c->fec_inner; 1090 p->u.qpsk.fec_inner = c->fec_inner;
1089 c->delivery_system = SYS_DVBS;
1090 break; 1091 break;
1091 case FE_QAM: 1092 case FE_QAM:
1092 dprintk("%s() Preparing QAM req\n", __func__); 1093 dprintk("%s() Preparing QAM req\n", __func__);
1093 p->u.qam.symbol_rate = c->symbol_rate; 1094 p->u.qam.symbol_rate = c->symbol_rate;
1094 p->u.qam.fec_inner = c->fec_inner; 1095 p->u.qam.fec_inner = c->fec_inner;
1095 p->u.qam.modulation = c->modulation; 1096 p->u.qam.modulation = c->modulation;
1096 c->delivery_system = SYS_DVBC_ANNEX_AC;
1097 break; 1097 break;
1098 case FE_OFDM: 1098 case FE_OFDM:
1099 dprintk("%s() Preparing OFDM req\n", __func__); 1099 dprintk("%s() Preparing OFDM req\n", __func__);
@@ -1111,15 +1111,10 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
1111 p->u.ofdm.transmission_mode = c->transmission_mode; 1111 p->u.ofdm.transmission_mode = c->transmission_mode;
1112 p->u.ofdm.guard_interval = c->guard_interval; 1112 p->u.ofdm.guard_interval = c->guard_interval;
1113 p->u.ofdm.hierarchy_information = c->hierarchy; 1113 p->u.ofdm.hierarchy_information = c->hierarchy;
1114 c->delivery_system = SYS_DVBT;
1115 break; 1114 break;
1116 case FE_ATSC: 1115 case FE_ATSC:
1117 dprintk("%s() Preparing VSB req\n", __func__); 1116 dprintk("%s() Preparing VSB req\n", __func__);
1118 p->u.vsb.modulation = c->modulation; 1117 p->u.vsb.modulation = c->modulation;
1119 if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
1120 c->delivery_system = SYS_ATSC;
1121 else
1122 c->delivery_system = SYS_DVBC_ANNEX_B;
1123 break; 1118 break;
1124 } 1119 }
1125} 1120}
@@ -1129,9 +1124,9 @@ static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
1129 */ 1124 */
1130static void dtv_property_adv_params_sync(struct dvb_frontend *fe) 1125static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1131{ 1126{
1132 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1127 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1133 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1128 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1134 struct dvb_frontend_parameters *p = &fepriv->parameters; 1129 struct dvb_frontend_parameters *p = &fepriv->parameters_in;
1135 1130
1136 p->frequency = c->frequency; 1131 p->frequency = c->frequency;
1137 p->inversion = c->inversion; 1132 p->inversion = c->inversion;
@@ -1148,10 +1143,9 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1148 break; 1143 break;
1149 } 1144 }
1150 1145
1151 if(c->delivery_system == SYS_ISDBT) { 1146 /* Fake out a generic DVB-T request so we pass validation in the ioctl */
1152 /* Fake out a generic DVB-T request so we pass validation in the ioctl */ 1147 if ((c->delivery_system == SYS_ISDBT) ||
1153 p->frequency = c->frequency; 1148 (c->delivery_system == SYS_DVBT2)) {
1154 p->inversion = c->inversion;
1155 p->u.ofdm.constellation = QAM_AUTO; 1149 p->u.ofdm.constellation = QAM_AUTO;
1156 p->u.ofdm.code_rate_HP = FEC_AUTO; 1150 p->u.ofdm.code_rate_HP = FEC_AUTO;
1157 p->u.ofdm.code_rate_LP = FEC_AUTO; 1151 p->u.ofdm.code_rate_LP = FEC_AUTO;
@@ -1171,7 +1165,7 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1171 1165
1172static void dtv_property_cache_submit(struct dvb_frontend *fe) 1166static void dtv_property_cache_submit(struct dvb_frontend *fe)
1173{ 1167{
1174 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1168 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1175 1169
1176 /* For legacy delivery systems we don't need the delivery_system to 1170 /* For legacy delivery systems we don't need the delivery_system to
1177 * be specified, but we populate the older structures from the cache 1171 * be specified, but we populate the older structures from the cache
@@ -1204,133 +1198,149 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1204 struct dtv_property *tvp, 1198 struct dtv_property *tvp,
1205 struct file *file) 1199 struct file *file)
1206{ 1200{
1207 int r = 0; 1201 const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1208 1202 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1209 /* Allow the frontend to validate incoming properties */ 1203 struct dtv_frontend_properties cdetected;
1210 if (fe->ops.get_property) 1204 int r;
1211 r = fe->ops.get_property(fe, tvp);
1212 1205
1213 if (r < 0) 1206 /*
1214 return r; 1207 * If the driver implements a get_frontend function, then convert
1208 * detected parameters to S2API properties.
1209 */
1210 if (fe->ops.get_frontend) {
1211 cdetected = *c;
1212 dtv_property_cache_sync(fe, &cdetected, &fepriv->parameters_out);
1213 c = &cdetected;
1214 }
1215 1215
1216 switch(tvp->cmd) { 1216 switch(tvp->cmd) {
1217 case DTV_FREQUENCY: 1217 case DTV_FREQUENCY:
1218 tvp->u.data = fe->dtv_property_cache.frequency; 1218 tvp->u.data = c->frequency;
1219 break; 1219 break;
1220 case DTV_MODULATION: 1220 case DTV_MODULATION:
1221 tvp->u.data = fe->dtv_property_cache.modulation; 1221 tvp->u.data = c->modulation;
1222 break; 1222 break;
1223 case DTV_BANDWIDTH_HZ: 1223 case DTV_BANDWIDTH_HZ:
1224 tvp->u.data = fe->dtv_property_cache.bandwidth_hz; 1224 tvp->u.data = c->bandwidth_hz;
1225 break; 1225 break;
1226 case DTV_INVERSION: 1226 case DTV_INVERSION:
1227 tvp->u.data = fe->dtv_property_cache.inversion; 1227 tvp->u.data = c->inversion;
1228 break; 1228 break;
1229 case DTV_SYMBOL_RATE: 1229 case DTV_SYMBOL_RATE:
1230 tvp->u.data = fe->dtv_property_cache.symbol_rate; 1230 tvp->u.data = c->symbol_rate;
1231 break; 1231 break;
1232 case DTV_INNER_FEC: 1232 case DTV_INNER_FEC:
1233 tvp->u.data = fe->dtv_property_cache.fec_inner; 1233 tvp->u.data = c->fec_inner;
1234 break; 1234 break;
1235 case DTV_PILOT: 1235 case DTV_PILOT:
1236 tvp->u.data = fe->dtv_property_cache.pilot; 1236 tvp->u.data = c->pilot;
1237 break; 1237 break;
1238 case DTV_ROLLOFF: 1238 case DTV_ROLLOFF:
1239 tvp->u.data = fe->dtv_property_cache.rolloff; 1239 tvp->u.data = c->rolloff;
1240 break; 1240 break;
1241 case DTV_DELIVERY_SYSTEM: 1241 case DTV_DELIVERY_SYSTEM:
1242 tvp->u.data = fe->dtv_property_cache.delivery_system; 1242 tvp->u.data = c->delivery_system;
1243 break; 1243 break;
1244 case DTV_VOLTAGE: 1244 case DTV_VOLTAGE:
1245 tvp->u.data = fe->dtv_property_cache.voltage; 1245 tvp->u.data = c->voltage;
1246 break; 1246 break;
1247 case DTV_TONE: 1247 case DTV_TONE:
1248 tvp->u.data = fe->dtv_property_cache.sectone; 1248 tvp->u.data = c->sectone;
1249 break; 1249 break;
1250 case DTV_API_VERSION: 1250 case DTV_API_VERSION:
1251 tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR; 1251 tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR;
1252 break; 1252 break;
1253 case DTV_CODE_RATE_HP: 1253 case DTV_CODE_RATE_HP:
1254 tvp->u.data = fe->dtv_property_cache.code_rate_HP; 1254 tvp->u.data = c->code_rate_HP;
1255 break; 1255 break;
1256 case DTV_CODE_RATE_LP: 1256 case DTV_CODE_RATE_LP:
1257 tvp->u.data = fe->dtv_property_cache.code_rate_LP; 1257 tvp->u.data = c->code_rate_LP;
1258 break; 1258 break;
1259 case DTV_GUARD_INTERVAL: 1259 case DTV_GUARD_INTERVAL:
1260 tvp->u.data = fe->dtv_property_cache.guard_interval; 1260 tvp->u.data = c->guard_interval;
1261 break; 1261 break;
1262 case DTV_TRANSMISSION_MODE: 1262 case DTV_TRANSMISSION_MODE:
1263 tvp->u.data = fe->dtv_property_cache.transmission_mode; 1263 tvp->u.data = c->transmission_mode;
1264 break; 1264 break;
1265 case DTV_HIERARCHY: 1265 case DTV_HIERARCHY:
1266 tvp->u.data = fe->dtv_property_cache.hierarchy; 1266 tvp->u.data = c->hierarchy;
1267 break; 1267 break;
1268 1268
1269 /* ISDB-T Support here */ 1269 /* ISDB-T Support here */
1270 case DTV_ISDBT_PARTIAL_RECEPTION: 1270 case DTV_ISDBT_PARTIAL_RECEPTION:
1271 tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception; 1271 tvp->u.data = c->isdbt_partial_reception;
1272 break; 1272 break;
1273 case DTV_ISDBT_SOUND_BROADCASTING: 1273 case DTV_ISDBT_SOUND_BROADCASTING:
1274 tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode; 1274 tvp->u.data = c->isdbt_sb_mode;
1275 break; 1275 break;
1276 case DTV_ISDBT_SB_SUBCHANNEL_ID: 1276 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1277 tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel; 1277 tvp->u.data = c->isdbt_sb_subchannel;
1278 break; 1278 break;
1279 case DTV_ISDBT_SB_SEGMENT_IDX: 1279 case DTV_ISDBT_SB_SEGMENT_IDX:
1280 tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx; 1280 tvp->u.data = c->isdbt_sb_segment_idx;
1281 break; 1281 break;
1282 case DTV_ISDBT_SB_SEGMENT_COUNT: 1282 case DTV_ISDBT_SB_SEGMENT_COUNT:
1283 tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count; 1283 tvp->u.data = c->isdbt_sb_segment_count;
1284 break; 1284 break;
1285 case DTV_ISDBT_LAYER_ENABLED: 1285 case DTV_ISDBT_LAYER_ENABLED:
1286 tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled; 1286 tvp->u.data = c->isdbt_layer_enabled;
1287 break; 1287 break;
1288 case DTV_ISDBT_LAYERA_FEC: 1288 case DTV_ISDBT_LAYERA_FEC:
1289 tvp->u.data = fe->dtv_property_cache.layer[0].fec; 1289 tvp->u.data = c->layer[0].fec;
1290 break; 1290 break;
1291 case DTV_ISDBT_LAYERA_MODULATION: 1291 case DTV_ISDBT_LAYERA_MODULATION:
1292 tvp->u.data = fe->dtv_property_cache.layer[0].modulation; 1292 tvp->u.data = c->layer[0].modulation;
1293 break; 1293 break;
1294 case DTV_ISDBT_LAYERA_SEGMENT_COUNT: 1294 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1295 tvp->u.data = fe->dtv_property_cache.layer[0].segment_count; 1295 tvp->u.data = c->layer[0].segment_count;
1296 break; 1296 break;
1297 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: 1297 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1298 tvp->u.data = fe->dtv_property_cache.layer[0].interleaving; 1298 tvp->u.data = c->layer[0].interleaving;
1299 break; 1299 break;
1300 case DTV_ISDBT_LAYERB_FEC: 1300 case DTV_ISDBT_LAYERB_FEC:
1301 tvp->u.data = fe->dtv_property_cache.layer[1].fec; 1301 tvp->u.data = c->layer[1].fec;
1302 break; 1302 break;
1303 case DTV_ISDBT_LAYERB_MODULATION: 1303 case DTV_ISDBT_LAYERB_MODULATION:
1304 tvp->u.data = fe->dtv_property_cache.layer[1].modulation; 1304 tvp->u.data = c->layer[1].modulation;
1305 break; 1305 break;
1306 case DTV_ISDBT_LAYERB_SEGMENT_COUNT: 1306 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1307 tvp->u.data = fe->dtv_property_cache.layer[1].segment_count; 1307 tvp->u.data = c->layer[1].segment_count;
1308 break; 1308 break;
1309 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: 1309 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1310 tvp->u.data = fe->dtv_property_cache.layer[1].interleaving; 1310 tvp->u.data = c->layer[1].interleaving;
1311 break; 1311 break;
1312 case DTV_ISDBT_LAYERC_FEC: 1312 case DTV_ISDBT_LAYERC_FEC:
1313 tvp->u.data = fe->dtv_property_cache.layer[2].fec; 1313 tvp->u.data = c->layer[2].fec;
1314 break; 1314 break;
1315 case DTV_ISDBT_LAYERC_MODULATION: 1315 case DTV_ISDBT_LAYERC_MODULATION:
1316 tvp->u.data = fe->dtv_property_cache.layer[2].modulation; 1316 tvp->u.data = c->layer[2].modulation;
1317 break; 1317 break;
1318 case DTV_ISDBT_LAYERC_SEGMENT_COUNT: 1318 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1319 tvp->u.data = fe->dtv_property_cache.layer[2].segment_count; 1319 tvp->u.data = c->layer[2].segment_count;
1320 break; 1320 break;
1321 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: 1321 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1322 tvp->u.data = fe->dtv_property_cache.layer[2].interleaving; 1322 tvp->u.data = c->layer[2].interleaving;
1323 break; 1323 break;
1324 case DTV_ISDBS_TS_ID: 1324 case DTV_ISDBS_TS_ID:
1325 tvp->u.data = fe->dtv_property_cache.isdbs_ts_id; 1325 tvp->u.data = c->isdbs_ts_id;
1326 break;
1327 case DTV_DVBT2_PLP_ID:
1328 tvp->u.data = c->dvbt2_plp_id;
1326 break; 1329 break;
1327 default: 1330 default:
1328 r = -1; 1331 return -EINVAL;
1332 }
1333
1334 /* Allow the frontend to override outgoing properties */
1335 if (fe->ops.get_property) {
1336 r = fe->ops.get_property(fe, tvp);
1337 if (r < 0)
1338 return r;
1329 } 1339 }
1330 1340
1331 dtv_property_dump(tvp); 1341 dtv_property_dump(tvp);
1332 1342
1333 return r; 1343 return 0;
1334} 1344}
1335 1345
1336static int dtv_property_process_set(struct dvb_frontend *fe, 1346static int dtv_property_process_set(struct dvb_frontend *fe,
@@ -1338,15 +1348,16 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1338 struct file *file) 1348 struct file *file)
1339{ 1349{
1340 int r = 0; 1350 int r = 0;
1351 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1341 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1352 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1342 dtv_property_dump(tvp); 1353 dtv_property_dump(tvp);
1343 1354
1344 /* Allow the frontend to validate incoming properties */ 1355 /* Allow the frontend to validate incoming properties */
1345 if (fe->ops.set_property) 1356 if (fe->ops.set_property) {
1346 r = fe->ops.set_property(fe, tvp); 1357 r = fe->ops.set_property(fe, tvp);
1347 1358 if (r < 0)
1348 if (r < 0) 1359 return r;
1349 return r; 1360 }
1350 1361
1351 switch(tvp->cmd) { 1362 switch(tvp->cmd) {
1352 case DTV_CLEAR: 1363 case DTV_CLEAR:
@@ -1361,126 +1372,129 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1361 * tunerequest so we can pass validation in the FE_SET_FRONTEND 1372 * tunerequest so we can pass validation in the FE_SET_FRONTEND
1362 * ioctl. 1373 * ioctl.
1363 */ 1374 */
1364 fe->dtv_property_cache.state = tvp->cmd; 1375 c->state = tvp->cmd;
1365 dprintk("%s() Finalised property cache\n", __func__); 1376 dprintk("%s() Finalised property cache\n", __func__);
1366 dtv_property_cache_submit(fe); 1377 dtv_property_cache_submit(fe);
1367 1378
1368 r |= dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND, 1379 r = dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND,
1369 &fepriv->parameters); 1380 &fepriv->parameters_in);
1370 break; 1381 break;
1371 case DTV_FREQUENCY: 1382 case DTV_FREQUENCY:
1372 fe->dtv_property_cache.frequency = tvp->u.data; 1383 c->frequency = tvp->u.data;
1373 break; 1384 break;
1374 case DTV_MODULATION: 1385 case DTV_MODULATION:
1375 fe->dtv_property_cache.modulation = tvp->u.data; 1386 c->modulation = tvp->u.data;
1376 break; 1387 break;
1377 case DTV_BANDWIDTH_HZ: 1388 case DTV_BANDWIDTH_HZ:
1378 fe->dtv_property_cache.bandwidth_hz = tvp->u.data; 1389 c->bandwidth_hz = tvp->u.data;
1379 break; 1390 break;
1380 case DTV_INVERSION: 1391 case DTV_INVERSION:
1381 fe->dtv_property_cache.inversion = tvp->u.data; 1392 c->inversion = tvp->u.data;
1382 break; 1393 break;
1383 case DTV_SYMBOL_RATE: 1394 case DTV_SYMBOL_RATE:
1384 fe->dtv_property_cache.symbol_rate = tvp->u.data; 1395 c->symbol_rate = tvp->u.data;
1385 break; 1396 break;
1386 case DTV_INNER_FEC: 1397 case DTV_INNER_FEC:
1387 fe->dtv_property_cache.fec_inner = tvp->u.data; 1398 c->fec_inner = tvp->u.data;
1388 break; 1399 break;
1389 case DTV_PILOT: 1400 case DTV_PILOT:
1390 fe->dtv_property_cache.pilot = tvp->u.data; 1401 c->pilot = tvp->u.data;
1391 break; 1402 break;
1392 case DTV_ROLLOFF: 1403 case DTV_ROLLOFF:
1393 fe->dtv_property_cache.rolloff = tvp->u.data; 1404 c->rolloff = tvp->u.data;
1394 break; 1405 break;
1395 case DTV_DELIVERY_SYSTEM: 1406 case DTV_DELIVERY_SYSTEM:
1396 fe->dtv_property_cache.delivery_system = tvp->u.data; 1407 c->delivery_system = tvp->u.data;
1397 break; 1408 break;
1398 case DTV_VOLTAGE: 1409 case DTV_VOLTAGE:
1399 fe->dtv_property_cache.voltage = tvp->u.data; 1410 c->voltage = tvp->u.data;
1400 r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE, 1411 r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE,
1401 (void *)fe->dtv_property_cache.voltage); 1412 (void *)c->voltage);
1402 break; 1413 break;
1403 case DTV_TONE: 1414 case DTV_TONE:
1404 fe->dtv_property_cache.sectone = tvp->u.data; 1415 c->sectone = tvp->u.data;
1405 r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE, 1416 r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE,
1406 (void *)fe->dtv_property_cache.sectone); 1417 (void *)c->sectone);
1407 break; 1418 break;
1408 case DTV_CODE_RATE_HP: 1419 case DTV_CODE_RATE_HP:
1409 fe->dtv_property_cache.code_rate_HP = tvp->u.data; 1420 c->code_rate_HP = tvp->u.data;
1410 break; 1421 break;
1411 case DTV_CODE_RATE_LP: 1422 case DTV_CODE_RATE_LP:
1412 fe->dtv_property_cache.code_rate_LP = tvp->u.data; 1423 c->code_rate_LP = tvp->u.data;
1413 break; 1424 break;
1414 case DTV_GUARD_INTERVAL: 1425 case DTV_GUARD_INTERVAL:
1415 fe->dtv_property_cache.guard_interval = tvp->u.data; 1426 c->guard_interval = tvp->u.data;
1416 break; 1427 break;
1417 case DTV_TRANSMISSION_MODE: 1428 case DTV_TRANSMISSION_MODE:
1418 fe->dtv_property_cache.transmission_mode = tvp->u.data; 1429 c->transmission_mode = tvp->u.data;
1419 break; 1430 break;
1420 case DTV_HIERARCHY: 1431 case DTV_HIERARCHY:
1421 fe->dtv_property_cache.hierarchy = tvp->u.data; 1432 c->hierarchy = tvp->u.data;
1422 break; 1433 break;
1423 1434
1424 /* ISDB-T Support here */ 1435 /* ISDB-T Support here */
1425 case DTV_ISDBT_PARTIAL_RECEPTION: 1436 case DTV_ISDBT_PARTIAL_RECEPTION:
1426 fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data; 1437 c->isdbt_partial_reception = tvp->u.data;
1427 break; 1438 break;
1428 case DTV_ISDBT_SOUND_BROADCASTING: 1439 case DTV_ISDBT_SOUND_BROADCASTING:
1429 fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data; 1440 c->isdbt_sb_mode = tvp->u.data;
1430 break; 1441 break;
1431 case DTV_ISDBT_SB_SUBCHANNEL_ID: 1442 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1432 fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data; 1443 c->isdbt_sb_subchannel = tvp->u.data;
1433 break; 1444 break;
1434 case DTV_ISDBT_SB_SEGMENT_IDX: 1445 case DTV_ISDBT_SB_SEGMENT_IDX:
1435 fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data; 1446 c->isdbt_sb_segment_idx = tvp->u.data;
1436 break; 1447 break;
1437 case DTV_ISDBT_SB_SEGMENT_COUNT: 1448 case DTV_ISDBT_SB_SEGMENT_COUNT:
1438 fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data; 1449 c->isdbt_sb_segment_count = tvp->u.data;
1439 break; 1450 break;
1440 case DTV_ISDBT_LAYER_ENABLED: 1451 case DTV_ISDBT_LAYER_ENABLED:
1441 fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data; 1452 c->isdbt_layer_enabled = tvp->u.data;
1442 break; 1453 break;
1443 case DTV_ISDBT_LAYERA_FEC: 1454 case DTV_ISDBT_LAYERA_FEC:
1444 fe->dtv_property_cache.layer[0].fec = tvp->u.data; 1455 c->layer[0].fec = tvp->u.data;
1445 break; 1456 break;
1446 case DTV_ISDBT_LAYERA_MODULATION: 1457 case DTV_ISDBT_LAYERA_MODULATION:
1447 fe->dtv_property_cache.layer[0].modulation = tvp->u.data; 1458 c->layer[0].modulation = tvp->u.data;
1448 break; 1459 break;
1449 case DTV_ISDBT_LAYERA_SEGMENT_COUNT: 1460 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1450 fe->dtv_property_cache.layer[0].segment_count = tvp->u.data; 1461 c->layer[0].segment_count = tvp->u.data;
1451 break; 1462 break;
1452 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: 1463 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1453 fe->dtv_property_cache.layer[0].interleaving = tvp->u.data; 1464 c->layer[0].interleaving = tvp->u.data;
1454 break; 1465 break;
1455 case DTV_ISDBT_LAYERB_FEC: 1466 case DTV_ISDBT_LAYERB_FEC:
1456 fe->dtv_property_cache.layer[1].fec = tvp->u.data; 1467 c->layer[1].fec = tvp->u.data;
1457 break; 1468 break;
1458 case DTV_ISDBT_LAYERB_MODULATION: 1469 case DTV_ISDBT_LAYERB_MODULATION:
1459 fe->dtv_property_cache.layer[1].modulation = tvp->u.data; 1470 c->layer[1].modulation = tvp->u.data;
1460 break; 1471 break;
1461 case DTV_ISDBT_LAYERB_SEGMENT_COUNT: 1472 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1462 fe->dtv_property_cache.layer[1].segment_count = tvp->u.data; 1473 c->layer[1].segment_count = tvp->u.data;
1463 break; 1474 break;
1464 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: 1475 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1465 fe->dtv_property_cache.layer[1].interleaving = tvp->u.data; 1476 c->layer[1].interleaving = tvp->u.data;
1466 break; 1477 break;
1467 case DTV_ISDBT_LAYERC_FEC: 1478 case DTV_ISDBT_LAYERC_FEC:
1468 fe->dtv_property_cache.layer[2].fec = tvp->u.data; 1479 c->layer[2].fec = tvp->u.data;
1469 break; 1480 break;
1470 case DTV_ISDBT_LAYERC_MODULATION: 1481 case DTV_ISDBT_LAYERC_MODULATION:
1471 fe->dtv_property_cache.layer[2].modulation = tvp->u.data; 1482 c->layer[2].modulation = tvp->u.data;
1472 break; 1483 break;
1473 case DTV_ISDBT_LAYERC_SEGMENT_COUNT: 1484 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1474 fe->dtv_property_cache.layer[2].segment_count = tvp->u.data; 1485 c->layer[2].segment_count = tvp->u.data;
1475 break; 1486 break;
1476 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: 1487 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1477 fe->dtv_property_cache.layer[2].interleaving = tvp->u.data; 1488 c->layer[2].interleaving = tvp->u.data;
1478 break; 1489 break;
1479 case DTV_ISDBS_TS_ID: 1490 case DTV_ISDBS_TS_ID:
1480 fe->dtv_property_cache.isdbs_ts_id = tvp->u.data; 1491 c->isdbs_ts_id = tvp->u.data;
1492 break;
1493 case DTV_DVBT2_PLP_ID:
1494 c->dvbt2_plp_id = tvp->u.data;
1481 break; 1495 break;
1482 default: 1496 default:
1483 r = -1; 1497 return -EINVAL;
1484 } 1498 }
1485 1499
1486 return r; 1500 return r;
@@ -1491,6 +1505,7 @@ static int dvb_frontend_ioctl(struct file *file,
1491{ 1505{
1492 struct dvb_device *dvbdev = file->private_data; 1506 struct dvb_device *dvbdev = file->private_data;
1493 struct dvb_frontend *fe = dvbdev->priv; 1507 struct dvb_frontend *fe = dvbdev->priv;
1508 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1494 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1509 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1495 int err = -EOPNOTSUPP; 1510 int err = -EOPNOTSUPP;
1496 1511
@@ -1510,7 +1525,7 @@ static int dvb_frontend_ioctl(struct file *file,
1510 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) 1525 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1511 err = dvb_frontend_ioctl_properties(file, cmd, parg); 1526 err = dvb_frontend_ioctl_properties(file, cmd, parg);
1512 else { 1527 else {
1513 fe->dtv_property_cache.state = DTV_UNDEFINED; 1528 c->state = DTV_UNDEFINED;
1514 err = dvb_frontend_ioctl_legacy(file, cmd, parg); 1529 err = dvb_frontend_ioctl_legacy(file, cmd, parg);
1515 } 1530 }
1516 1531
@@ -1523,6 +1538,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
1523{ 1538{
1524 struct dvb_device *dvbdev = file->private_data; 1539 struct dvb_device *dvbdev = file->private_data;
1525 struct dvb_frontend *fe = dvbdev->priv; 1540 struct dvb_frontend *fe = dvbdev->priv;
1541 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1526 int err = 0; 1542 int err = 0;
1527 1543
1528 struct dtv_properties *tvps = NULL; 1544 struct dtv_properties *tvps = NULL;
@@ -1554,11 +1570,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
1554 } 1570 }
1555 1571
1556 for (i = 0; i < tvps->num; i++) { 1572 for (i = 0; i < tvps->num; i++) {
1557 (tvp + i)->result = dtv_property_process_set(fe, tvp + i, file); 1573 err = dtv_property_process_set(fe, tvp + i, file);
1558 err |= (tvp + i)->result; 1574 if (err < 0)
1575 goto out;
1576 (tvp + i)->result = err;
1559 } 1577 }
1560 1578
1561 if(fe->dtv_property_cache.state == DTV_TUNE) 1579 if (c->state == DTV_TUNE)
1562 dprintk("%s() Property cache is full, tuning\n", __func__); 1580 dprintk("%s() Property cache is full, tuning\n", __func__);
1563 1581
1564 } else 1582 } else
@@ -1586,8 +1604,10 @@ static int dvb_frontend_ioctl_properties(struct file *file,
1586 } 1604 }
1587 1605
1588 for (i = 0; i < tvps->num; i++) { 1606 for (i = 0; i < tvps->num; i++) {
1589 (tvp + i)->result = dtv_property_process_get(fe, tvp + i, file); 1607 err = dtv_property_process_get(fe, tvp + i, file);
1590 err |= (tvp + i)->result; 1608 if (err < 0)
1609 goto out;
1610 (tvp + i)->result = err;
1591 } 1611 }
1592 1612
1593 if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) { 1613 if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
@@ -1787,10 +1807,11 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1787 break; 1807 break;
1788 1808
1789 case FE_SET_FRONTEND: { 1809 case FE_SET_FRONTEND: {
1810 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1790 struct dvb_frontend_tune_settings fetunesettings; 1811 struct dvb_frontend_tune_settings fetunesettings;
1791 1812
1792 if(fe->dtv_property_cache.state == DTV_TUNE) { 1813 if (c->state == DTV_TUNE) {
1793 if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { 1814 if (dvb_frontend_check_parameters(fe, &fepriv->parameters_in) < 0) {
1794 err = -EINVAL; 1815 err = -EINVAL;
1795 break; 1816 break;
1796 } 1817 }
@@ -1800,9 +1821,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1800 break; 1821 break;
1801 } 1822 }
1802 1823
1803 memcpy (&fepriv->parameters, parg, 1824 memcpy (&fepriv->parameters_in, parg,
1804 sizeof (struct dvb_frontend_parameters)); 1825 sizeof (struct dvb_frontend_parameters));
1805 dtv_property_cache_sync(fe, &fepriv->parameters); 1826 dtv_property_cache_sync(fe, c, &fepriv->parameters_in);
1806 } 1827 }
1807 1828
1808 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); 1829 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
@@ -1811,15 +1832,15 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1811 1832
1812 /* force auto frequency inversion if requested */ 1833 /* force auto frequency inversion if requested */
1813 if (dvb_force_auto_inversion) { 1834 if (dvb_force_auto_inversion) {
1814 fepriv->parameters.inversion = INVERSION_AUTO; 1835 fepriv->parameters_in.inversion = INVERSION_AUTO;
1815 fetunesettings.parameters.inversion = INVERSION_AUTO; 1836 fetunesettings.parameters.inversion = INVERSION_AUTO;
1816 } 1837 }
1817 if (fe->ops.info.type == FE_OFDM) { 1838 if (fe->ops.info.type == FE_OFDM) {
1818 /* without hierarchical coding code_rate_LP is irrelevant, 1839 /* without hierarchical coding code_rate_LP is irrelevant,
1819 * so we tolerate the otherwise invalid FEC_NONE setting */ 1840 * so we tolerate the otherwise invalid FEC_NONE setting */
1820 if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && 1841 if (fepriv->parameters_in.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
1821 fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE) 1842 fepriv->parameters_in.u.ofdm.code_rate_LP == FEC_NONE)
1822 fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO; 1843 fepriv->parameters_in.u.ofdm.code_rate_LP = FEC_AUTO;
1823 } 1844 }
1824 1845
1825 /* get frontend-specific tuning settings */ 1846 /* get frontend-specific tuning settings */
@@ -1832,8 +1853,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1832 switch(fe->ops.info.type) { 1853 switch(fe->ops.info.type) {
1833 case FE_QPSK: 1854 case FE_QPSK:
1834 fepriv->min_delay = HZ/20; 1855 fepriv->min_delay = HZ/20;
1835 fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; 1856 fepriv->step_size = fepriv->parameters_in.u.qpsk.symbol_rate / 16000;
1836 fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000; 1857 fepriv->max_drift = fepriv->parameters_in.u.qpsk.symbol_rate / 2000;
1837 break; 1858 break;
1838 1859
1839 case FE_QAM: 1860 case FE_QAM:
@@ -1875,8 +1896,8 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
1875 1896
1876 case FE_GET_FRONTEND: 1897 case FE_GET_FRONTEND:
1877 if (fe->ops.get_frontend) { 1898 if (fe->ops.get_frontend) {
1878 memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); 1899 err = fe->ops.get_frontend(fe, &fepriv->parameters_out);
1879 err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); 1900 memcpy(parg, &fepriv->parameters_out, sizeof(struct dvb_frontend_parameters));
1880 } 1901 }
1881 break; 1902 break;
1882 1903
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 3b860504bf04..5590eb6eb408 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -358,6 +358,9 @@ struct dtv_frontend_properties {
358 358
359 /* ISDB-T specifics */ 359 /* ISDB-T specifics */
360 u32 isdbs_ts_id; 360 u32 isdbs_ts_id;
361
362 /* DVB-T2 specifics */
363 u32 dvbt2_plp_id;
361}; 364};
362 365
363struct dvb_frontend { 366struct dvb_frontend {
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index c545039287ad..e85304c59a2b 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -292,6 +292,11 @@ config DVB_USB_ANYSEE
292 select DVB_MT352 if !DVB_FE_CUSTOMISE 292 select DVB_MT352 if !DVB_FE_CUSTOMISE
293 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 293 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
294 select DVB_TDA10023 if !DVB_FE_CUSTOMISE 294 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
295 select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
296 select DVB_CX24116 if !DVB_FE_CUSTOMISE
297 select DVB_STV0900 if !DVB_FE_CUSTOMISE
298 select DVB_STV6110 if !DVB_FE_CUSTOMISE
299 select DVB_ISL6423 if !DVB_FE_CUSTOMISE
295 help 300 help
296 Say Y here to support the Anysee E30, Anysee E30 Plus or 301 Say Y here to support the Anysee E30, Anysee E30 Plus or
297 Anysee E30 C Plus DVB USB2.0 receiver. 302 Anysee E30 C Plus DVB USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index f8e9bf116f21..b95a95e17840 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -78,17 +78,26 @@ static struct rc_map_table rc_map_a800_table[] = {
78 78
79static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 79static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
80{ 80{
81 u8 key[5]; 81 int ret;
82 u8 *key = kmalloc(5, GFP_KERNEL);
83 if (!key)
84 return -ENOMEM;
85
82 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0), 86 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
83 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5, 87 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
84 2000) != 5) 88 2000) != 5) {
85 return -ENODEV; 89 ret = -ENODEV;
90 goto out;
91 }
86 92
87 /* call the universal NEC remote processor, to find out the key's state and event */ 93 /* call the universal NEC remote processor, to find out the key's state and event */
88 dvb_usb_nec_rc_key_to_event(d,key,event,state); 94 dvb_usb_nec_rc_key_to_event(d,key,event,state);
89 if (key[0] != 0) 95 if (key[0] != 0)
90 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); 96 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
91 return 0; 97 ret = 0;
98out:
99 kfree(key);
100 return ret;
92} 101}
93 102
94/* USB Driver stuff */ 103/* USB Driver stuff */
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 6b402e943539..4dc1ca333236 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -36,6 +36,11 @@
36#include "mt352.h" 36#include "mt352.h"
37#include "mt352_priv.h" 37#include "mt352_priv.h"
38#include "zl10353.h" 38#include "zl10353.h"
39#include "tda18212.h"
40#include "cx24116.h"
41#include "stv0900.h"
42#include "stv6110.h"
43#include "isl6423.h"
39 44
40/* debug */ 45/* debug */
41static int dvb_usb_anysee_debug; 46static int dvb_usb_anysee_debug;
@@ -105,6 +110,27 @@ static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
105 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); 110 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
106} 111}
107 112
113/* write single register with mask */
114static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
115 u8 mask)
116{
117 int ret;
118 u8 tmp;
119
120 /* no need for read if whole reg is written */
121 if (mask != 0xff) {
122 ret = anysee_read_reg(d, reg, &tmp);
123 if (ret)
124 return ret;
125
126 val &= mask;
127 tmp &= ~mask;
128 val |= tmp;
129 }
130
131 return anysee_write_reg(d, reg, val);
132}
133
108static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) 134static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
109{ 135{
110 u8 buf[] = {CMD_GET_HW_INFO}; 136 u8 buf[] = {CMD_GET_HW_INFO};
@@ -162,18 +188,18 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
162 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { 188 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
163 u8 buf[6]; 189 u8 buf[6];
164 buf[0] = CMD_I2C_READ; 190 buf[0] = CMD_I2C_READ;
165 buf[1] = msg[i].addr + 1; 191 buf[1] = (msg[i].addr << 1) | 0x01;
166 buf[2] = msg[i].buf[0]; 192 buf[2] = msg[i].buf[0];
167 buf[3] = 0x00; 193 buf[3] = msg[i].buf[1];
168 buf[4] = 0x00; 194 buf[4] = msg[i].len-1;
169 buf[5] = 0x01; 195 buf[5] = msg[i+1].len;
170 ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf, 196 ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
171 msg[i+1].len); 197 msg[i+1].len);
172 inc = 2; 198 inc = 2;
173 } else { 199 } else {
174 u8 buf[4+msg[i].len]; 200 u8 buf[4+msg[i].len];
175 buf[0] = CMD_I2C_WRITE; 201 buf[0] = CMD_I2C_WRITE;
176 buf[1] = msg[i].addr; 202 buf[1] = (msg[i].addr << 1);
177 buf[2] = msg[i].len; 203 buf[2] = msg[i].len;
178 buf[3] = 0x01; 204 buf[3] = 0x01;
179 memcpy(&buf[4], msg[i].buf, msg[i].len); 205 memcpy(&buf[4], msg[i].buf, msg[i].len);
@@ -224,7 +250,7 @@ static int anysee_mt352_demod_init(struct dvb_frontend *fe)
224 250
225/* Callbacks for DVB USB */ 251/* Callbacks for DVB USB */
226static struct tda10023_config anysee_tda10023_config = { 252static struct tda10023_config anysee_tda10023_config = {
227 .demod_address = 0x1a, 253 .demod_address = (0x1a >> 1),
228 .invert = 0, 254 .invert = 0,
229 .xtal = 16000000, 255 .xtal = 16000000,
230 .pll_m = 11, 256 .pll_m = 11,
@@ -235,143 +261,539 @@ static struct tda10023_config anysee_tda10023_config = {
235}; 261};
236 262
237static struct mt352_config anysee_mt352_config = { 263static struct mt352_config anysee_mt352_config = {
238 .demod_address = 0x1e, 264 .demod_address = (0x1e >> 1),
239 .demod_init = anysee_mt352_demod_init, 265 .demod_init = anysee_mt352_demod_init,
240}; 266};
241 267
242static struct zl10353_config anysee_zl10353_config = { 268static struct zl10353_config anysee_zl10353_config = {
243 .demod_address = 0x1e, 269 .demod_address = (0x1e >> 1),
244 .parallel_ts = 1, 270 .parallel_ts = 1,
245}; 271};
246 272
273static struct zl10353_config anysee_zl10353_tda18212_config2 = {
274 .demod_address = (0x1e >> 1),
275 .parallel_ts = 1,
276 .disable_i2c_gate_ctrl = 1,
277 .no_tuner = 1,
278 .if2 = 41500,
279};
280
281static struct zl10353_config anysee_zl10353_tda18212_config = {
282 .demod_address = (0x18 >> 1),
283 .parallel_ts = 1,
284 .disable_i2c_gate_ctrl = 1,
285 .no_tuner = 1,
286 .if2 = 41500,
287};
288
289static struct tda10023_config anysee_tda10023_tda18212_config = {
290 .demod_address = (0x1a >> 1),
291 .xtal = 16000000,
292 .pll_m = 12,
293 .pll_p = 3,
294 .pll_n = 1,
295 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
296 .deltaf = 0xba02,
297};
298
299static struct tda18212_config anysee_tda18212_config = {
300 .i2c_address = (0xc0 >> 1),
301 .if_dvbt_6 = 4150,
302 .if_dvbt_7 = 4150,
303 .if_dvbt_8 = 4150,
304 .if_dvbc = 5000,
305};
306
307static struct cx24116_config anysee_cx24116_config = {
308 .demod_address = (0xaa >> 1),
309 .mpg_clk_pos_pol = 0x00,
310 .i2c_wr_max = 48,
311};
312
313static struct stv0900_config anysee_stv0900_config = {
314 .demod_address = (0xd0 >> 1),
315 .demod_mode = 0,
316 .xtal = 8000000,
317 .clkmode = 3,
318 .diseqc_mode = 2,
319 .tun1_maddress = 0,
320 .tun1_adc = 1, /* 1 Vpp */
321 .path1_mode = 3,
322};
323
324static struct stv6110_config anysee_stv6110_config = {
325 .i2c_address = (0xc0 >> 1),
326 .mclk = 16000000,
327 .clk_div = 1,
328};
329
330static struct isl6423_config anysee_isl6423_config = {
331 .current_max = SEC_CURRENT_800m,
332 .curlim = SEC_CURRENT_LIM_OFF,
333 .mod_extern = 1,
334 .addr = (0x10 >> 1),
335};
336
337/*
338 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
339 * Manufacturer: AMT.CO.KR
340 *
341 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
342 * PCB: ?
343 * parts: DNOS404ZH102A(MT352, DTT7579(?))
344 *
345 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
346 * PCB: ?
347 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
348 *
349 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
350 * PCB: 507CD (rev1.1)
351 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
352 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
353 * IOA=4f IOB=ff IOC=00 IOD=06 IOF=01
354 * IOD[0] ZL10353 1=enabled
355 * IOA[7] TS 0=enabled
356 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
357 *
358 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
359 * PCB: 507DC (rev0.2)
360 * parts: TDA10023, DTOS403IH102B TM, CST56I01
361 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
362 * IOA=4f IOB=ff IOC=00 IOD=26 IOF=01
363 * IOD[0] TDA10023 1=enabled
364 *
365 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
366 * PCB: 507SI (rev2.1)
367 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
368 * OEA=80 OEB=00 OEC=ff OED=ff OEF=fe
369 * IOA=4d IOB=ff IOC=00 IOD=26 IOF=01
370 * IOD[0] CX24116 1=enabled
371 *
372 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
373 * PCB: 507FA (rev0.4)
374 * parts: TDA10023, DTOS403IH102B TM, TDA8024
375 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
376 * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0
377 * IOD[5] TDA10023 1=enabled
378 * IOE[0] tuner 1=enabled
379 *
380 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
381 * PCB: 507FA (rev1.1)
382 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
383 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
384 * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0
385 * DVB-C:
386 * IOD[5] TDA10023 1=enabled
387 * IOE[0] tuner 1=enabled
388 * DVB-T:
389 * IOD[0] ZL10353 1=enabled
390 * IOE[0] tuner 0=enabled
391 * tuner is behind ZL10353 I2C-gate
392 *
393 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
394 * PCB: 508TC (rev0.6)
395 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
396 * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff
397 * IOA=4d IOB=00 IOC=cc IOD=48 IOF=e4
398 * IOA[7] TS 1=enabled
399 * IOE[4] TDA18212 1=enabled
400 * DVB-C:
401 * IOD[6] ZL10353 0=disabled
402 * IOD[5] TDA10023 1=enabled
403 * IOE[0] IF 1=enabled
404 * DVB-T:
405 * IOD[5] TDA10023 0=disabled
406 * IOD[6] ZL10353 1=enabled
407 * IOE[0] IF 0=enabled
408 *
409 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
410 * PCB: 508S2 (rev0.7)
411 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
412 * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff
413 * IOA=4d IOB=00 IOC=c4 IOD=08 IOF=e4
414 * IOA[7] TS 1=enabled
415 * IOE[5] STV0903 1=enabled
416 *
417 */
418
247static int anysee_frontend_attach(struct dvb_usb_adapter *adap) 419static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
248{ 420{
249 int ret; 421 int ret;
250 struct anysee_state *state = adap->dev->priv; 422 struct anysee_state *state = adap->dev->priv;
251 u8 hw_info[3]; 423 u8 hw_info[3];
252 u8 io_d; /* IO port D */ 424 u8 tmp;
425 struct i2c_msg msg[2] = {
426 {
427 .addr = anysee_tda18212_config.i2c_address,
428 .flags = 0,
429 .len = 1,
430 .buf = "\x00",
431 }, {
432 .addr = anysee_tda18212_config.i2c_address,
433 .flags = I2C_M_RD,
434 .len = 1,
435 .buf = &tmp,
436 }
437 };
253 438
254 /* check which hardware we have 439 /* Check which hardware we have.
255 We must do this call two times to get reliable values (hw bug). */ 440 * We must do this call two times to get reliable values (hw bug).
441 */
256 ret = anysee_get_hw_info(adap->dev, hw_info); 442 ret = anysee_get_hw_info(adap->dev, hw_info);
257 if (ret) 443 if (ret)
258 return ret; 444 goto error;
445
259 ret = anysee_get_hw_info(adap->dev, hw_info); 446 ret = anysee_get_hw_info(adap->dev, hw_info);
260 if (ret) 447 if (ret)
261 return ret; 448 goto error;
262 449
263 /* Meaning of these info bytes are guessed. */ 450 /* Meaning of these info bytes are guessed. */
264 info("firmware version:%d.%d.%d hardware id:%d", 451 info("firmware version:%d.%d hardware id:%d",
265 0, hw_info[1], hw_info[2], hw_info[0]); 452 hw_info[1], hw_info[2], hw_info[0]);
266 453
267 ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */ 454 state->hw = hw_info[0];
268 if (ret)
269 return ret;
270 deb_info("%s: IO port D:%02x\n", __func__, io_d);
271
272 /* Select demod using trial and error method. */
273
274 /* Try to attach demodulator in following order:
275 model demod hw firmware
276 1. E30 MT352 02 0.2.1
277 2. E30 ZL10353 02 0.2.1
278 3. E30 Combo ZL10353 0f 0.1.2 DVB-T/C combo
279 4. E30 Plus ZL10353 06 0.1.0
280 5. E30C Plus TDA10023 0a 0.1.0 rev 0.2
281 E30C Plus TDA10023 0f 0.1.2 rev 0.4
282 E30 Combo TDA10023 0f 0.1.2 DVB-T/C combo
283 */
284
285 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
286 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
287 &adap->dev->i2c_adap);
288 if (adap->fe != NULL) {
289 state->tuner = DVB_PLL_THOMSON_DTT7579;
290 return 0;
291 }
292 455
293 /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ 456 switch (state->hw) {
294 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, 457 case ANYSEE_HW_02: /* 2 */
295 &adap->dev->i2c_adap); 458 /* E30 */
296 if (adap->fe != NULL) { 459
297 state->tuner = DVB_PLL_THOMSON_DTT7579; 460 /* attach demod */
298 return 0; 461 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
299 } 462 &adap->dev->i2c_adap);
463 if (adap->fe)
464 break;
465
466 /* attach demod */
467 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
468 &adap->dev->i2c_adap);
469
470 break;
471 case ANYSEE_HW_507CD: /* 6 */
472 /* E30 Plus */
300 473
301 /* for E30 Combo Plus DVB-T demodulator */ 474 /* enable DVB-T demod on IOD[0] */
302 if (dvb_usb_anysee_delsys) { 475 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
303 ret = anysee_write_reg(adap->dev, 0xb0, 0x01);
304 if (ret) 476 if (ret)
305 return ret; 477 goto error;
478
479 /* enable transport stream on IOA[7] */
480 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
481 if (ret)
482 goto error;
306 483
307 /* Zarlink ZL10353 DVB-T demod */ 484 /* attach demod */
308 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, 485 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
309 &adap->dev->i2c_adap); 486 &adap->dev->i2c_adap);
310 if (adap->fe != NULL) { 487
311 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; 488 break;
312 return 0; 489 case ANYSEE_HW_507DC: /* 10 */
490 /* E30 C Plus */
491
492 /* enable DVB-C demod on IOD[0] */
493 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
494 if (ret)
495 goto error;
496
497 /* attach demod */
498 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
499 &adap->dev->i2c_adap, 0x48);
500
501 break;
502 case ANYSEE_HW_507SI: /* 11 */
503 /* E30 S2 Plus */
504
505 /* enable DVB-S/S2 demod on IOD[0] */
506 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
507 if (ret)
508 goto error;
509
510 /* attach demod */
511 adap->fe = dvb_attach(cx24116_attach, &anysee_cx24116_config,
512 &adap->dev->i2c_adap);
513
514 break;
515 case ANYSEE_HW_507FA: /* 15 */
516 /* E30 Combo Plus */
517 /* E30 C Plus */
518
519 /* enable tuner on IOE[4] */
520 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
521 if (ret)
522 goto error;
523
524 /* probe TDA18212 */
525 tmp = 0;
526 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
527 if (ret == 2 && tmp == 0xc7)
528 deb_info("%s: TDA18212 found\n", __func__);
529 else
530 tmp = 0;
531
532 /* disable tuner on IOE[4] */
533 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
534 if (ret)
535 goto error;
536
537 if (dvb_usb_anysee_delsys) {
538 /* disable DVB-C demod on IOD[5] */
539 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
540 0x20);
541 if (ret)
542 goto error;
543
544 /* enable DVB-T demod on IOD[0] */
545 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
546 0x01);
547 if (ret)
548 goto error;
549
550 /* attach demod */
551 if (tmp == 0xc7) {
552 /* TDA18212 config */
553 adap->fe = dvb_attach(zl10353_attach,
554 &anysee_zl10353_tda18212_config2,
555 &adap->dev->i2c_adap);
556 } else {
557 /* PLL config */
558 adap->fe = dvb_attach(zl10353_attach,
559 &anysee_zl10353_config,
560 &adap->dev->i2c_adap);
561 }
562 } else {
563 /* disable DVB-T demod on IOD[0] */
564 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
565 0x01);
566 if (ret)
567 goto error;
568
569 /* enable DVB-C demod on IOD[5] */
570 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
571 0x20);
572 if (ret)
573 goto error;
574
575 /* attach demod */
576 if (tmp == 0xc7) {
577 /* TDA18212 config */
578 adap->fe = dvb_attach(tda10023_attach,
579 &anysee_tda10023_tda18212_config,
580 &adap->dev->i2c_adap, 0x48);
581 } else {
582 /* PLL config */
583 adap->fe = dvb_attach(tda10023_attach,
584 &anysee_tda10023_config,
585 &adap->dev->i2c_adap, 0x48);
586 }
313 } 587 }
314 }
315 588
316 /* connect demod on IO port D for TDA10023 & ZL10353 */ 589 break;
317 ret = anysee_write_reg(adap->dev, 0xb0, 0x25); 590 case ANYSEE_HW_508TC: /* 18 */
318 if (ret) 591 /* E7 TC */
319 return ret;
320 592
321 /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ 593 /* enable transport stream on IOA[7] */
322 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, 594 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
323 &adap->dev->i2c_adap); 595 if (ret)
324 if (adap->fe != NULL) { 596 goto error;
325 state->tuner = DVB_PLL_THOMSON_DTT7579; 597
326 return 0; 598 if (dvb_usb_anysee_delsys) {
327 } 599 /* disable DVB-C demod on IOD[5] */
600 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
601 0x20);
602 if (ret)
603 goto error;
604
605 /* enable DVB-T demod on IOD[6] */
606 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
607 0x40);
608 if (ret)
609 goto error;
610
611 /* enable IF route on IOE[0] */
612 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
613 0x01);
614 if (ret)
615 goto error;
616
617 /* attach demod */
618 adap->fe = dvb_attach(zl10353_attach,
619 &anysee_zl10353_tda18212_config,
620 &adap->dev->i2c_adap);
621 } else {
622 /* disable DVB-T demod on IOD[6] */
623 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
624 0x40);
625 if (ret)
626 goto error;
627
628 /* enable DVB-C demod on IOD[5] */
629 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
630 0x20);
631 if (ret)
632 goto error;
633
634 /* enable IF route on IOE[0] */
635 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
636 0x01);
637 if (ret)
638 goto error;
639
640 /* attach demod */
641 adap->fe = dvb_attach(tda10023_attach,
642 &anysee_tda10023_tda18212_config,
643 &adap->dev->i2c_adap, 0x48);
644 }
328 645
329 /* IO port E - E30C rev 0.4 board requires this */ 646 break;
330 ret = anysee_write_reg(adap->dev, 0xb1, 0xa7); 647 case ANYSEE_HW_508S2: /* 19 */
331 if (ret) 648 /* E7 S2 */
332 return ret;
333 649
334 /* Philips TDA10023 DVB-C demod */ 650 /* enable transport stream on IOA[7] */
335 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, 651 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
336 &adap->dev->i2c_adap, 0x48); 652 if (ret)
337 if (adap->fe != NULL) { 653 goto error;
338 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
339 return 0;
340 }
341 654
342 /* return IO port D to init value for safe */ 655 /* enable DVB-S/S2 demod on IOE[5] */
343 ret = anysee_write_reg(adap->dev, 0xb0, io_d); 656 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
344 if (ret) 657 if (ret)
345 return ret; 658 goto error;
659
660 /* attach demod */
661 adap->fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
662 &adap->dev->i2c_adap, 0);
346 663
347 err("Unknown Anysee version: %02x %02x %02x. "\ 664 break;
348 "Please report the <linux-dvb@linuxtv.org>.", 665 }
349 hw_info[0], hw_info[1], hw_info[2]);
350 666
351 return -ENODEV; 667 if (!adap->fe) {
668 /* we have no frontend :-( */
669 ret = -ENODEV;
670 err("Unsupported Anysee version. " \
671 "Please report the <linux-media@vger.kernel.org>.");
672 }
673error:
674 return ret;
352} 675}
353 676
354static int anysee_tuner_attach(struct dvb_usb_adapter *adap) 677static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
355{ 678{
356 struct anysee_state *state = adap->dev->priv; 679 struct anysee_state *state = adap->dev->priv;
680 struct dvb_frontend *fe;
681 int ret;
357 deb_info("%s:\n", __func__); 682 deb_info("%s:\n", __func__);
358 683
359 switch (state->tuner) { 684 switch (state->hw) {
360 case DVB_PLL_THOMSON_DTT7579: 685 case ANYSEE_HW_02: /* 2 */
361 /* Thomson dtt7579 (not sure) PLL inside of: 686 /* E30 */
362 Samsung DNOS404ZH102A NIM 687
363 Samsung DNOS404ZH103A NIM */ 688 /* attach tuner */
364 dvb_attach(dvb_pll_attach, adap->fe, 0x61, 689 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
365 NULL, DVB_PLL_THOMSON_DTT7579); 690 NULL, DVB_PLL_THOMSON_DTT7579);
691
692 break;
693 case ANYSEE_HW_507CD: /* 6 */
694 /* E30 Plus */
695
696 /* attach tuner */
697 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
698 &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
699
700 break;
701 case ANYSEE_HW_507DC: /* 10 */
702 /* E30 C Plus */
703
704 /* attach tuner */
705 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
706 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
707
708 break;
709 case ANYSEE_HW_507SI: /* 11 */
710 /* E30 S2 Plus */
711
712 /* attach LNB controller */
713 fe = dvb_attach(isl6423_attach, adap->fe, &adap->dev->i2c_adap,
714 &anysee_isl6423_config);
715
716 break;
717 case ANYSEE_HW_507FA: /* 15 */
718 /* E30 Combo Plus */
719 /* E30 C Plus */
720
721 if (dvb_usb_anysee_delsys) {
722 /* enable DVB-T tuner on IOE[0] */
723 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
724 0x01);
725 if (ret)
726 goto error;
727 } else {
728 /* enable DVB-C tuner on IOE[0] */
729 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
730 0x01);
731 if (ret)
732 goto error;
733 }
734
735 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
736 * fails attach old simple PLL. */
737
738 /* enable tuner on IOE[4] */
739 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
740 if (ret)
741 goto error;
742
743 /* attach tuner */
744 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
745 &anysee_tda18212_config);
746 if (fe)
747 break;
748
749 /* disable tuner on IOE[4] */
750 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
751 if (ret)
752 goto error;
753
754 /* attach tuner */
755 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
756 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
757
366 break; 758 break;
367 case DVB_PLL_SAMSUNG_DTOS403IH102A: 759 case ANYSEE_HW_508TC: /* 18 */
368 /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */ 760 /* E7 TC */
369 dvb_attach(dvb_pll_attach, adap->fe, 0xc0, 761
370 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); 762 /* enable tuner on IOE[4] */
763 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
764 if (ret)
765 goto error;
766
767 /* attach tuner */
768 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
769 &anysee_tda18212_config);
770
371 break; 771 break;
772 case ANYSEE_HW_508S2: /* 19 */
773 /* E7 S2 */
774
775 /* attach tuner */
776 fe = dvb_attach(stv6110_attach, adap->fe,
777 &anysee_stv6110_config, &adap->dev->i2c_adap);
778
779 if (fe) {
780 /* attach LNB controller */
781 fe = dvb_attach(isl6423_attach, adap->fe,
782 &adap->dev->i2c_adap, &anysee_isl6423_config);
783 }
784
785 break;
786 default:
787 fe = NULL;
372 } 788 }
373 789
374 return 0; 790 if (fe)
791 ret = 0;
792 else
793 ret = -ENODEV;
794
795error:
796 return ret;
375} 797}
376 798
377static int anysee_rc_query(struct dvb_usb_device *d) 799static int anysee_rc_query(struct dvb_usb_device *d)
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h
index 7ca01ff6e13c..a7673aa1e007 100644
--- a/drivers/media/dvb/dvb-usb/anysee.h
+++ b/drivers/media/dvb/dvb-usb/anysee.h
@@ -57,10 +57,29 @@ enum cmd {
57}; 57};
58 58
59struct anysee_state { 59struct anysee_state {
60 u8 tuner; 60 u8 hw; /* PCB ID */
61 u8 seq; 61 u8 seq;
62}; 62};
63 63
64#define ANYSEE_HW_02 2 /* E30 */
65#define ANYSEE_HW_507CD 6 /* E30 Plus */
66#define ANYSEE_HW_507DC 10 /* E30 C Plus */
67#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */
68#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */
69#define ANYSEE_HW_508TC 18 /* E7 TC */
70#define ANYSEE_HW_508S2 19 /* E7 S2 */
71
72#define REG_IOA 0x80 /* Port A (bit addressable) */
73#define REG_IOB 0x90 /* Port B (bit addressable) */
74#define REG_IOC 0xa0 /* Port C (bit addressable) */
75#define REG_IOD 0xb0 /* Port D (bit addressable) */
76#define REG_IOE 0xb1 /* Port E (NOT bit addressable) */
77#define REG_OEA 0xb2 /* Port A Output Enable */
78#define REG_OEB 0xb3 /* Port B Output Enable */
79#define REG_OEC 0xb4 /* Port C Output Enable */
80#define REG_OED 0xb5 /* Port D Output Enable */
81#define REG_OEE 0xb6 /* Port E Output Enable */
82
64#endif 83#endif
65 84
66/*************************************************************************** 85/***************************************************************************
@@ -136,7 +155,7 @@ General reply packet(s) are always used if not own reply defined.
136---------------------------------------------------------------------------- 155----------------------------------------------------------------------------
137| 04 | 0x00 156| 04 | 0x00
138---------------------------------------------------------------------------- 157----------------------------------------------------------------------------
139| 05 | 0x01 158| 05 | data length
140---------------------------------------------------------------------------- 159----------------------------------------------------------------------------
141| 06-59 | don't care 160| 06-59 | don't care
142---------------------------------------------------------------------------- 161----------------------------------------------------------------------------
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c
index eb34cc3894e0..2351077ff2b3 100644
--- a/drivers/media/dvb/dvb-usb/au6610.c
+++ b/drivers/media/dvb/dvb-usb/au6610.c
@@ -33,8 +33,16 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
33{ 33{
34 int ret; 34 int ret;
35 u16 index; 35 u16 index;
36 u8 usb_buf[6]; /* enough for all known requests, 36 u8 *usb_buf;
37 read returns 5 and write 6 bytes */ 37
38 /*
39 * allocate enough for all known requests,
40 * read returns 5 and write 6 bytes
41 */
42 usb_buf = kmalloc(6, GFP_KERNEL);
43 if (!usb_buf)
44 return -ENOMEM;
45
38 switch (wlen) { 46 switch (wlen) {
39 case 1: 47 case 1:
40 index = wbuf[0] << 8; 48 index = wbuf[0] << 8;
@@ -45,14 +53,15 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
45 break; 53 break;
46 default: 54 default:
47 warn("wlen = %x, aborting.", wlen); 55 warn("wlen = %x, aborting.", wlen);
48 return -EINVAL; 56 ret = -EINVAL;
57 goto error;
49 } 58 }
50 59
51 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, 60 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
52 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, 61 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
53 usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT); 62 usb_buf, 6, AU6610_USB_TIMEOUT);
54 if (ret < 0) 63 if (ret < 0)
55 return ret; 64 goto error;
56 65
57 switch (operation) { 66 switch (operation) {
58 case AU6610_REQ_I2C_READ: 67 case AU6610_REQ_I2C_READ:
@@ -60,7 +69,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
60 /* requested value is always 5th byte in buffer */ 69 /* requested value is always 5th byte in buffer */
61 rbuf[0] = usb_buf[4]; 70 rbuf[0] = usb_buf[4];
62 } 71 }
63 72error:
73 kfree(usb_buf);
64 return ret; 74 return ret;
65} 75}
66 76
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
index 3df2045b7d2d..6d1a3041540d 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -39,7 +39,7 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
39 u8 requesttype; 39 u8 requesttype;
40 u16 value; 40 u16 value;
41 u16 index; 41 u16 index;
42 u8 buf[req->data_len]; 42 u8 *buf;
43 43
44 request = req->cmd; 44 request = req->cmd;
45 value = req->value; 45 value = req->value;
@@ -62,6 +62,12 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
62 goto error; 62 goto error;
63 } 63 }
64 64
65 buf = kmalloc(req->data_len, GFP_KERNEL);
66 if (!buf) {
67 ret = -ENOMEM;
68 goto error;
69 }
70
65 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { 71 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
66 /* write */ 72 /* write */
67 memcpy(buf, req->data, req->data_len); 73 memcpy(buf, req->data, req->data_len);
@@ -74,7 +80,7 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
74 msleep(1); /* avoid I2C errors */ 80 msleep(1); /* avoid I2C errors */
75 81
76 ret = usb_control_msg(udev, pipe, request, requesttype, value, index, 82 ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
77 buf, sizeof(buf), CE6230_USB_TIMEOUT); 83 buf, req->data_len, CE6230_USB_TIMEOUT);
78 84
79 ce6230_debug_dump(request, requesttype, value, index, buf, 85 ce6230_debug_dump(request, requesttype, value, index, buf,
80 req->data_len, deb_xfer); 86 req->data_len, deb_xfer);
@@ -88,6 +94,7 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
88 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) 94 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
89 memcpy(req->data, buf, req->data_len); 95 memcpy(req->data, buf, req->data_len);
90 96
97 kfree(buf);
91error: 98error:
92 return ret; 99 return ret;
93} 100}
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index b2a87f2c2c3e..9bd6d51b3b93 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -46,8 +46,9 @@ struct dib0700_state {
46 u8 is_dib7000pc; 46 u8 is_dib7000pc;
47 u8 fw_use_new_i2c_api; 47 u8 fw_use_new_i2c_api;
48 u8 disable_streaming_master_mode; 48 u8 disable_streaming_master_mode;
49 u32 fw_version; 49 u32 fw_version;
50 u32 nb_packet_buffer_size; 50 u32 nb_packet_buffer_size;
51 u8 buf[255];
51}; 52};
52 53
53extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, 54extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index b79af68c54ae..5eb91b4f8fd0 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -27,19 +27,25 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, 27int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
28 u32 *romversion, u32 *ramversion, u32 *fwtype) 28 u32 *romversion, u32 *ramversion, u32 *fwtype)
29{ 29{
30 u8 b[16]; 30 struct dib0700_state *st = d->priv;
31 int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), 31 int ret;
32
33 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
32 REQUEST_GET_VERSION, 34 REQUEST_GET_VERSION,
33 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, 35 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
34 b, sizeof(b), USB_CTRL_GET_TIMEOUT); 36 st->buf, 16, USB_CTRL_GET_TIMEOUT);
35 if (hwversion != NULL) 37 if (hwversion != NULL)
36 *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; 38 *hwversion = (st->buf[0] << 24) | (st->buf[1] << 16) |
39 (st->buf[2] << 8) | st->buf[3];
37 if (romversion != NULL) 40 if (romversion != NULL)
38 *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; 41 *romversion = (st->buf[4] << 24) | (st->buf[5] << 16) |
42 (st->buf[6] << 8) | st->buf[7];
39 if (ramversion != NULL) 43 if (ramversion != NULL)
40 *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; 44 *ramversion = (st->buf[8] << 24) | (st->buf[9] << 16) |
45 (st->buf[10] << 8) | st->buf[11];
41 if (fwtype != NULL) 46 if (fwtype != NULL)
42 *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; 47 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |
48 (st->buf[14] << 8) | st->buf[15];
43 return ret; 49 return ret;
44} 50}
45 51
@@ -101,24 +107,31 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen
101 107
102int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) 108int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
103{ 109{
104 u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) }; 110 struct dib0700_state *st = d->priv;
105 return dib0700_ctrl_wr(d, buf, sizeof(buf)); 111 s16 ret;
112
113 st->buf[0] = REQUEST_SET_GPIO;
114 st->buf[1] = gpio;
115 st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
116
117 ret = dib0700_ctrl_wr(d, st->buf, 3);
118
119 return ret;
106} 120}
107 121
108static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) 122static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
109{ 123{
110 struct dib0700_state *st = d->priv; 124 struct dib0700_state *st = d->priv;
111 u8 b[3];
112 int ret; 125 int ret;
113 126
114 if (st->fw_version >= 0x10201) { 127 if (st->fw_version >= 0x10201) {
115 b[0] = REQUEST_SET_USB_XFER_LEN; 128 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
116 b[1] = (nb_ts_packets >> 8) & 0xff; 129 st->buf[1] = (nb_ts_packets >> 8) & 0xff;
117 b[2] = nb_ts_packets & 0xff; 130 st->buf[2] = nb_ts_packets & 0xff;
118 131
119 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); 132 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
120 133
121 ret = dib0700_ctrl_wr(d, b, sizeof(b)); 134 ret = dib0700_ctrl_wr(d, st->buf, 3);
122 } else { 135 } else {
123 deb_info("this firmware does not allow to change the USB xfer len\n"); 136 deb_info("this firmware does not allow to change the USB xfer len\n");
124 ret = -EIO; 137 ret = -EIO;
@@ -137,11 +150,11 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
137 properly support i2c read calls not preceded by a write */ 150 properly support i2c read calls not preceded by a write */
138 151
139 struct dvb_usb_device *d = i2c_get_adapdata(adap); 152 struct dvb_usb_device *d = i2c_get_adapdata(adap);
153 struct dib0700_state *st = d->priv;
140 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */ 154 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
141 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */ 155 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
142 uint8_t en_start = 0; 156 uint8_t en_start = 0;
143 uint8_t en_stop = 0; 157 uint8_t en_stop = 0;
144 uint8_t buf[255]; /* TBV: malloc ? */
145 int result, i; 158 int result, i;
146 159
147 /* Ensure nobody else hits the i2c bus while we're sending our 160 /* Ensure nobody else hits the i2c bus while we're sending our
@@ -195,24 +208,24 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
195 208
196 } else { 209 } else {
197 /* Write request */ 210 /* Write request */
198 buf[0] = REQUEST_NEW_I2C_WRITE; 211 st->buf[0] = REQUEST_NEW_I2C_WRITE;
199 buf[1] = msg[i].addr << 1; 212 st->buf[1] = msg[i].addr << 1;
200 buf[2] = (en_start << 7) | (en_stop << 6) | 213 st->buf[2] = (en_start << 7) | (en_stop << 6) |
201 (msg[i].len & 0x3F); 214 (msg[i].len & 0x3F);
202 /* I2C ctrl + FE bus; */ 215 /* I2C ctrl + FE bus; */
203 buf[3] = ((gen_mode << 6) & 0xC0) | 216 st->buf[3] = ((gen_mode << 6) & 0xC0) |
204 ((bus_mode << 4) & 0x30); 217 ((bus_mode << 4) & 0x30);
205 /* The Actual i2c payload */ 218 /* The Actual i2c payload */
206 memcpy(&buf[4], msg[i].buf, msg[i].len); 219 memcpy(&st->buf[4], msg[i].buf, msg[i].len);
207 220
208 deb_data(">>> "); 221 deb_data(">>> ");
209 debug_dump(buf, msg[i].len + 4, deb_data); 222 debug_dump(st->buf, msg[i].len + 4, deb_data);
210 223
211 result = usb_control_msg(d->udev, 224 result = usb_control_msg(d->udev,
212 usb_sndctrlpipe(d->udev, 0), 225 usb_sndctrlpipe(d->udev, 0),
213 REQUEST_NEW_I2C_WRITE, 226 REQUEST_NEW_I2C_WRITE,
214 USB_TYPE_VENDOR | USB_DIR_OUT, 227 USB_TYPE_VENDOR | USB_DIR_OUT,
215 0, 0, buf, msg[i].len + 4, 228 0, 0, st->buf, msg[i].len + 4,
216 USB_CTRL_GET_TIMEOUT); 229 USB_CTRL_GET_TIMEOUT);
217 if (result < 0) { 230 if (result < 0) {
218 deb_info("i2c write error (status = %d)\n", result); 231 deb_info("i2c write error (status = %d)\n", result);
@@ -231,27 +244,29 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
231 struct i2c_msg *msg, int num) 244 struct i2c_msg *msg, int num)
232{ 245{
233 struct dvb_usb_device *d = i2c_get_adapdata(adap); 246 struct dvb_usb_device *d = i2c_get_adapdata(adap);
247 struct dib0700_state *st = d->priv;
234 int i,len; 248 int i,len;
235 u8 buf[255];
236 249
237 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 250 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
238 return -EAGAIN; 251 return -EAGAIN;
239 252
240 for (i = 0; i < num; i++) { 253 for (i = 0; i < num; i++) {
241 /* fill in the address */ 254 /* fill in the address */
242 buf[1] = msg[i].addr << 1; 255 st->buf[1] = msg[i].addr << 1;
243 /* fill the buffer */ 256 /* fill the buffer */
244 memcpy(&buf[2], msg[i].buf, msg[i].len); 257 memcpy(&st->buf[2], msg[i].buf, msg[i].len);
245 258
246 /* write/read request */ 259 /* write/read request */
247 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { 260 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
248 buf[0] = REQUEST_I2C_READ; 261 st->buf[0] = REQUEST_I2C_READ;
249 buf[1] |= 1; 262 st->buf[1] |= 1;
250 263
251 /* special thing in the current firmware: when length is zero the read-failed */ 264 /* special thing in the current firmware: when length is zero the read-failed */
252 if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) { 265 len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
266 msg[i+1].buf, msg[i+1].len);
267 if (len <= 0) {
253 deb_info("I2C read failed on address 0x%02x\n", 268 deb_info("I2C read failed on address 0x%02x\n",
254 msg[i].addr); 269 msg[i].addr);
255 break; 270 break;
256 } 271 }
257 272
@@ -259,13 +274,13 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
259 274
260 i++; 275 i++;
261 } else { 276 } else {
262 buf[0] = REQUEST_I2C_WRITE; 277 st->buf[0] = REQUEST_I2C_WRITE;
263 if (dib0700_ctrl_wr(d, buf, msg[i].len + 2) < 0) 278 if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
264 break; 279 break;
265 } 280 }
266 } 281 }
267
268 mutex_unlock(&d->i2c_mutex); 282 mutex_unlock(&d->i2c_mutex);
283
269 return i; 284 return i;
270} 285}
271 286
@@ -297,15 +312,23 @@ struct i2c_algorithm dib0700_i2c_algo = {
297int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, 312int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
298 struct dvb_usb_device_description **desc, int *cold) 313 struct dvb_usb_device_description **desc, int *cold)
299{ 314{
300 u8 b[16]; 315 s16 ret;
301 s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), 316 u8 *b;
317
318 b = kmalloc(16, GFP_KERNEL);
319 if (!b)
320 return -ENOMEM;
321
322
323 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
302 REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT); 324 REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
303 325
304 deb_info("FW GET_VERSION length: %d\n",ret); 326 deb_info("FW GET_VERSION length: %d\n",ret);
305 327
306 *cold = ret <= 0; 328 *cold = ret <= 0;
307
308 deb_info("cold: %d\n", *cold); 329 deb_info("cold: %d\n", *cold);
330
331 kfree(b);
309 return 0; 332 return 0;
310} 333}
311 334
@@ -313,43 +336,50 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
313 u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv, 336 u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
314 u16 pll_loopdiv, u16 free_div, u16 dsuScaler) 337 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
315{ 338{
316 u8 b[10]; 339 struct dib0700_state *st = d->priv;
317 b[0] = REQUEST_SET_CLOCK; 340 s16 ret;
318 b[1] = (en_pll << 7) | (pll_src << 6) | (pll_range << 5) | (clock_gpio3 << 4); 341
319 b[2] = (pll_prediv >> 8) & 0xff; // MSB 342 st->buf[0] = REQUEST_SET_CLOCK;
320 b[3] = pll_prediv & 0xff; // LSB 343 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
321 b[4] = (pll_loopdiv >> 8) & 0xff; // MSB 344 (pll_range << 5) | (clock_gpio3 << 4);
322 b[5] = pll_loopdiv & 0xff; // LSB 345 st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */
323 b[6] = (free_div >> 8) & 0xff; // MSB 346 st->buf[3] = pll_prediv & 0xff; /* LSB */
324 b[7] = free_div & 0xff; // LSB 347 st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
325 b[8] = (dsuScaler >> 8) & 0xff; // MSB 348 st->buf[5] = pll_loopdiv & 0xff; /* LSB */
326 b[9] = dsuScaler & 0xff; // LSB 349 st->buf[6] = (free_div >> 8) & 0xff; /* MSB */
327 350 st->buf[7] = free_div & 0xff; /* LSB */
328 return dib0700_ctrl_wr(d, b, 10); 351 st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */
352 st->buf[9] = dsuScaler & 0xff; /* LSB */
353
354 ret = dib0700_ctrl_wr(d, st->buf, 10);
355
356 return ret;
329} 357}
330 358
331int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) 359int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
332{ 360{
361 struct dib0700_state *st = d->priv;
333 u16 divider; 362 u16 divider;
334 u8 b[8];
335 363
336 if (scl_kHz == 0) 364 if (scl_kHz == 0)
337 return -EINVAL; 365 return -EINVAL;
338 366
339 b[0] = REQUEST_SET_I2C_PARAM; 367 st->buf[0] = REQUEST_SET_I2C_PARAM;
340 divider = (u16) (30000 / scl_kHz); 368 divider = (u16) (30000 / scl_kHz);
341 b[2] = (u8) (divider >> 8); 369 st->buf[1] = 0;
342 b[3] = (u8) (divider & 0xff); 370 st->buf[2] = (u8) (divider >> 8);
371 st->buf[3] = (u8) (divider & 0xff);
343 divider = (u16) (72000 / scl_kHz); 372 divider = (u16) (72000 / scl_kHz);
344 b[4] = (u8) (divider >> 8); 373 st->buf[4] = (u8) (divider >> 8);
345 b[5] = (u8) (divider & 0xff); 374 st->buf[5] = (u8) (divider & 0xff);
346 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */ 375 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
347 b[6] = (u8) (divider >> 8); 376 st->buf[6] = (u8) (divider >> 8);
348 b[7] = (u8) (divider & 0xff); 377 st->buf[7] = (u8) (divider & 0xff);
349 378
350 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", 379 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
351 (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); 380 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
352 return dib0700_ctrl_wr(d, b, 8); 381 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
382 return dib0700_ctrl_wr(d, st->buf, 8);
353} 383}
354 384
355 385
@@ -364,32 +394,45 @@ int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
364 394
365static int dib0700_jumpram(struct usb_device *udev, u32 address) 395static int dib0700_jumpram(struct usb_device *udev, u32 address)
366{ 396{
367 int ret, actlen; 397 int ret = 0, actlen;
368 u8 buf[8] = { REQUEST_JUMPRAM, 0, 0, 0, 398 u8 *buf;
369 (address >> 24) & 0xff, 399
370 (address >> 16) & 0xff, 400 buf = kmalloc(8, GFP_KERNEL);
371 (address >> 8) & 0xff, 401 if (!buf)
372 address & 0xff }; 402 return -ENOMEM;
403 buf[0] = REQUEST_JUMPRAM;
404 buf[1] = 0;
405 buf[2] = 0;
406 buf[3] = 0;
407 buf[4] = (address >> 24) & 0xff;
408 buf[5] = (address >> 16) & 0xff;
409 buf[6] = (address >> 8) & 0xff;
410 buf[7] = address & 0xff;
373 411
374 if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) { 412 if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
375 deb_fw("jumpram to 0x%x failed\n",address); 413 deb_fw("jumpram to 0x%x failed\n",address);
376 return ret; 414 goto out;
377 } 415 }
378 if (actlen != 8) { 416 if (actlen != 8) {
379 deb_fw("jumpram to 0x%x failed\n",address); 417 deb_fw("jumpram to 0x%x failed\n",address);
380 return -EIO; 418 ret = -EIO;
419 goto out;
381 } 420 }
382 return 0; 421out:
422 kfree(buf);
423 return ret;
383} 424}
384 425
385int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) 426int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
386{ 427{
387 struct hexline hx; 428 struct hexline hx;
388 int pos = 0, ret, act_len, i, adap_num; 429 int pos = 0, ret, act_len, i, adap_num;
389 u8 b[16]; 430 u8 *buf;
390 u32 fw_version; 431 u32 fw_version;
391 432
392 u8 buf[260]; 433 buf = kmalloc(260, GFP_KERNEL);
434 if (!buf)
435 return -ENOMEM;
393 436
394 while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) { 437 while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
395 deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n", 438 deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
@@ -411,7 +454,7 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
411 454
412 if (ret < 0) { 455 if (ret < 0) {
413 err("firmware download failed at %d with %d",pos,ret); 456 err("firmware download failed at %d with %d",pos,ret);
414 return ret; 457 goto out;
415 } 458 }
416 } 459 }
417 460
@@ -432,8 +475,8 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
432 usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 475 usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
433 REQUEST_GET_VERSION, 476 REQUEST_GET_VERSION,
434 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, 477 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
435 b, sizeof(b), USB_CTRL_GET_TIMEOUT); 478 buf, 16, USB_CTRL_GET_TIMEOUT);
436 fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; 479 fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
437 480
438 /* set the buffer size - DVB-USB is allocating URB buffers 481 /* set the buffer size - DVB-USB is allocating URB buffers
439 * only after the firwmare download was successful */ 482 * only after the firwmare download was successful */
@@ -451,14 +494,14 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
451 } 494 }
452 } 495 }
453 } 496 }
454 497out:
498 kfree(buf);
455 return ret; 499 return ret;
456} 500}
457 501
458int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 502int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
459{ 503{
460 struct dib0700_state *st = adap->dev->priv; 504 struct dib0700_state *st = adap->dev->priv;
461 u8 b[4];
462 int ret; 505 int ret;
463 506
464 if ((onoff != 0) && (st->fw_version >= 0x10201)) { 507 if ((onoff != 0) && (st->fw_version >= 0x10201)) {
@@ -472,15 +515,17 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
472 } 515 }
473 } 516 }
474 517
475 b[0] = REQUEST_ENABLE_VIDEO; 518 st->buf[0] = REQUEST_ENABLE_VIDEO;
476 b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ 519 /* this bit gives a kind of command,
520 * rather than enabling something or not */
521 st->buf[1] = (onoff << 4) | 0x00;
477 522
478 if (st->disable_streaming_master_mode == 1) 523 if (st->disable_streaming_master_mode == 1)
479 b[2] = 0x00; 524 st->buf[2] = 0x00;
480 else 525 else
481 b[2] = 0x01 << 4; /* Master mode */ 526 st->buf[2] = 0x01 << 4; /* Master mode */
482 527
483 b[3] = 0x00; 528 st->buf[3] = 0x00;
484 529
485 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); 530 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
486 531
@@ -499,20 +544,23 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
499 st->channel_state |= 1 << (3-adap->stream.props.endpoint); 544 st->channel_state |= 1 << (3-adap->stream.props.endpoint);
500 } 545 }
501 546
502 b[2] |= st->channel_state; 547 st->buf[2] |= st->channel_state;
503 548
504 deb_info("data for streaming: %x %x\n", b[1], b[2]); 549 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
505 550
506 return dib0700_ctrl_wr(adap->dev, b, 4); 551 return dib0700_ctrl_wr(adap->dev, st->buf, 4);
507} 552}
508 553
509int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) 554int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
510{ 555{
511 struct dvb_usb_device *d = rc->priv; 556 struct dvb_usb_device *d = rc->priv;
512 struct dib0700_state *st = d->priv; 557 struct dib0700_state *st = d->priv;
513 u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
514 int new_proto, ret; 558 int new_proto, ret;
515 559
560 st->buf[0] = REQUEST_SET_RC;
561 st->buf[1] = 0;
562 st->buf[2] = 0;
563
516 /* Set the IR mode */ 564 /* Set the IR mode */
517 if (rc_type == RC_TYPE_RC5) 565 if (rc_type == RC_TYPE_RC5)
518 new_proto = 1; 566 new_proto = 1;
@@ -526,9 +574,9 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
526 } else 574 } else
527 return -EINVAL; 575 return -EINVAL;
528 576
529 rc_setup[1] = new_proto; 577 st->buf[1] = new_proto;
530 578
531 ret = dib0700_ctrl_wr(d, rc_setup, sizeof(rc_setup)); 579 ret = dib0700_ctrl_wr(d, st->buf, 3);
532 if (ret < 0) { 580 if (ret < 0) {
533 err("ir protocol setup failed"); 581 err("ir protocol setup failed");
534 return ret; 582 return ret;
@@ -561,7 +609,6 @@ struct dib0700_rc_response {
561static void dib0700_rc_urb_completion(struct urb *purb) 609static void dib0700_rc_urb_completion(struct urb *purb)
562{ 610{
563 struct dvb_usb_device *d = purb->context; 611 struct dvb_usb_device *d = purb->context;
564 struct dib0700_state *st;
565 struct dib0700_rc_response *poll_reply; 612 struct dib0700_rc_response *poll_reply;
566 u32 uninitialized_var(keycode); 613 u32 uninitialized_var(keycode);
567 u8 toggle; 614 u8 toggle;
@@ -576,7 +623,6 @@ static void dib0700_rc_urb_completion(struct urb *purb)
576 return; 623 return;
577 } 624 }
578 625
579 st = d->priv;
580 poll_reply = purb->transfer_buffer; 626 poll_reply = purb->transfer_buffer;
581 627
582 if (purb->status < 0) { 628 if (purb->status < 0) {
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 65214af5cd74..c519ad5eb731 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -2439,7 +2439,6 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
2439 2439
2440 dib0700_set_i2c_speed(adap->dev, 340); 2440 dib0700_set_i2c_speed(adap->dev, 340);
2441 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); 2441 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
2442
2443 if (adap->fe == NULL) 2442 if (adap->fe == NULL)
2444 return -ENODEV; 2443 return -ENODEV;
2445 2444
@@ -2802,6 +2801,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
2802 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) }, 2801 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
2803 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) }, 2802 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
2804 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) }, 2803 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
2804/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
2805 { 0 } /* Terminating entry */ 2805 { 0 } /* Terminating entry */
2806}; 2806};
2807MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 2807MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -3411,7 +3411,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
3411 }, 3411 },
3412 }, 3412 },
3413 3413
3414 .num_device_descs = 3, 3414 .num_device_descs = 4,
3415 .devices = { 3415 .devices = {
3416 { "DiBcom STK7770P reference design", 3416 { "DiBcom STK7770P reference design",
3417 { &dib0700_usb_id_table[59], NULL }, 3417 { &dib0700_usb_id_table[59], NULL },
@@ -3427,6 +3427,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
3427 { &dib0700_usb_id_table[74], NULL }, 3427 { &dib0700_usb_id_table[74], NULL },
3428 { NULL }, 3428 { NULL },
3429 }, 3429 },
3430 { "Medion CTX1921 DVB-T USB",
3431 { &dib0700_usb_id_table[75], NULL },
3432 { NULL },
3433 },
3430 }, 3434 },
3431 3435
3432 .rc.core = { 3436 .rc.core = {
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 956f7ae2e510..4c2a689c820e 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -408,7 +408,7 @@ struct rc_map_table rc_map_dibusb_table[] = {
408 408
409 { 0x8008, KEY_DVD }, 409 { 0x8008, KEY_DVD },
410 { 0x8009, KEY_AUDIO }, 410 { 0x8009, KEY_AUDIO },
411 { 0x800a, KEY_MEDIA }, /* Pictures */ 411 { 0x800a, KEY_IMAGES }, /* Pictures */
412 { 0x800b, KEY_VIDEO }, 412 { 0x800b, KEY_VIDEO },
413 413
414 { 0x800c, KEY_BACK }, 414 { 0x800c, KEY_BACK },
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index df1ec3e69f4a..b3cb626ed56e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -12,7 +12,7 @@
12static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) 12static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
13{ 13{
14 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv; 14 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
15 int newfeedcount,ret; 15 int newfeedcount, ret;
16 16
17 if (adap == NULL) 17 if (adap == NULL)
18 return -ENODEV; 18 return -ENODEV;
@@ -24,9 +24,13 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
24 deb_ts("stop feeding\n"); 24 deb_ts("stop feeding\n");
25 usb_urb_kill(&adap->stream); 25 usb_urb_kill(&adap->stream);
26 26
27 if (adap->props.streaming_ctrl != NULL) 27 if (adap->props.streaming_ctrl != NULL) {
28 if ((ret = adap->props.streaming_ctrl(adap,0))) 28 ret = adap->props.streaming_ctrl(adap, 0);
29 if (ret < 0) {
29 err("error while stopping stream."); 30 err("error while stopping stream.");
31 return ret;
32 }
33 }
30 } 34 }
31 35
32 adap->feedcount = newfeedcount; 36 adap->feedcount = newfeedcount;
@@ -49,17 +53,24 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
49 53
50 deb_ts("controlling pid parser\n"); 54 deb_ts("controlling pid parser\n");
51 if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER && 55 if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
52 adap->props.caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF && 56 adap->props.caps &
53 adap->props.pid_filter_ctrl != NULL) 57 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
54 if (adap->props.pid_filter_ctrl(adap,adap->pid_filtering) < 0) 58 adap->props.pid_filter_ctrl != NULL) {
59 ret = adap->props.pid_filter_ctrl(adap,
60 adap->pid_filtering);
61 if (ret < 0) {
55 err("could not handle pid_parser"); 62 err("could not handle pid_parser");
56 63 return ret;
64 }
65 }
57 deb_ts("start feeding\n"); 66 deb_ts("start feeding\n");
58 if (adap->props.streaming_ctrl != NULL) 67 if (adap->props.streaming_ctrl != NULL) {
59 if (adap->props.streaming_ctrl(adap,1)) { 68 ret = adap->props.streaming_ctrl(adap, 1);
69 if (ret < 0) {
60 err("error while enabling fifo."); 70 err("error while enabling fifo.");
61 return -ENODEV; 71 return ret;
62 } 72 }
73 }
63 74
64 } 75 }
65 return 0; 76 return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 3a8b7446b7b0..21b15495d2d7 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -91,6 +91,7 @@
91#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 91#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
92#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397 92#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397
93#define USB_PID_CONEXANT_D680_DMB 0x86d6 93#define USB_PID_CONEXANT_D680_DMB 0x86d6
94#define USB_PID_CREATIX_CTX1921 0x1921
94#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 95#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
95#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 96#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
96#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 97#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index d312323504a4..058b2318abed 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -121,12 +121,16 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
121 u16 index, u8 * data, u16 len, int flags) 121 u16 index, u8 * data, u16 len, int flags)
122{ 122{
123 int ret; 123 int ret;
124 u8 u8buf[len]; 124 u8 *u8buf;
125
126 unsigned int pipe = (flags == DW210X_READ_MSG) ? 125 unsigned int pipe = (flags == DW210X_READ_MSG) ?
127 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); 126 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
128 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; 127 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
129 128
129 u8buf = kmalloc(len, GFP_KERNEL);
130 if (!u8buf)
131 return -ENOMEM;
132
133
130 if (flags == DW210X_WRITE_MSG) 134 if (flags == DW210X_WRITE_MSG)
131 memcpy(u8buf, data, len); 135 memcpy(u8buf, data, len);
132 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, 136 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
@@ -134,6 +138,8 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
134 138
135 if (flags == DW210X_READ_MSG) 139 if (flags == DW210X_READ_MSG)
136 memcpy(data, u8buf, len); 140 memcpy(data, u8buf, len);
141
142 kfree(u8buf);
137 return ret; 143 return ret;
138} 144}
139 145
diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c
index 52f5d4f0f230..1ba3e5dbee10 100644
--- a/drivers/media/dvb/dvb-usb/ec168.c
+++ b/drivers/media/dvb/dvb-usb/ec168.c
@@ -36,7 +36,9 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
36 int ret; 36 int ret;
37 unsigned int pipe; 37 unsigned int pipe;
38 u8 request, requesttype; 38 u8 request, requesttype;
39 u8 buf[req->size]; 39 u8 *buf;
40
41
40 42
41 switch (req->cmd) { 43 switch (req->cmd) {
42 case DOWNLOAD_FIRMWARE: 44 case DOWNLOAD_FIRMWARE:
@@ -72,6 +74,12 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
72 goto error; 74 goto error;
73 } 75 }
74 76
77 buf = kmalloc(req->size, GFP_KERNEL);
78 if (!buf) {
79 ret = -ENOMEM;
80 goto error;
81 }
82
75 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { 83 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
76 /* write */ 84 /* write */
77 memcpy(buf, req->data, req->size); 85 memcpy(buf, req->data, req->size);
@@ -84,13 +92,13 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
84 msleep(1); /* avoid I2C errors */ 92 msleep(1); /* avoid I2C errors */
85 93
86 ret = usb_control_msg(udev, pipe, request, requesttype, req->value, 94 ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
87 req->index, buf, sizeof(buf), EC168_USB_TIMEOUT); 95 req->index, buf, req->size, EC168_USB_TIMEOUT);
88 96
89 ec168_debug_dump(request, requesttype, req->value, req->index, buf, 97 ec168_debug_dump(request, requesttype, req->value, req->index, buf,
90 req->size, deb_xfer); 98 req->size, deb_xfer);
91 99
92 if (ret < 0) 100 if (ret < 0)
93 goto error; 101 goto err_dealloc;
94 else 102 else
95 ret = 0; 103 ret = 0;
96 104
@@ -98,7 +106,11 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
98 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) 106 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
99 memcpy(req->data, buf, req->size); 107 memcpy(req->data, buf, req->size);
100 108
109 kfree(buf);
101 return ret; 110 return ret;
111
112err_dealloc:
113 kfree(buf);
102error: 114error:
103 deb_info("%s: failed:%d\n", __func__, ret); 115 deb_info("%s: failed:%d\n", __func__, ret);
104 return ret; 116 return ret;
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c
index 14a65b4aec07..76159aed9bb0 100644
--- a/drivers/media/dvb/dvb-usb/friio.c
+++ b/drivers/media/dvb/dvb-usb/friio.c
@@ -142,17 +142,20 @@ static u32 gl861_i2c_func(struct i2c_adapter *adapter)
142 return I2C_FUNC_I2C; 142 return I2C_FUNC_I2C;
143} 143}
144 144
145
146static int friio_ext_ctl(struct dvb_usb_adapter *adap, 145static int friio_ext_ctl(struct dvb_usb_adapter *adap,
147 u32 sat_color, int lnb_on) 146 u32 sat_color, int lnb_on)
148{ 147{
149 int i; 148 int i;
150 int ret; 149 int ret;
151 struct i2c_msg msg; 150 struct i2c_msg msg;
152 u8 buf[2]; 151 u8 *buf;
153 u32 mask; 152 u32 mask;
154 u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0; 153 u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
155 154
155 buf = kmalloc(2, GFP_KERNEL);
156 if (!buf)
157 return -ENOMEM;
158
156 msg.addr = 0x00; 159 msg.addr = 0x00;
157 msg.flags = 0; 160 msg.flags = 0;
158 msg.len = 2; 161 msg.len = 2;
@@ -189,6 +192,7 @@ static int friio_ext_ctl(struct dvb_usb_adapter *adap,
189 buf[1] |= FRIIO_CTL_CLK; 192 buf[1] |= FRIIO_CTL_CLK;
190 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1); 193 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
191 194
195 kfree(buf);
192 return (ret == 70); 196 return (ret == 70);
193} 197}
194 198
@@ -219,11 +223,20 @@ static int friio_initialize(struct dvb_usb_device *d)
219 int ret; 223 int ret;
220 int i; 224 int i;
221 int retry = 0; 225 int retry = 0;
222 u8 rbuf[2]; 226 u8 *rbuf, *wbuf;
223 u8 wbuf[3];
224 227
225 deb_info("%s called.\n", __func__); 228 deb_info("%s called.\n", __func__);
226 229
230 wbuf = kmalloc(3, GFP_KERNEL);
231 if (!wbuf)
232 return -ENOMEM;
233
234 rbuf = kmalloc(2, GFP_KERNEL);
235 if (!rbuf) {
236 kfree(wbuf);
237 return -ENOMEM;
238 }
239
227 /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */ 240 /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
228 /* because the i2c device is not set up yet. */ 241 /* because the i2c device is not set up yet. */
229 wbuf[0] = 0x11; 242 wbuf[0] = 0x11;
@@ -358,6 +371,8 @@ restart:
358 return 0; 371 return 0;
359 372
360error: 373error:
374 kfree(wbuf);
375 kfree(rbuf);
361 deb_info("%s:ret == %d\n", __func__, ret); 376 deb_info("%s:ret == %d\n", __func__, ret);
362 return -EIO; 377 return -EIO;
363} 378}
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index f2db01212ca1..f36f471deae2 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -62,8 +62,6 @@
62 * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system 62 * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
63 * with other tuners. After a cold reset streaming will not start. 63 * with other tuners. After a cold reset streaming will not start.
64 * 64 *
65 * PID functions have been removed from this driver version due to
66 * problems with different firmware and application versions.
67 */ 65 */
68#define DVB_USB_LOG_PREFIX "LME2510(C)" 66#define DVB_USB_LOG_PREFIX "LME2510(C)"
69#include <linux/usb.h> 67#include <linux/usb.h>
@@ -104,6 +102,10 @@ static int dvb_usb_lme2510_firmware;
104module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644); 102module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
105MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG"); 103MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
106 104
105static int pid_filter;
106module_param_named(pid, pid_filter, int, 0644);
107MODULE_PARM_DESC(pid, "set default 0=on 1=off");
108
107 109
108DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 110DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
109 111
@@ -125,6 +127,7 @@ struct lme2510_state {
125 u8 i2c_tuner_gate_r; 127 u8 i2c_tuner_gate_r;
126 u8 i2c_tuner_addr; 128 u8 i2c_tuner_addr;
127 u8 stream_on; 129 u8 stream_on;
130 u8 pid_size;
128 void *buffer; 131 void *buffer;
129 struct urb *lme_urb; 132 struct urb *lme_urb;
130 void *usb_buffer; 133 void *usb_buffer;
@@ -167,14 +170,14 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
167 } 170 }
168 buff = st->usb_buffer; 171 buff = st->usb_buffer;
169 172
170 /* the read/write capped at 512 */
171 memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
172
173 ret = mutex_lock_interruptible(&d->usb_mutex); 173 ret = mutex_lock_interruptible(&d->usb_mutex);
174 174
175 if (ret < 0) 175 if (ret < 0)
176 return -EAGAIN; 176 return -EAGAIN;
177 177
178 /* the read/write capped at 512 */
179 memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
180
178 ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01)); 181 ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
179 182
180 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01); 183 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
@@ -216,6 +219,37 @@ static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress)
216 return 0; 219 return 0;
217} 220}
218 221
222static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
223{
224 struct lme2510_state *st = d->priv;
225 static u8 pid_buff[] = LME_ZERO_PID;
226 static u8 rbuf[1];
227 u8 pid_no = index * 2;
228 u8 pid_len = pid_no + 2;
229 int ret = 0;
230 deb_info(1, "PID Setting Pid %04x", pid_out);
231
232 if (st->pid_size == 0)
233 ret |= lme2510_stream_restart(d);
234
235 pid_buff[2] = pid_no;
236 pid_buff[3] = (u8)pid_out & 0xff;
237 pid_buff[4] = pid_no + 1;
238 pid_buff[5] = (u8)(pid_out >> 8);
239
240 if (pid_len > st->pid_size)
241 st->pid_size = pid_len;
242 pid_buff[7] = 0x80 + st->pid_size;
243
244 ret |= lme2510_usb_talk(d, pid_buff ,
245 sizeof(pid_buff) , rbuf, sizeof(rbuf));
246
247 if (st->stream_on)
248 ret |= lme2510_stream_restart(d);
249
250 return ret;
251}
252
219static void lme2510_int_response(struct urb *lme_urb) 253static void lme2510_int_response(struct urb *lme_urb)
220{ 254{
221 struct dvb_usb_adapter *adap = lme_urb->context; 255 struct dvb_usb_adapter *adap = lme_urb->context;
@@ -326,16 +360,68 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap)
326 return 0; 360 return 0;
327} 361}
328 362
363static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
364{
365 struct lme2510_state *st = adap->dev->priv;
366 static u8 clear_pid_reg[] = LME_CLEAR_PID;
367 static u8 rbuf[1];
368 int ret;
369
370 deb_info(1, "PID Clearing Filter");
371
372 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
373 if (ret < 0)
374 return -EAGAIN;
375
376 if (!onoff)
377 ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
378 sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
379
380 st->pid_size = 0;
381
382 mutex_unlock(&adap->dev->i2c_mutex);
383
384 return 0;
385}
386
387static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
388 int onoff)
389{
390 int ret = 0;
391
392 deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
393 pid, index, onoff);
394
395 if (onoff)
396 if (!pid_filter) {
397 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
398 if (ret < 0)
399 return -EAGAIN;
400 ret |= lme2510_enable_pid(adap->dev, index, pid);
401 mutex_unlock(&adap->dev->i2c_mutex);
402 }
403
404
405 return ret;
406}
407
408
329static int lme2510_return_status(struct usb_device *dev) 409static int lme2510_return_status(struct usb_device *dev)
330{ 410{
331 int ret = 0; 411 int ret = 0;
332 u8 data[10] = {0}; 412 u8 *data;
413
414 data = kzalloc(10, GFP_KERNEL);
415 if (!data)
416 return -ENOMEM;
333 417
334 ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 418 ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
335 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200); 419 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
336 info("Firmware Status: %x (%x)", ret , data[2]); 420 info("Firmware Status: %x (%x)", ret , data[2]);
337 421
338 return (ret < 0) ? -ENODEV : data[2]; 422 ret = (ret < 0) ? -ENODEV : data[2];
423 kfree(data);
424 return ret;
339} 425}
340 426
341static int lme2510_msg(struct dvb_usb_device *d, 427static int lme2510_msg(struct dvb_usb_device *d,
@@ -591,9 +677,10 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
591 else { 677 else {
592 deb_info(1, "STM Steam Off"); 678 deb_info(1, "STM Steam Off");
593 /* mutex is here only to avoid collision with I2C */ 679 /* mutex is here only to avoid collision with I2C */
594 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); 680 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
681 return -EAGAIN;
595 682
596 ret |= lme2510_usb_talk(adap->dev, clear_reg_3, 683 ret = lme2510_usb_talk(adap->dev, clear_reg_3,
597 sizeof(clear_reg_3), rbuf, rlen); 684 sizeof(clear_reg_3), rbuf, rlen);
598 st->stream_on = 0; 685 st->stream_on = 0;
599 st->i2c_talk_onoff = 1; 686 st->i2c_talk_onoff = 1;
@@ -655,7 +742,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
655 const struct firmware *fw) 742 const struct firmware *fw)
656{ 743{
657 int ret = 0; 744 int ret = 0;
658 u8 data[512] = {0}; 745 u8 *data;
659 u16 j, wlen, len_in, start, end; 746 u16 j, wlen, len_in, start, end;
660 u8 packet_size, dlen, i; 747 u8 packet_size, dlen, i;
661 u8 *fw_data; 748 u8 *fw_data;
@@ -663,6 +750,11 @@ static int lme2510_download_firmware(struct usb_device *dev,
663 packet_size = 0x31; 750 packet_size = 0x31;
664 len_in = 1; 751 len_in = 1;
665 752
753 data = kzalloc(512, GFP_KERNEL);
754 if (!data) {
755 info("FRM Could not start Firmware Download (Buffer allocation failed)");
756 return -ENOMEM;
757 }
666 758
667 info("FRM Starting Firmware Download"); 759 info("FRM Starting Firmware Download");
668 760
@@ -678,15 +770,15 @@ static int lme2510_download_firmware(struct usb_device *dev,
678 data[0] = i | 0x80; 770 data[0] = i | 0x80;
679 dlen = (u8)(end - j)-1; 771 dlen = (u8)(end - j)-1;
680 } 772 }
681 data[1] = dlen; 773 data[1] = dlen;
682 memcpy(&data[2], fw_data, dlen+1); 774 memcpy(&data[2], fw_data, dlen+1);
683 wlen = (u8) dlen + 4; 775 wlen = (u8) dlen + 4;
684 data[wlen-1] = check_sum(fw_data, dlen+1); 776 data[wlen-1] = check_sum(fw_data, dlen+1);
685 deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3], 777 deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
686 data[dlen+2], data[dlen+3]); 778 data[dlen+2], data[dlen+3]);
687 ret |= lme2510_bulk_write(dev, data, wlen, 1); 779 ret |= lme2510_bulk_write(dev, data, wlen, 1);
688 ret |= lme2510_bulk_read(dev, data, len_in , 1); 780 ret |= lme2510_bulk_read(dev, data, len_in , 1);
689 ret |= (data[0] == 0x88) ? 0 : -1; 781 ret |= (data[0] == 0x88) ? 0 : -1;
690 } 782 }
691 } 783 }
692 784
@@ -706,7 +798,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
706 else 798 else
707 info("FRM Firmware Download Completed - Resetting Device"); 799 info("FRM Firmware Download Completed - Resetting Device");
708 800
709 801 kfree(data);
710 return (ret < 0) ? -ENODEV : 0; 802 return (ret < 0) ? -ENODEV : 0;
711} 803}
712 804
@@ -747,7 +839,7 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
747 fw_lme = fw_s0194; 839 fw_lme = fw_s0194;
748 ret = request_firmware(&fw, fw_lme, &udev->dev); 840 ret = request_firmware(&fw, fw_lme, &udev->dev);
749 if (ret == 0) { 841 if (ret == 0) {
750 cold = 0;/*lme2510-s0194 cannot cold reset*/ 842 cold = 0;
751 break; 843 break;
752 } 844 }
753 dvb_usb_lme2510_firmware = TUNER_LG; 845 dvb_usb_lme2510_firmware = TUNER_LG;
@@ -769,8 +861,10 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
769 case TUNER_S7395: 861 case TUNER_S7395:
770 fw_lme = fw_c_s7395; 862 fw_lme = fw_c_s7395;
771 ret = request_firmware(&fw, fw_lme, &udev->dev); 863 ret = request_firmware(&fw, fw_lme, &udev->dev);
772 if (ret == 0) 864 if (ret == 0) {
865 cold = 0;
773 break; 866 break;
867 }
774 dvb_usb_lme2510_firmware = TUNER_LG; 868 dvb_usb_lme2510_firmware = TUNER_LG;
775 case TUNER_LG: 869 case TUNER_LG:
776 fw_lme = fw_c_lg; 870 fw_lme = fw_c_lg;
@@ -796,14 +890,14 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
796 ret = lme2510_download_firmware(udev, fw); 890 ret = lme2510_download_firmware(udev, fw);
797 } 891 }
798 892
893 release_firmware(fw);
894
799 if (cold) { 895 if (cold) {
800 info("FRM Changing to %s firmware", fw_lme); 896 info("FRM Changing to %s firmware", fw_lme);
801 lme_coldreset(udev); 897 lme_coldreset(udev);
802 return -ENODEV; 898 return -ENODEV;
803 } 899 }
804 900
805 release_firmware(fw);
806
807 return ret; 901 return ret;
808} 902}
809 903
@@ -1017,12 +1111,13 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
1017 static u8 rbuf[1]; 1111 static u8 rbuf[1];
1018 int ret, len = 3, rlen = 1; 1112 int ret, len = 3, rlen = 1;
1019 1113
1020 ret = mutex_lock_interruptible(&d->i2c_mutex); 1114 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
1115 return -EAGAIN;
1021 1116
1022 if (onoff) 1117 if (onoff)
1023 ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen); 1118 ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
1024 else 1119 else
1025 ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen); 1120 ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
1026 1121
1027 st->i2c_talk_onoff = 1; 1122 st->i2c_talk_onoff = 1;
1028 1123
@@ -1086,7 +1181,13 @@ static struct dvb_usb_device_properties lme2510_properties = {
1086 .num_adapters = 1, 1181 .num_adapters = 1,
1087 .adapter = { 1182 .adapter = {
1088 { 1183 {
1184 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
1185 DVB_USB_ADAP_NEED_PID_FILTERING|
1186 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1089 .streaming_ctrl = lme2510_streaming_ctrl, 1187 .streaming_ctrl = lme2510_streaming_ctrl,
1188 .pid_filter_count = 15,
1189 .pid_filter = lme2510_pid_filter,
1190 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1090 .frontend_attach = dm04_lme2510_frontend_attach, 1191 .frontend_attach = dm04_lme2510_frontend_attach,
1091 .tuner_attach = dm04_lme2510_tuner, 1192 .tuner_attach = dm04_lme2510_tuner,
1092 /* parameter for the MPEG2-data transfer */ 1193 /* parameter for the MPEG2-data transfer */
@@ -1122,7 +1223,13 @@ static struct dvb_usb_device_properties lme2510c_properties = {
1122 .num_adapters = 1, 1223 .num_adapters = 1,
1123 .adapter = { 1224 .adapter = {
1124 { 1225 {
1226 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
1227 DVB_USB_ADAP_NEED_PID_FILTERING|
1228 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1125 .streaming_ctrl = lme2510_streaming_ctrl, 1229 .streaming_ctrl = lme2510_streaming_ctrl,
1230 .pid_filter_count = 15,
1231 .pid_filter = lme2510_pid_filter,
1232 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1126 .frontend_attach = dm04_lme2510_frontend_attach, 1233 .frontend_attach = dm04_lme2510_frontend_attach,
1127 .tuner_attach = dm04_lme2510_tuner, 1234 .tuner_attach = dm04_lme2510_tuner,
1128 /* parameter for the MPEG2-data transfer */ 1235 /* parameter for the MPEG2-data transfer */
@@ -1151,7 +1258,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
1151 } 1258 }
1152}; 1259};
1153 1260
1154void *lme2510_exit_int(struct dvb_usb_device *d) 1261static void *lme2510_exit_int(struct dvb_usb_device *d)
1155{ 1262{
1156 struct lme2510_state *st = d->priv; 1263 struct lme2510_state *st = d->priv;
1157 struct dvb_usb_adapter *adap = &d->adapter[0]; 1264 struct dvb_usb_adapter *adap = &d->adapter[0];
@@ -1178,7 +1285,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d)
1178 return buffer; 1285 return buffer;
1179} 1286}
1180 1287
1181void lme2510_exit(struct usb_interface *intf) 1288static void lme2510_exit(struct usb_interface *intf)
1182{ 1289{
1183 struct dvb_usb_device *d = usb_get_intfdata(intf); 1290 struct dvb_usb_device *d = usb_get_intfdata(intf);
1184 void *usb_buffer; 1291 void *usb_buffer;
@@ -1220,5 +1327,5 @@ module_exit(lme2510_module_exit);
1220 1327
1221MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 1328MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1222MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); 1329MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1223MODULE_VERSION("1.80"); 1330MODULE_VERSION("1.86");
1224MODULE_LICENSE("GPL"); 1331MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h
index e6af16c1e3e5..ab21e2ef53fa 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.h
+++ b/drivers/media/dvb/dvb-usb/lmedm04.h
@@ -40,6 +40,7 @@
40*/ 40*/
41#define LME_ST_ON_W {0x06, 0x00} 41#define LME_ST_ON_W {0x06, 0x00}
42#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0} 42#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
43#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
43 44
44/* LNB Voltage 45/* LNB Voltage
45 * 07 XX XX 46 * 07 XX XX
@@ -108,14 +109,14 @@ static u8 s7395_inittab[] = {
108 0x3d, 0x30, 109 0x3d, 0x30,
109 0x40, 0x63, 110 0x40, 0x63,
110 0x41, 0x04, 111 0x41, 0x04,
111 0x42, 0x60, 112 0x42, 0x20,
112 0x43, 0x00, 113 0x43, 0x00,
113 0x44, 0x00, 114 0x44, 0x00,
114 0x45, 0x00, 115 0x45, 0x00,
115 0x46, 0x00, 116 0x46, 0x00,
116 0x47, 0x00, 117 0x47, 0x00,
117 0x4a, 0x00, 118 0x4a, 0x00,
118 0x50, 0x12, 119 0x50, 0x10,
119 0x51, 0x36, 120 0x51, 0x36,
120 0x52, 0x21, 121 0x52, 0x21,
121 0x53, 0x94, 122 0x53, 0x94,
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index da9dc91ce910..9456792f219b 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -134,13 +134,17 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
134{ 134{
135 struct m920x_state *m = d->priv; 135 struct m920x_state *m = d->priv;
136 int i, ret = 0; 136 int i, ret = 0;
137 u8 rc_state[2]; 137 u8 *rc_state;
138
139 rc_state = kmalloc(2, GFP_KERNEL);
140 if (!rc_state)
141 return -ENOMEM;
138 142
139 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) 143 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
140 goto unlock; 144 goto out;
141 145
142 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) 146 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
143 goto unlock; 147 goto out;
144 148
145 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) 149 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
146 if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) { 150 if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
@@ -149,7 +153,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
149 switch(rc_state[0]) { 153 switch(rc_state[0]) {
150 case 0x80: 154 case 0x80:
151 *state = REMOTE_NO_KEY_PRESSED; 155 *state = REMOTE_NO_KEY_PRESSED;
152 goto unlock; 156 goto out;
153 157
154 case 0x88: /* framing error or "invalid code" */ 158 case 0x88: /* framing error or "invalid code" */
155 case 0x99: 159 case 0x99:
@@ -157,7 +161,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
157 case 0xd8: 161 case 0xd8:
158 *state = REMOTE_NO_KEY_PRESSED; 162 *state = REMOTE_NO_KEY_PRESSED;
159 m->rep_count = 0; 163 m->rep_count = 0;
160 goto unlock; 164 goto out;
161 165
162 case 0x93: 166 case 0x93:
163 case 0x92: 167 case 0x92:
@@ -165,7 +169,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
165 case 0x82: 169 case 0x82:
166 m->rep_count = 0; 170 m->rep_count = 0;
167 *state = REMOTE_KEY_PRESSED; 171 *state = REMOTE_KEY_PRESSED;
168 goto unlock; 172 goto out;
169 173
170 case 0x91: 174 case 0x91:
171 case 0x81: /* pinnacle PCTV310e */ 175 case 0x81: /* pinnacle PCTV310e */
@@ -174,12 +178,12 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
174 *state = REMOTE_KEY_REPEAT; 178 *state = REMOTE_KEY_REPEAT;
175 else 179 else
176 *state = REMOTE_NO_KEY_PRESSED; 180 *state = REMOTE_NO_KEY_PRESSED;
177 goto unlock; 181 goto out;
178 182
179 default: 183 default:
180 deb("Unexpected rc state %02x\n", rc_state[0]); 184 deb("Unexpected rc state %02x\n", rc_state[0]);
181 *state = REMOTE_NO_KEY_PRESSED; 185 *state = REMOTE_NO_KEY_PRESSED;
182 goto unlock; 186 goto out;
183 } 187 }
184 } 188 }
185 189
@@ -188,8 +192,8 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
188 192
189 *state = REMOTE_NO_KEY_PRESSED; 193 *state = REMOTE_NO_KEY_PRESSED;
190 194
191 unlock: 195 out:
192 196 kfree(rc_state);
193 return ret; 197 return ret;
194} 198}
195 199
@@ -339,13 +343,19 @@ static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, in
339static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw) 343static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
340{ 344{
341 u16 value, index, size; 345 u16 value, index, size;
342 u8 read[4], *buff; 346 u8 *read, *buff;
343 int i, pass, ret = 0; 347 int i, pass, ret = 0;
344 348
345 buff = kmalloc(65536, GFP_KERNEL); 349 buff = kmalloc(65536, GFP_KERNEL);
346 if (buff == NULL) 350 if (buff == NULL)
347 return -ENOMEM; 351 return -ENOMEM;
348 352
353 read = kmalloc(4, GFP_KERNEL);
354 if (!read) {
355 kfree(buff);
356 return -ENOMEM;
357 }
358
349 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) 359 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
350 goto done; 360 goto done;
351 deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]); 361 deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
@@ -396,6 +406,7 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar
396 deb("firmware uploaded!\n"); 406 deb("firmware uploaded!\n");
397 407
398 done: 408 done:
409 kfree(read);
399 kfree(buff); 410 kfree(buff);
400 411
401 return ret; 412 return ret;
@@ -632,9 +643,9 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = {
632 { 0x16, KEY_POWER }, 643 { 0x16, KEY_POWER },
633 { 0x17, KEY_FAVORITES }, 644 { 0x17, KEY_FAVORITES },
634 { 0x0f, KEY_TEXT }, 645 { 0x0f, KEY_TEXT },
635 { 0x48, KEY_MEDIA }, /* preview */ 646 { 0x48, KEY_PROGRAM }, /* preview */
636 { 0x1c, KEY_EPG }, 647 { 0x1c, KEY_EPG },
637 { 0x04, KEY_LIST }, /* record list */ 648 { 0x04, KEY_LIST }, /* record list */
638 { 0x03, KEY_1 }, 649 { 0x03, KEY_1 },
639 { 0x01, KEY_2 }, 650 { 0x01, KEY_2 },
640 { 0x06, KEY_3 }, 651 { 0x06, KEY_3 },
@@ -674,14 +685,14 @@ static struct rc_map_table rc_map_pinnacle310e_table[] = {
674 { 0x0e, KEY_MUTE }, 685 { 0x0e, KEY_MUTE },
675/* { 0x49, KEY_LR }, */ /* L/R */ 686/* { 0x49, KEY_LR }, */ /* L/R */
676 { 0x07, KEY_SLEEP }, /* Hibernate */ 687 { 0x07, KEY_SLEEP }, /* Hibernate */
677 { 0x08, KEY_MEDIA }, /* A/V */ 688 { 0x08, KEY_VIDEO }, /* A/V */
678 { 0x0e, KEY_MENU }, /* Recall */ 689 { 0x0e, KEY_MENU }, /* Recall */
679 { 0x45, KEY_ZOOMIN }, 690 { 0x45, KEY_ZOOMIN },
680 { 0x46, KEY_ZOOMOUT }, 691 { 0x46, KEY_ZOOMOUT },
681 { 0x18, KEY_TV }, /* Red */ 692 { 0x18, KEY_RED }, /* Red */
682 { 0x53, KEY_VCR }, /* Green */ 693 { 0x53, KEY_GREEN }, /* Green */
683 { 0x5e, KEY_SAT }, /* Yellow */ 694 { 0x5e, KEY_YELLOW }, /* Yellow */
684 { 0x5f, KEY_PLAYER }, /* Blue */ 695 { 0x5f, KEY_BLUE }, /* Blue */
685}; 696};
686 697
687/* DVB USB Driver stuff */ 698/* DVB USB Driver stuff */
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 9d3cd2de46fc..bc350e982b72 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -47,7 +47,7 @@ static struct rc_map_table rc_map_haupp_table[] = {
47 { 0x1e17, KEY_RIGHT }, 47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO }, 48 { 0x1e18, KEY_VIDEO },
49 { 0x1e19, KEY_AUDIO }, 49 { 0x1e19, KEY_AUDIO },
50 { 0x1e1a, KEY_MEDIA }, 50 { 0x1e1a, KEY_IMAGES },
51 { 0x1e1b, KEY_EPG }, 51 { 0x1e1b, KEY_EPG },
52 { 0x1e1c, KEY_TV }, 52 { 0x1e1c, KEY_TV },
53 { 0x1e1e, KEY_NEXT }, 53 { 0x1e1e, KEY_NEXT },
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 7e569f4dd80b..2e4fab7215f5 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -53,27 +53,36 @@ static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
53 u8 * data, u16 len, int flags) 53 u8 * data, u16 len, int flags)
54{ 54{
55 int ret; 55 int ret;
56 u8 r; 56 u8 tmp;
57 u8 u8buf[len]; 57 u8 *buf;
58
59 unsigned int pipe = (flags == OPERA_READ_MSG) ? 58 unsigned int pipe = (flags == OPERA_READ_MSG) ?
60 usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0); 59 usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
61 u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; 60 u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
62 61
62 buf = kmalloc(len, GFP_KERNEL);
63 if (!buf)
64 return -ENOMEM;
65
63 if (flags == OPERA_WRITE_MSG) 66 if (flags == OPERA_WRITE_MSG)
64 memcpy(u8buf, data, len); 67 memcpy(buf, data, len);
65 ret = 68 ret = usb_control_msg(dev, pipe, request,
66 usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, 69 request_type | USB_TYPE_VENDOR, value, 0x0,
67 value, 0x0, u8buf, len, 2000); 70 buf, len, 2000);
68 71
69 if (request == OPERA_TUNER_REQ) { 72 if (request == OPERA_TUNER_REQ) {
73 tmp = buf[0];
70 if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 74 if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
71 OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR, 75 OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
72 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08) 76 0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
73 return 0; 77 ret = 0;
78 goto out;
79 }
80 buf[0] = tmp;
74 } 81 }
75 if (flags == OPERA_READ_MSG) 82 if (flags == OPERA_READ_MSG)
76 memcpy(data, u8buf, len); 83 memcpy(data, buf, len);
84out:
85 kfree(buf);
77 return ret; 86 return ret;
78} 87}
79 88
@@ -189,7 +198,7 @@ static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
189static u8 opera1_inittab[] = { 198static u8 opera1_inittab[] = {
190 0x00, 0xa1, 199 0x00, 0xa1,
191 0x01, 0x15, 200 0x01, 0x15,
192 0x02, 0x00, 201 0x02, 0x30,
193 0x03, 0x00, 202 0x03, 0x00,
194 0x04, 0x7d, 203 0x04, 0x7d,
195 0x05, 0x05, 204 0x05, 0x05,
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index ccc7e4452664..2bb8d4cc8d88 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -41,14 +41,23 @@ struct vp702x_fe_state {
41 41
42static int vp702x_fe_refresh_state(struct vp702x_fe_state *st) 42static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
43{ 43{
44 u8 buf[10]; 44 struct vp702x_device_state *dst = st->d->priv;
45 if (time_after(jiffies,st->next_status_check)) { 45 u8 *buf;
46 vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10);
47 46
47 if (time_after(jiffies, st->next_status_check)) {
48 mutex_lock(&dst->buf_mutex);
49 buf = dst->buf;
50
51 vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
48 st->lock = buf[4]; 52 st->lock = buf[4];
49 vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1);
50 vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1);
51 53
54 vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
55 st->snr = buf[0];
56
57 vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
58 st->sig = buf[0];
59
60 mutex_unlock(&dst->buf_mutex);
52 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; 61 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
53 } 62 }
54 return 0; 63 return 0;
@@ -130,11 +139,17 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
130 struct dvb_frontend_parameters *fep) 139 struct dvb_frontend_parameters *fep)
131{ 140{
132 struct vp702x_fe_state *st = fe->demodulator_priv; 141 struct vp702x_fe_state *st = fe->demodulator_priv;
142 struct vp702x_device_state *dst = st->d->priv;
133 u32 freq = fep->frequency/1000; 143 u32 freq = fep->frequency/1000;
134 /*CalFrequency*/ 144 /*CalFrequency*/
135/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */ 145/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
136 u64 sr; 146 u64 sr;
137 u8 cmd[8] = { 0 },ibuf[10]; 147 u8 *cmd;
148
149 mutex_lock(&dst->buf_mutex);
150
151 cmd = dst->buf;
152 memset(cmd, 0, 10);
138 153
139 cmd[0] = (freq >> 8) & 0x7f; 154 cmd[0] = (freq >> 8) & 0x7f;
140 cmd[1] = freq & 0xff; 155 cmd[1] = freq & 0xff;
@@ -170,13 +185,15 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
170 st->status_check_interval = 250; 185 st->status_check_interval = 250;
171 st->next_status_check = jiffies; 186 st->next_status_check = jiffies;
172 187
173 vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); 188 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
174 189
175 if (ibuf[2] == 0 && ibuf[3] == 0) 190 if (cmd[2] == 0 && cmd[3] == 0)
176 deb_fe("tuning failed.\n"); 191 deb_fe("tuning failed.\n");
177 else 192 else
178 deb_fe("tuning succeeded.\n"); 193 deb_fe("tuning succeeded.\n");
179 194
195 mutex_unlock(&dst->buf_mutex);
196
180 return 0; 197 return 0;
181} 198}
182 199
@@ -204,27 +221,32 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
204static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, 221static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
205 struct dvb_diseqc_master_cmd *m) 222 struct dvb_diseqc_master_cmd *m)
206{ 223{
224 u8 *cmd;
207 struct vp702x_fe_state *st = fe->demodulator_priv; 225 struct vp702x_fe_state *st = fe->demodulator_priv;
208 u8 cmd[8],ibuf[10]; 226 struct vp702x_device_state *dst = st->d->priv;
209 memset(cmd,0,8);
210 227
211 deb_fe("%s\n",__func__); 228 deb_fe("%s\n",__func__);
212 229
213 if (m->msg_len > 4) 230 if (m->msg_len > 4)
214 return -EINVAL; 231 return -EINVAL;
215 232
233 mutex_lock(&dst->buf_mutex);
234
235 cmd = dst->buf;
216 cmd[1] = SET_DISEQC_CMD; 236 cmd[1] = SET_DISEQC_CMD;
217 cmd[2] = m->msg_len; 237 cmd[2] = m->msg_len;
218 memcpy(&cmd[3], m->msg, m->msg_len); 238 memcpy(&cmd[3], m->msg, m->msg_len);
219 cmd[7] = vp702x_chksum(cmd,0,7); 239 cmd[7] = vp702x_chksum(cmd, 0, 7);
220 240
221 vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); 241 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
222 242
223 if (ibuf[2] == 0 && ibuf[3] == 0) 243 if (cmd[2] == 0 && cmd[3] == 0)
224 deb_fe("diseqc cmd failed.\n"); 244 deb_fe("diseqc cmd failed.\n");
225 else 245 else
226 deb_fe("diseqc cmd succeeded.\n"); 246 deb_fe("diseqc cmd succeeded.\n");
227 247
248 mutex_unlock(&dst->buf_mutex);
249
228 return 0; 250 return 0;
229} 251}
230 252
@@ -237,7 +259,9 @@ static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd
237static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) 259static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
238{ 260{
239 struct vp702x_fe_state *st = fe->demodulator_priv; 261 struct vp702x_fe_state *st = fe->demodulator_priv;
240 u8 ibuf[10]; 262 struct vp702x_device_state *dst = st->d->priv;
263 u8 *buf;
264
241 deb_fe("%s\n",__func__); 265 deb_fe("%s\n",__func__);
242 266
243 st->tone_mode = tone; 267 st->tone_mode = tone;
@@ -247,14 +271,21 @@ static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
247 else 271 else
248 st->lnb_buf[2] = 0x00; 272 st->lnb_buf[2] = 0x00;
249 273
250 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); 274 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
275
276 mutex_lock(&dst->buf_mutex);
277
278 buf = dst->buf;
279 memcpy(buf, st->lnb_buf, 8);
251 280
252 vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); 281 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
253 if (ibuf[2] == 0 && ibuf[3] == 0) 282 if (buf[2] == 0 && buf[3] == 0)
254 deb_fe("set_tone cmd failed.\n"); 283 deb_fe("set_tone cmd failed.\n");
255 else 284 else
256 deb_fe("set_tone cmd succeeded.\n"); 285 deb_fe("set_tone cmd succeeded.\n");
257 286
287 mutex_unlock(&dst->buf_mutex);
288
258 return 0; 289 return 0;
259} 290}
260 291
@@ -262,7 +293,8 @@ static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
262 voltage) 293 voltage)
263{ 294{
264 struct vp702x_fe_state *st = fe->demodulator_priv; 295 struct vp702x_fe_state *st = fe->demodulator_priv;
265 u8 ibuf[10]; 296 struct vp702x_device_state *dst = st->d->priv;
297 u8 *buf;
266 deb_fe("%s\n",__func__); 298 deb_fe("%s\n",__func__);
267 299
268 st->voltage = voltage; 300 st->voltage = voltage;
@@ -272,14 +304,20 @@ static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
272 else 304 else
273 st->lnb_buf[4] = 0x00; 305 st->lnb_buf[4] = 0x00;
274 306
275 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); 307 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
308
309 mutex_lock(&dst->buf_mutex);
310
311 buf = dst->buf;
312 memcpy(buf, st->lnb_buf, 8);
276 313
277 vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); 314 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
278 if (ibuf[2] == 0 && ibuf[3] == 0) 315 if (buf[2] == 0 && buf[3] == 0)
279 deb_fe("set_voltage cmd failed.\n"); 316 deb_fe("set_voltage cmd failed.\n");
280 else 317 else
281 deb_fe("set_voltage cmd succeeded.\n"); 318 deb_fe("set_voltage cmd succeeded.\n");
282 319
320 mutex_unlock(&dst->buf_mutex);
283 return 0; 321 return 0;
284} 322}
285 323
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index 7890e75600df..54355f84a98f 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -15,6 +15,7 @@
15 * see Documentation/dvb/README.dvb-usb for more information 15 * see Documentation/dvb/README.dvb-usb for more information
16 */ 16 */
17#include "vp702x.h" 17#include "vp702x.h"
18#include <linux/mutex.h>
18 19
19/* debug */ 20/* debug */
20int dvb_usb_vp702x_debug; 21int dvb_usb_vp702x_debug;
@@ -23,27 +24,23 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DV
23 24
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25 26
26struct vp702x_state { 27struct vp702x_adapter_state {
27 int pid_filter_count; 28 int pid_filter_count;
28 int pid_filter_can_bypass; 29 int pid_filter_can_bypass;
29 u8 pid_filter_state; 30 u8 pid_filter_state;
30}; 31};
31 32
32struct vp702x_device_state { 33static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
33 u8 power_state; 34 u16 value, u16 index, u8 *b, int blen)
34};
35
36/* check for mutex FIXME */
37int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
38{ 35{
39 int ret = -1; 36 int ret;
40 37
41 ret = usb_control_msg(d->udev, 38 ret = usb_control_msg(d->udev,
42 usb_rcvctrlpipe(d->udev,0), 39 usb_rcvctrlpipe(d->udev, 0),
43 req, 40 req,
44 USB_TYPE_VENDOR | USB_DIR_IN, 41 USB_TYPE_VENDOR | USB_DIR_IN,
45 value,index,b,blen, 42 value, index, b, blen,
46 2000); 43 2000);
47 44
48 if (ret < 0) { 45 if (ret < 0) {
49 warn("usb in operation failed. (%d)", ret); 46 warn("usb in operation failed. (%d)", ret);
@@ -58,8 +55,20 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
58 return ret; 55 return ret;
59} 56}
60 57
61static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, 58int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
62 u16 index, u8 *b, int blen) 59 u16 index, u8 *b, int blen)
60{
61 int ret;
62
63 mutex_lock(&d->usb_mutex);
64 ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
65 mutex_unlock(&d->usb_mutex);
66
67 return ret;
68}
69
70int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
71 u16 index, u8 *b, int blen)
63{ 72{
64 int ret; 73 int ret;
65 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); 74 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
@@ -77,6 +86,18 @@ static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
77 return 0; 86 return 0;
78} 87}
79 88
89int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
90 u16 index, u8 *b, int blen)
91{
92 int ret;
93
94 mutex_lock(&d->usb_mutex);
95 ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
96 mutex_unlock(&d->usb_mutex);
97
98 return ret;
99}
100
80int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec) 101int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
81{ 102{
82 int ret; 103 int ret;
@@ -84,50 +105,93 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
84 if ((ret = mutex_lock_interruptible(&d->usb_mutex))) 105 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
85 return ret; 106 return ret;
86 107
87 ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen); 108 ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
88 msleep(msec); 109 msleep(msec);
89 ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); 110 ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
90 111
91 mutex_unlock(&d->usb_mutex); 112 mutex_unlock(&d->usb_mutex);
92
93 return ret; 113 return ret;
94} 114}
95 115
96static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, 116static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
97 int olen, u8 *i, int ilen, int msec) 117 int olen, u8 *i, int ilen, int msec)
98{ 118{
99 u8 bout[olen+2]; 119 struct vp702x_device_state *st = d->priv;
100 u8 bin[ilen+1];
101 int ret = 0; 120 int ret = 0;
121 u8 *buf;
122 int buflen = max(olen + 2, ilen + 1);
123
124 ret = mutex_lock_interruptible(&st->buf_mutex);
125 if (ret < 0)
126 return ret;
127
128 if (buflen > st->buf_len) {
129 buf = kmalloc(buflen, GFP_KERNEL);
130 if (!buf) {
131 mutex_unlock(&st->buf_mutex);
132 return -ENOMEM;
133 }
134 info("successfully reallocated a bigger buffer");
135 kfree(st->buf);
136 st->buf = buf;
137 st->buf_len = buflen;
138 } else {
139 buf = st->buf;
140 }
102 141
103 bout[0] = 0x00; 142 buf[0] = 0x00;
104 bout[1] = cmd; 143 buf[1] = cmd;
105 memcpy(&bout[2],o,olen); 144 memcpy(&buf[2], o, olen);
106 145
107 ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec); 146 ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
108 147
109 if (ret == 0) 148 if (ret == 0)
110 memcpy(i,&bin[1],ilen); 149 memcpy(i, &buf[1], ilen);
150 mutex_unlock(&st->buf_mutex);
111 151
112 return ret; 152 return ret;
113} 153}
114 154
115static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass) 155static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
116{ 156{
117 u8 buf[16] = { 0 }; 157 int ret;
118 return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16); 158 struct vp702x_device_state *st = adap->dev->priv;
159 u8 *buf;
160
161 mutex_lock(&st->buf_mutex);
162
163 buf = st->buf;
164 memset(buf, 0, 16);
165
166 ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
167 0, buf, 16);
168 mutex_unlock(&st->buf_mutex);
169 return ret;
119} 170}
120 171
121static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state) 172static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
122{ 173{
123 u8 buf[16] = { 0 }; 174 int ret;
124 return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16); 175 struct vp702x_device_state *st = adap->dev->priv;
176 u8 *buf;
177
178 mutex_lock(&st->buf_mutex);
179
180 buf = st->buf;
181 memset(buf, 0, 16);
182 ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
183 0, buf, 16);
184
185 mutex_unlock(&st->buf_mutex);
186
187 return ret;
125} 188}
126 189
127static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff) 190static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
128{ 191{
129 struct vp702x_state *st = adap->priv; 192 struct vp702x_adapter_state *st = adap->priv;
130 u8 buf[16] = { 0 }; 193 struct vp702x_device_state *dst = adap->dev->priv;
194 u8 *buf;
131 195
132 if (onoff) 196 if (onoff)
133 st->pid_filter_state |= (1 << id); 197 st->pid_filter_state |= (1 << id);
@@ -139,32 +203,45 @@ static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onof
139 id = 0x10 + id*2; 203 id = 0x10 + id*2;
140 204
141 vp702x_set_pld_state(adap, st->pid_filter_state); 205 vp702x_set_pld_state(adap, st->pid_filter_state);
206
207 mutex_lock(&dst->buf_mutex);
208
209 buf = dst->buf;
210 memset(buf, 0, 16);
142 vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16); 211 vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
143 vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16); 212 vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16);
213
214 mutex_unlock(&dst->buf_mutex);
215
144 return 0; 216 return 0;
145} 217}
146 218
147 219
148static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap) 220static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
149{ 221{
150 struct vp702x_state *st = adap->priv; 222 struct vp702x_adapter_state *st = adap->priv;
223 struct vp702x_device_state *dst = adap->dev->priv;
151 int i; 224 int i;
152 u8 b[10] = { 0 }; 225 u8 *b;
153 226
154 st->pid_filter_count = 8; 227 st->pid_filter_count = 8;
155 st->pid_filter_can_bypass = 1; 228 st->pid_filter_can_bypass = 1;
156 st->pid_filter_state = 0x00; 229 st->pid_filter_state = 0x00;
157 230
158 vp702x_set_pld_mode(adap, 1); // bypass 231 vp702x_set_pld_mode(adap, 1); /* bypass */
159 232
160 for (i = 0; i < st->pid_filter_count; i++) 233 for (i = 0; i < st->pid_filter_count; i++)
161 vp702x_set_pid(adap, 0xffff, i, 1); 234 vp702x_set_pid(adap, 0xffff, i, 1);
162 235
236 mutex_lock(&dst->buf_mutex);
237 b = dst->buf;
238 memset(b, 0, 10);
163 vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10); 239 vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
164 vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10); 240 vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
165 vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10); 241 vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
242 mutex_unlock(&dst->buf_mutex);
243 /*vp702x_set_pld_mode(d, 0); // filter */
166 244
167 //vp702x_set_pld_mode(d, 0); // filter
168 return 0; 245 return 0;
169} 246}
170 247
@@ -182,18 +259,23 @@ static struct rc_map_table rc_map_vp702x_table[] = {
182/* remote control stuff (does not work with my box) */ 259/* remote control stuff (does not work with my box) */
183static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 260static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
184{ 261{
185 u8 key[10]; 262 u8 *key;
186 int i; 263 int i;
187 264
188/* remove the following return to enabled remote querying */ 265/* remove the following return to enabled remote querying */
189 return 0; 266 return 0;
190 267
268 key = kmalloc(10, GFP_KERNEL);
269 if (!key)
270 return -ENOMEM;
271
191 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); 272 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
192 273
193 deb_rc("remote query key: %x %d\n",key[1],key[1]); 274 deb_rc("remote query key: %x %d\n",key[1],key[1]);
194 275
195 if (key[1] == 0x44) { 276 if (key[1] == 0x44) {
196 *state = REMOTE_NO_KEY_PRESSED; 277 *state = REMOTE_NO_KEY_PRESSED;
278 kfree(key);
197 return 0; 279 return 0;
198 } 280 }
199 281
@@ -203,15 +285,23 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
203 *event = rc_map_vp702x_table[i].keycode; 285 *event = rc_map_vp702x_table[i].keycode;
204 break; 286 break;
205 } 287 }
288 kfree(key);
206 return 0; 289 return 0;
207} 290}
208 291
209 292
210static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) 293static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
211{ 294{
212 u8 i; 295 u8 i, *buf;
296 struct vp702x_device_state *st = d->priv;
297
298 mutex_lock(&st->buf_mutex);
299 buf = st->buf;
213 for (i = 6; i < 12; i++) 300 for (i = 6; i < 12; i++)
214 vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1); 301 vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
302
303 memcpy(mac, buf, 6);
304 mutex_unlock(&st->buf_mutex);
215 return 0; 305 return 0;
216} 306}
217 307
@@ -221,7 +311,8 @@ static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
221 311
222 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0); 312 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
223 313
224 if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10)) 314 if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
315 buf, 10, 10))
225 return -EIO; 316 return -EIO;
226 317
227 buf[9] = '\0'; 318 buf[9] = '\0';
@@ -240,8 +331,38 @@ static struct dvb_usb_device_properties vp702x_properties;
240static int vp702x_usb_probe(struct usb_interface *intf, 331static int vp702x_usb_probe(struct usb_interface *intf,
241 const struct usb_device_id *id) 332 const struct usb_device_id *id)
242{ 333{
243 return dvb_usb_device_init(intf, &vp702x_properties, 334 struct dvb_usb_device *d;
244 THIS_MODULE, NULL, adapter_nr); 335 struct vp702x_device_state *st;
336 int ret;
337
338 ret = dvb_usb_device_init(intf, &vp702x_properties,
339 THIS_MODULE, &d, adapter_nr);
340 if (ret)
341 goto out;
342
343 st = d->priv;
344 st->buf_len = 16;
345 st->buf = kmalloc(st->buf_len, GFP_KERNEL);
346 if (!st->buf) {
347 ret = -ENOMEM;
348 dvb_usb_device_exit(intf);
349 goto out;
350 }
351 mutex_init(&st->buf_mutex);
352
353out:
354 return ret;
355
356}
357
358static void vp702x_usb_disconnect(struct usb_interface *intf)
359{
360 struct dvb_usb_device *d = usb_get_intfdata(intf);
361 struct vp702x_device_state *st = d->priv;
362 mutex_lock(&st->buf_mutex);
363 kfree(st->buf);
364 mutex_unlock(&st->buf_mutex);
365 dvb_usb_device_exit(intf);
245} 366}
246 367
247static struct usb_device_id vp702x_usb_table [] = { 368static struct usb_device_id vp702x_usb_table [] = {
@@ -278,7 +399,7 @@ static struct dvb_usb_device_properties vp702x_properties = {
278 } 399 }
279 } 400 }
280 }, 401 },
281 .size_of_priv = sizeof(struct vp702x_state), 402 .size_of_priv = sizeof(struct vp702x_adapter_state),
282 } 403 }
283 }, 404 },
284 .read_mac_address = vp702x_read_mac_addr, 405 .read_mac_address = vp702x_read_mac_addr,
@@ -307,9 +428,9 @@ static struct dvb_usb_device_properties vp702x_properties = {
307/* usb specific object needed to register this driver with the usb subsystem */ 428/* usb specific object needed to register this driver with the usb subsystem */
308static struct usb_driver vp702x_usb_driver = { 429static struct usb_driver vp702x_usb_driver = {
309 .name = "dvb_usb_vp702x", 430 .name = "dvb_usb_vp702x",
310 .probe = vp702x_usb_probe, 431 .probe = vp702x_usb_probe,
311 .disconnect = dvb_usb_device_exit, 432 .disconnect = vp702x_usb_disconnect,
312 .id_table = vp702x_usb_table, 433 .id_table = vp702x_usb_table,
313}; 434};
314 435
315/* module stuff */ 436/* module stuff */
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
index c2f97f96c21f..20b90055e7ac 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.h
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -98,6 +98,13 @@ extern int dvb_usb_vp702x_debug;
98#define RESET_TUNER 0xBE 98#define RESET_TUNER 0xBE
99/* IN i: 0, v: 0, no extra buffer */ 99/* IN i: 0, v: 0, no extra buffer */
100 100
101struct vp702x_device_state {
102 struct mutex buf_mutex;
103 int buf_len;
104 u8 *buf;
105};
106
107
101extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); 108extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
102 109
103extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); 110extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index ab0ab3c35e80..3db89e3cb0bb 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -28,9 +28,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
28int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec) 28int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
29{ 29{
30 int ret = 0; 30 int ret = 0;
31 u8 inbuf[12] = { 0 }, outbuf[20] = { 0 }; 31 u8 *buf = d->priv;
32 32
33 outbuf[0] = cmd; 33 buf[0] = cmd;
34 34
35 if (outlen > 19) 35 if (outlen > 19)
36 outlen = 19; 36 outlen = 19;
@@ -38,19 +38,21 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
38 if (inlen > 11) 38 if (inlen > 11)
39 inlen = 11; 39 inlen = 11;
40 40
41 ret = mutex_lock_interruptible(&d->usb_mutex);
42 if (ret)
43 return ret;
44
41 if (out != NULL && outlen > 0) 45 if (out != NULL && outlen > 0)
42 memcpy(&outbuf[1], out, outlen); 46 memcpy(&buf[1], out, outlen);
43 47
44 deb_xfer("out buffer: "); 48 deb_xfer("out buffer: ");
45 debug_dump(outbuf,outlen+1,deb_xfer); 49 debug_dump(buf, outlen+1, deb_xfer);
46 50
47 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
48 return ret;
49 51
50 if (usb_control_msg(d->udev, 52 if (usb_control_msg(d->udev,
51 usb_sndctrlpipe(d->udev,0), 53 usb_sndctrlpipe(d->udev,0),
52 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, 54 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
53 outbuf, 20, 2000) != 20) { 55 buf, 20, 2000) != 20) {
54 err("USB control message 'out' went wrong."); 56 err("USB control message 'out' went wrong.");
55 ret = -EIO; 57 ret = -EIO;
56 goto unlock; 58 goto unlock;
@@ -61,17 +63,17 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
61 if (usb_control_msg(d->udev, 63 if (usb_control_msg(d->udev,
62 usb_rcvctrlpipe(d->udev,0), 64 usb_rcvctrlpipe(d->udev,0),
63 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, 65 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
64 inbuf, 12, 2000) != 12) { 66 buf, 12, 2000) != 12) {
65 err("USB control message 'in' went wrong."); 67 err("USB control message 'in' went wrong.");
66 ret = -EIO; 68 ret = -EIO;
67 goto unlock; 69 goto unlock;
68 } 70 }
69 71
70 deb_xfer("in buffer: "); 72 deb_xfer("in buffer: ");
71 debug_dump(inbuf,12,deb_xfer); 73 debug_dump(buf, 12, deb_xfer);
72 74
73 if (in != NULL && inlen > 0) 75 if (in != NULL && inlen > 0)
74 memcpy(in,&inbuf[1],inlen); 76 memcpy(in, &buf[1], inlen);
75 77
76unlock: 78unlock:
77 mutex_unlock(&d->usb_mutex); 79 mutex_unlock(&d->usb_mutex);
@@ -222,8 +224,26 @@ static struct dvb_usb_device_properties vp7045_properties;
222static int vp7045_usb_probe(struct usb_interface *intf, 224static int vp7045_usb_probe(struct usb_interface *intf,
223 const struct usb_device_id *id) 225 const struct usb_device_id *id)
224{ 226{
225 return dvb_usb_device_init(intf, &vp7045_properties, 227 struct dvb_usb_device *d;
226 THIS_MODULE, NULL, adapter_nr); 228 int ret = dvb_usb_device_init(intf, &vp7045_properties,
229 THIS_MODULE, &d, adapter_nr);
230 if (ret)
231 return ret;
232
233 d->priv = kmalloc(20, GFP_KERNEL);
234 if (!d->priv) {
235 dvb_usb_device_exit(intf);
236 return -ENOMEM;
237 }
238
239 return ret;
240}
241
242static void vp7045_usb_disconnect(struct usb_interface *intf)
243{
244 struct dvb_usb_device *d = usb_get_intfdata(intf);
245 kfree(d->priv);
246 dvb_usb_device_exit(intf);
227} 247}
228 248
229static struct usb_device_id vp7045_usb_table [] = { 249static struct usb_device_id vp7045_usb_table [] = {
@@ -238,6 +258,7 @@ MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
238static struct dvb_usb_device_properties vp7045_properties = { 258static struct dvb_usb_device_properties vp7045_properties = {
239 .usb_ctrl = CYPRESS_FX2, 259 .usb_ctrl = CYPRESS_FX2,
240 .firmware = "dvb-usb-vp7045-01.fw", 260 .firmware = "dvb-usb-vp7045-01.fw",
261 .size_of_priv = sizeof(u8 *),
241 262
242 .num_adapters = 1, 263 .num_adapters = 1,
243 .adapter = { 264 .adapter = {
@@ -284,7 +305,7 @@ static struct dvb_usb_device_properties vp7045_properties = {
284static struct usb_driver vp7045_usb_driver = { 305static struct usb_driver vp7045_usb_driver = {
285 .name = "dvb_usb_vp7045", 306 .name = "dvb_usb_vp7045",
286 .probe = vp7045_usb_probe, 307 .probe = vp7045_usb_probe,
287 .disconnect = dvb_usb_device_exit, 308 .disconnect = vp7045_usb_disconnect,
288 .id_table = vp7045_usb_table, 309 .id_table = vp7045_usb_table,
289}; 310};
290 311
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 83093d1f4f74..44b816f2601e 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -263,18 +263,16 @@ config DVB_S5H1432
263 help 263 help
264 A DVB-T tuner module. Say Y when you want to support this frontend. 264 A DVB-T tuner module. Say Y when you want to support this frontend.
265 265
266config DVB_DRX397XD 266config DVB_DRXD
267 tristate "Micronas DRX3975D/DRX3977D based" 267 tristate "Micronas DRXD driver"
268 depends on DVB_CORE && I2C 268 depends on DVB_CORE && I2C
269 default m if DVB_FE_CUSTOMISE 269 default m if DVB_FE_CUSTOMISE
270 help 270 help
271 A DVB-T tuner module. Say Y when you want to support this frontend. 271 A DVB-T tuner module. Say Y when you want to support this frontend.
272 272
273 TODO: 273 Note: this driver was based on vendor driver reference code (released
274 This driver needs external firmware. Please use the command 274 under the GPL) as opposed to the existing drx397xd driver, which
275 "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to 275 was written via reverse engineering.
276 download/extract them, and then copy them to /usr/lib/hotplug/firmware
277 or /lib/firmware (depending on configuration of firmware hotplug).
278 276
279config DVB_L64781 277config DVB_L64781
280 tristate "LSI L64781" 278 tristate "LSI L64781"
@@ -385,6 +383,13 @@ config DVB_STV0367
385 help 383 help
386 A DVB-T/C tuner module. Say Y when you want to support this frontend. 384 A DVB-T/C tuner module. Say Y when you want to support this frontend.
387 385
386config DVB_CXD2820R
387 tristate "Sony CXD2820R"
388 depends on DVB_CORE && I2C
389 default m if DVB_FE_CUSTOMISE
390 help
391 Say Y when you want to support this frontend.
392
388comment "DVB-C (cable) frontends" 393comment "DVB-C (cable) frontends"
389 depends on DVB_CORE 394 depends on DVB_CORE
390 395
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 3b0c4bdc4b2b..2f3a6f736d64 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -8,6 +8,8 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
8stb0899-objs = stb0899_drv.o stb0899_algo.o 8stb0899-objs = stb0899_drv.o stb0899_algo.o
9stv0900-objs = stv0900_core.o stv0900_sw.o 9stv0900-objs = stv0900_core.o stv0900_sw.o
10au8522-objs = au8522_dig.o au8522_decoder.o 10au8522-objs = au8522_dig.o au8522_decoder.o
11drxd-objs = drxd_firm.o drxd_hard.o
12cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
11 13
12obj-$(CONFIG_DVB_PLL) += dvb-pll.o 14obj-$(CONFIG_DVB_PLL) += dvb-pll.o
13obj-$(CONFIG_DVB_STV0299) += stv0299.o 15obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -36,7 +38,7 @@ obj-$(CONFIG_DVB_ZL10036) += zl10036.o
36obj-$(CONFIG_DVB_ZL10039) += zl10039.o 38obj-$(CONFIG_DVB_ZL10039) += zl10039.o
37obj-$(CONFIG_DVB_ZL10353) += zl10353.o 39obj-$(CONFIG_DVB_ZL10353) += zl10353.o
38obj-$(CONFIG_DVB_CX22702) += cx22702.o 40obj-$(CONFIG_DVB_CX22702) += cx22702.o
39obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o 41obj-$(CONFIG_DVB_DRXD) += drxd.o
40obj-$(CONFIG_DVB_TDA10021) += tda10021.o 42obj-$(CONFIG_DVB_TDA10021) += tda10021.o
41obj-$(CONFIG_DVB_TDA10023) += tda10023.o 43obj-$(CONFIG_DVB_TDA10023) += tda10023.o
42obj-$(CONFIG_DVB_STV0297) += stv0297.o 44obj-$(CONFIG_DVB_STV0297) += stv0297.o
@@ -85,3 +87,5 @@ obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
85obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o 87obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
86obj-$(CONFIG_DVB_IX2505V) += ix2505v.o 88obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
87obj-$(CONFIG_DVB_STV0367) += stv0367.o 89obj-$(CONFIG_DVB_STV0367) += stv0367.o
90obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
91
diff --git a/drivers/media/dvb/frontends/bsbe1-d01a.h b/drivers/media/dvb/frontends/bsbe1-d01a.h
new file mode 100644
index 000000000000..7ed3c424178c
--- /dev/null
+++ b/drivers/media/dvb/frontends/bsbe1-d01a.h
@@ -0,0 +1,146 @@
1/*
2 * bsbe1-d01a.h - ALPS BSBE1-D01A tuner support
3 *
4 * Copyright (C) 2011 Oliver Endriss <o.endriss@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 *
23 *
24 * the project's page is at http://www.linuxtv.org
25 */
26
27#ifndef BSBE1_D01A_H
28#define BSBE1_D01A_H
29
30#include "stb6000.h"
31#include "stv0288.h"
32
33static u8 stv0288_bsbe1_d01a_inittab[] = {
34 0x01, 0x15,
35 0x02, 0x20,
36 0x09, 0x0,
37 0x0a, 0x4,
38 0x0b, 0x0,
39 0x0c, 0x0,
40 0x0d, 0x0,
41 0x0e, 0xd4,
42 0x0f, 0x30,
43 0x11, 0x80,
44 0x12, 0x03,
45 0x13, 0x48,
46 0x14, 0x84,
47 0x15, 0x45,
48 0x16, 0xb7,
49 0x17, 0x9c,
50 0x18, 0x0,
51 0x19, 0xa6,
52 0x1a, 0x88,
53 0x1b, 0x8f,
54 0x1c, 0xf0,
55 0x20, 0x0b,
56 0x21, 0x54,
57 0x22, 0x0,
58 0x23, 0x0,
59 0x2b, 0xff,
60 0x2c, 0xf7,
61 0x30, 0x0,
62 0x31, 0x1e,
63 0x32, 0x14,
64 0x33, 0x0f,
65 0x34, 0x09,
66 0x35, 0x0c,
67 0x36, 0x05,
68 0x37, 0x2f,
69 0x38, 0x16,
70 0x39, 0xbd,
71 0x3a, 0x03,
72 0x3b, 0x13,
73 0x3c, 0x11,
74 0x3d, 0x30,
75 0x40, 0x63,
76 0x41, 0x04,
77 0x42, 0x60,
78 0x43, 0x00,
79 0x44, 0x00,
80 0x45, 0x00,
81 0x46, 0x00,
82 0x47, 0x00,
83 0x4a, 0x00,
84 0x50, 0x10,
85 0x51, 0x36,
86 0x52, 0x09,
87 0x53, 0x94,
88 0x54, 0x62,
89 0x55, 0x29,
90 0x56, 0x64,
91 0x57, 0x2b,
92 0x58, 0x54,
93 0x59, 0x86,
94 0x5a, 0x0,
95 0x5b, 0x9b,
96 0x5c, 0x08,
97 0x5d, 0x7f,
98 0x5e, 0x0,
99 0x5f, 0xff,
100 0x70, 0x0,
101 0x71, 0x0,
102 0x72, 0x0,
103 0x74, 0x0,
104 0x75, 0x0,
105 0x76, 0x0,
106 0x81, 0x0,
107 0x82, 0x3f,
108 0x83, 0x3f,
109 0x84, 0x0,
110 0x85, 0x0,
111 0x88, 0x0,
112 0x89, 0x0,
113 0x8a, 0x0,
114 0x8b, 0x0,
115 0x8c, 0x0,
116 0x90, 0x0,
117 0x91, 0x0,
118 0x92, 0x0,
119 0x93, 0x0,
120 0x94, 0x1c,
121 0x97, 0x0,
122 0xa0, 0x48,
123 0xa1, 0x0,
124 0xb0, 0xb8,
125 0xb1, 0x3a,
126 0xb2, 0x10,
127 0xb3, 0x82,
128 0xb4, 0x80,
129 0xb5, 0x82,
130 0xb6, 0x82,
131 0xb7, 0x82,
132 0xb8, 0x20,
133 0xb9, 0x0,
134 0xf0, 0x0,
135 0xf1, 0x0,
136 0xf2, 0xc0,
137 0xff, 0xff,
138};
139
140static struct stv0288_config stv0288_bsbe1_d01a_config = {
141 .demod_address = 0x68,
142 .min_delay_ms = 100,
143 .inittab = stv0288_bsbe1_d01a_inittab,
144};
145
146#endif
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h
index 45a6dfd8ebb5..c480c839b302 100644
--- a/drivers/media/dvb/frontends/bsru6.h
+++ b/drivers/media/dvb/frontends/bsru6.h
@@ -27,7 +27,7 @@
27 27
28static u8 alps_bsru6_inittab[] = { 28static u8 alps_bsru6_inittab[] = {
29 0x01, 0x15, 29 0x01, 0x15,
30 0x02, 0x00, 30 0x02, 0x30,
31 0x03, 0x00, 31 0x03, 0x00,
32 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ 32 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
33 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ 33 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 2410d8b59b6b..95c6465b87a1 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -137,7 +137,7 @@ MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
137/* SNR measurements */ 137/* SNR measurements */
138static int esno_snr; 138static int esno_snr;
139module_param(esno_snr, int, 0644); 139module_param(esno_snr, int, 0644);
140MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\ 140MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
141 "1=ESNO(db * 10) (default:0)"); 141 "1=ESNO(db * 10) (default:0)");
142 142
143enum cmds { 143enum cmds {
@@ -566,7 +566,7 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
566{ 566{
567 struct cx24116_state *state = fe->demodulator_priv; 567 struct cx24116_state *state = fe->demodulator_priv;
568 struct cx24116_cmd cmd; 568 struct cx24116_cmd cmd;
569 int i, ret; 569 int i, ret, len, max, remaining;
570 unsigned char vers[4]; 570 unsigned char vers[4];
571 571
572 dprintk("%s\n", __func__); 572 dprintk("%s\n", __func__);
@@ -603,8 +603,21 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
603 cx24116_writereg(state, 0xF5, 0x00); 603 cx24116_writereg(state, 0xF5, 0x00);
604 cx24116_writereg(state, 0xF6, 0x00); 604 cx24116_writereg(state, 0xF6, 0x00);
605 605
606 /* write the entire firmware as one transaction */ 606 /* Split firmware to the max I2C write len and write.
607 cx24116_writeregN(state, 0xF7, fw->data, fw->size); 607 * Writes whole firmware as one write when i2c_wr_max is set to 0. */
608 if (state->config->i2c_wr_max)
609 max = state->config->i2c_wr_max;
610 else
611 max = INT_MAX; /* enough for 32k firmware */
612
613 for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
614 len = remaining;
615 if (len > max - 1)
616 len = max - 1;
617
618 cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
619 len);
620 }
608 621
609 cx24116_writereg(state, 0xF4, 0x10); 622 cx24116_writereg(state, 0xF4, 0x10);
610 cx24116_writereg(state, 0xF0, 0x00); 623 cx24116_writereg(state, 0xF0, 0x00);
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h
index b1b76b47a14c..7d90ab949c03 100644
--- a/drivers/media/dvb/frontends/cx24116.h
+++ b/drivers/media/dvb/frontends/cx24116.h
@@ -35,6 +35,9 @@ struct cx24116_config {
35 35
36 /* Need to set MPEG parameters */ 36 /* Need to set MPEG parameters */
37 u8 mpg_clk_pos_pol:0x02; 37 u8 mpg_clk_pos_pol:0x02;
38
39 /* max bytes I2C provider can write at once */
40 u16 i2c_wr_max;
38}; 41};
39 42
40#if defined(CONFIG_DVB_CX24116) || \ 43#if defined(CONFIG_DVB_CX24116) || \
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h
new file mode 100644
index 000000000000..ad17845123d9
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r.h
@@ -0,0 +1,118 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#ifndef CXD2820R_H
23#define CXD2820R_H
24
25#include <linux/dvb/frontend.h>
26
27#define CXD2820R_GPIO_D (0 << 0) /* disable */
28#define CXD2820R_GPIO_E (1 << 0) /* enable */
29#define CXD2820R_GPIO_O (0 << 1) /* output */
30#define CXD2820R_GPIO_I (1 << 1) /* input */
31#define CXD2820R_GPIO_L (0 << 2) /* output low */
32#define CXD2820R_GPIO_H (1 << 2) /* output high */
33
34#define CXD2820R_TS_SERIAL 0x08
35#define CXD2820R_TS_SERIAL_MSB 0x28
36#define CXD2820R_TS_PARALLEL 0x30
37#define CXD2820R_TS_PARALLEL_MSB 0x70
38
39struct cxd2820r_config {
40 /* Demodulator I2C address.
41 * Driver determines DVB-C slave I2C address automatically from master
42 * address.
43 * Default: none, must set
44 * Values: 0x6c, 0x6d
45 */
46 u8 i2c_address;
47
48 /* TS output mode.
49 * Default: none, must set.
50 * Values:
51 */
52 u8 ts_mode;
53
54 /* IF AGC polarity.
55 * Default: 0
56 * Values: 0, 1
57 */
58 int if_agc_polarity:1;
59
60 /* Spectrum inversion.
61 * Default: 0
62 * Values: 0, 1
63 */
64 int spec_inv:1;
65
66 /* IFs for all used modes.
67 * Default: none, must set
68 * Values: <kHz>
69 */
70 u16 if_dvbt_6;
71 u16 if_dvbt_7;
72 u16 if_dvbt_8;
73 u16 if_dvbt2_5;
74 u16 if_dvbt2_6;
75 u16 if_dvbt2_7;
76 u16 if_dvbt2_8;
77 u16 if_dvbc;
78
79 /* GPIOs for all used modes.
80 * Default: none, disabled
81 * Values: <see above>
82 */
83 u8 gpio_dvbt[3];
84 u8 gpio_dvbt2[3];
85 u8 gpio_dvbc[3];
86};
87
88
89#if defined(CONFIG_DVB_CXD2820R) || \
90 (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
91extern struct dvb_frontend *cxd2820r_attach(
92 const struct cxd2820r_config *config,
93 struct i2c_adapter *i2c,
94 struct dvb_frontend *fe
95);
96extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
97 struct dvb_frontend *fe
98);
99#else
100static inline struct dvb_frontend *cxd2820r_attach(
101 const struct cxd2820r_config *config,
102 struct i2c_adapter *i2c,
103 struct dvb_frontend *fe
104)
105{
106 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
107 return NULL;
108}
109static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
110 struct dvb_frontend *fe
111)
112{
113 return NULL;
114}
115
116#endif
117
118#endif /* CXD2820R_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
new file mode 100644
index 000000000000..3c07d400731d
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_c.c
@@ -0,0 +1,338 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *params)
26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
29 int ret, i;
30 u8 buf[2];
31 u16 if_ctl;
32 u64 num;
33 struct reg_val_mask tab[] = {
34 { 0x00080, 0x01, 0xff },
35 { 0x00081, 0x05, 0xff },
36 { 0x00085, 0x07, 0xff },
37 { 0x00088, 0x01, 0xff },
38
39 { 0x00082, 0x20, 0x60 },
40 { 0x1016a, 0x48, 0xff },
41 { 0x100a5, 0x00, 0x01 },
42 { 0x10020, 0x06, 0x07 },
43 { 0x10059, 0x50, 0xff },
44 { 0x10087, 0x0c, 0x3c },
45 { 0x1008b, 0x07, 0xff },
46 { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
47 { 0x10070, priv->cfg.ts_mode, 0xff },
48 };
49
50 dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
51
52 /* update GPIOs */
53 ret = cxd2820r_gpio(fe);
54 if (ret)
55 goto error;
56
57 /* program tuner */
58 if (fe->ops.tuner_ops.set_params)
59 fe->ops.tuner_ops.set_params(fe, params);
60
61 if (priv->delivery_system != SYS_DVBC_ANNEX_AC) {
62 for (i = 0; i < ARRAY_SIZE(tab); i++) {
63 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
64 tab[i].val, tab[i].mask);
65 if (ret)
66 goto error;
67 }
68 }
69
70 priv->delivery_system = SYS_DVBC_ANNEX_AC;
71 priv->ber_running = 0; /* tune stops BER counter */
72
73 num = priv->cfg.if_dvbc;
74 num *= 0x4000;
75 if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
76 buf[0] = (if_ctl >> 8) & 0x3f;
77 buf[1] = (if_ctl >> 0) & 0xff;
78
79 ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2);
80 if (ret)
81 goto error;
82
83 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
84 if (ret)
85 goto error;
86
87 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
88 if (ret)
89 goto error;
90
91 return ret;
92error:
93 dbg("%s: failed:%d", __func__, ret);
94 return ret;
95}
96
97int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
98 struct dvb_frontend_parameters *p)
99{
100 struct cxd2820r_priv *priv = fe->demodulator_priv;
101 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
102 int ret;
103 u8 buf[2];
104
105 ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2);
106 if (ret)
107 goto error;
108
109 c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
110
111 ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]);
112 if (ret)
113 goto error;
114
115 switch ((buf[0] >> 0) & 0x03) {
116 case 0:
117 c->modulation = QAM_16;
118 break;
119 case 1:
120 c->modulation = QAM_32;
121 break;
122 case 2:
123 c->modulation = QAM_64;
124 break;
125 case 3:
126 c->modulation = QAM_128;
127 break;
128 case 4:
129 c->modulation = QAM_256;
130 break;
131 }
132
133 switch ((buf[0] >> 7) & 0x01) {
134 case 0:
135 c->inversion = INVERSION_OFF;
136 break;
137 case 1:
138 c->inversion = INVERSION_ON;
139 break;
140 }
141
142 return ret;
143error:
144 dbg("%s: failed:%d", __func__, ret);
145 return ret;
146}
147
148int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
149{
150 struct cxd2820r_priv *priv = fe->demodulator_priv;
151 int ret;
152 u8 buf[3], start_ber = 0;
153 *ber = 0;
154
155 if (priv->ber_running) {
156 ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
157 if (ret)
158 goto error;
159
160 if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
161 *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
162 start_ber = 1;
163 }
164 } else {
165 priv->ber_running = 1;
166 start_ber = 1;
167 }
168
169 if (start_ber) {
170 /* (re)start BER */
171 ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
172 if (ret)
173 goto error;
174 }
175
176 return ret;
177error:
178 dbg("%s: failed:%d", __func__, ret);
179 return ret;
180}
181
182int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
183 u16 *strength)
184{
185 struct cxd2820r_priv *priv = fe->demodulator_priv;
186 int ret;
187 u8 buf[2];
188 u16 tmp;
189
190 ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
191 if (ret)
192 goto error;
193
194 tmp = (buf[0] & 0x03) << 8 | buf[1];
195 tmp = (~tmp & 0x03ff);
196
197 if (tmp == 512)
198 /* ~no signal */
199 tmp = 0;
200 else if (tmp > 350)
201 tmp = 350;
202
203 /* scale value to 0x0000-0xffff */
204 *strength = tmp * 0xffff / (350-0);
205
206 return ret;
207error:
208 dbg("%s: failed:%d", __func__, ret);
209 return ret;
210}
211
212int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
213{
214 struct cxd2820r_priv *priv = fe->demodulator_priv;
215 int ret;
216 u8 tmp;
217 unsigned int A, B;
218 /* report SNR in dB * 10 */
219
220 ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
221 if (ret)
222 goto error;
223
224 if (((tmp >> 0) & 0x03) % 2) {
225 A = 875;
226 B = 650;
227 } else {
228 A = 950;
229 B = 760;
230 }
231
232 ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
233 if (ret)
234 goto error;
235
236 #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
237 if (tmp)
238 *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
239 / 10;
240 else
241 *snr = 0;
242
243 return ret;
244error:
245 dbg("%s: failed:%d", __func__, ret);
246 return ret;
247}
248
249int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
250{
251 *ucblocks = 0;
252 /* no way to read ? */
253 return 0;
254}
255
256int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
257{
258 struct cxd2820r_priv *priv = fe->demodulator_priv;
259 int ret;
260 u8 buf[2];
261 *status = 0;
262
263 ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf));
264 if (ret)
265 goto error;
266
267 if (((buf[0] >> 0) & 0x01) == 1) {
268 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
269 FE_HAS_VITERBI | FE_HAS_SYNC;
270
271 if (((buf[1] >> 3) & 0x01) == 1) {
272 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
273 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
274 }
275 }
276
277 dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
278
279 return ret;
280error:
281 dbg("%s: failed:%d", __func__, ret);
282 return ret;
283}
284
285int cxd2820r_init_c(struct dvb_frontend *fe)
286{
287 struct cxd2820r_priv *priv = fe->demodulator_priv;
288 int ret;
289
290 ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
291 if (ret)
292 goto error;
293
294 return ret;
295error:
296 dbg("%s: failed:%d", __func__, ret);
297 return ret;
298}
299
300int cxd2820r_sleep_c(struct dvb_frontend *fe)
301{
302 struct cxd2820r_priv *priv = fe->demodulator_priv;
303 int ret, i;
304 struct reg_val_mask tab[] = {
305 { 0x000ff, 0x1f, 0xff },
306 { 0x00085, 0x00, 0xff },
307 { 0x00088, 0x01, 0xff },
308 { 0x00081, 0x00, 0xff },
309 { 0x00080, 0x00, 0xff },
310 };
311
312 dbg("%s", __func__);
313
314 priv->delivery_system = SYS_UNDEFINED;
315
316 for (i = 0; i < ARRAY_SIZE(tab); i++) {
317 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
318 tab[i].mask);
319 if (ret)
320 goto error;
321 }
322
323 return ret;
324error:
325 dbg("%s: failed:%d", __func__, ret);
326 return ret;
327}
328
329int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
330 struct dvb_frontend_tune_settings *s)
331{
332 s->min_delay_ms = 500;
333 s->step_size = 0; /* no zigzag */
334 s->max_drift = 0;
335
336 return 0;
337}
338
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
new file mode 100644
index 000000000000..0779f69db793
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_core.c
@@ -0,0 +1,915 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_debug;
25module_param_named(debug, cxd2820r_debug, int, 0644);
26MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
27
28/* write multiple registers */
29static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
30 u8 *val, int len)
31{
32 int ret;
33 u8 buf[len+1];
34 struct i2c_msg msg[1] = {
35 {
36 .addr = i2c,
37 .flags = 0,
38 .len = sizeof(buf),
39 .buf = buf,
40 }
41 };
42
43 buf[0] = reg;
44 memcpy(&buf[1], val, len);
45
46 ret = i2c_transfer(priv->i2c, msg, 1);
47 if (ret == 1) {
48 ret = 0;
49 } else {
50 warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
51 ret = -EREMOTEIO;
52 }
53 return ret;
54}
55
56/* read multiple registers */
57static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
58 u8 *val, int len)
59{
60 int ret;
61 u8 buf[len];
62 struct i2c_msg msg[2] = {
63 {
64 .addr = i2c,
65 .flags = 0,
66 .len = 1,
67 .buf = &reg,
68 }, {
69 .addr = i2c,
70 .flags = I2C_M_RD,
71 .len = sizeof(buf),
72 .buf = buf,
73 }
74 };
75
76 ret = i2c_transfer(priv->i2c, msg, 2);
77 if (ret == 2) {
78 memcpy(val, buf, len);
79 ret = 0;
80 } else {
81 warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
82 ret = -EREMOTEIO;
83 }
84
85 return ret;
86}
87
88/* write multiple registers */
89int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
90 int len)
91{
92 int ret;
93 u8 i2c_addr;
94 u8 reg = (reginfo >> 0) & 0xff;
95 u8 bank = (reginfo >> 8) & 0xff;
96 u8 i2c = (reginfo >> 16) & 0x01;
97
98 /* select I2C */
99 if (i2c)
100 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
101 else
102 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
103
104 /* switch bank if needed */
105 if (bank != priv->bank[i2c]) {
106 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
107 if (ret)
108 return ret;
109 priv->bank[i2c] = bank;
110 }
111 return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
112}
113
114/* read multiple registers */
115int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
116 int len)
117{
118 int ret;
119 u8 i2c_addr;
120 u8 reg = (reginfo >> 0) & 0xff;
121 u8 bank = (reginfo >> 8) & 0xff;
122 u8 i2c = (reginfo >> 16) & 0x01;
123
124 /* select I2C */
125 if (i2c)
126 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
127 else
128 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
129
130 /* switch bank if needed */
131 if (bank != priv->bank[i2c]) {
132 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
133 if (ret)
134 return ret;
135 priv->bank[i2c] = bank;
136 }
137 return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
138}
139
140/* write single register */
141int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
142{
143 return cxd2820r_wr_regs(priv, reg, &val, 1);
144}
145
146/* read single register */
147int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
148{
149 return cxd2820r_rd_regs(priv, reg, val, 1);
150}
151
152/* write single register with mask */
153int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
154 u8 mask)
155{
156 int ret;
157 u8 tmp;
158
159 /* no need for read if whole reg is written */
160 if (mask != 0xff) {
161 ret = cxd2820r_rd_reg(priv, reg, &tmp);
162 if (ret)
163 return ret;
164
165 val &= mask;
166 tmp &= ~mask;
167 val |= tmp;
168 }
169
170 return cxd2820r_wr_reg(priv, reg, val);
171}
172
173int cxd2820r_gpio(struct dvb_frontend *fe)
174{
175 struct cxd2820r_priv *priv = fe->demodulator_priv;
176 int ret, i;
177 u8 *gpio, tmp0, tmp1;
178 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
179
180 switch (fe->dtv_property_cache.delivery_system) {
181 case SYS_DVBT:
182 gpio = priv->cfg.gpio_dvbt;
183 break;
184 case SYS_DVBT2:
185 gpio = priv->cfg.gpio_dvbt2;
186 break;
187 case SYS_DVBC_ANNEX_AC:
188 gpio = priv->cfg.gpio_dvbc;
189 break;
190 default:
191 ret = -EINVAL;
192 goto error;
193 }
194
195 /* update GPIOs only when needed */
196 if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
197 return 0;
198
199 tmp0 = 0x00;
200 tmp1 = 0x00;
201 for (i = 0; i < sizeof(priv->gpio); i++) {
202 /* enable / disable */
203 if (gpio[i] & CXD2820R_GPIO_E)
204 tmp0 |= (2 << 6) >> (2 * i);
205 else
206 tmp0 |= (1 << 6) >> (2 * i);
207
208 /* input / output */
209 if (gpio[i] & CXD2820R_GPIO_I)
210 tmp1 |= (1 << (3 + i));
211 else
212 tmp1 |= (0 << (3 + i));
213
214 /* high / low */
215 if (gpio[i] & CXD2820R_GPIO_H)
216 tmp1 |= (1 << (0 + i));
217 else
218 tmp1 |= (0 << (0 + i));
219
220 dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
221 }
222
223 dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
224
225 /* write bits [7:2] */
226 ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
227 if (ret)
228 goto error;
229
230 /* write bits [5:0] */
231 ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
232 if (ret)
233 goto error;
234
235 memcpy(priv->gpio, gpio, sizeof(priv->gpio));
236
237 return ret;
238error:
239 dbg("%s: failed:%d", __func__, ret);
240 return ret;
241}
242
243/* lock FE */
244static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe)
245{
246 int ret = 0;
247 dbg("%s: active_fe=%d", __func__, active_fe);
248
249 mutex_lock(&priv->fe_lock);
250
251 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
252 if (priv->active_fe == active_fe)
253 ;
254 else if (priv->active_fe == -1)
255 priv->active_fe = active_fe;
256 else
257 ret = -EBUSY;
258
259 mutex_unlock(&priv->fe_lock);
260
261 return ret;
262}
263
264/* unlock FE */
265static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe)
266{
267 dbg("%s: active_fe=%d", __func__, active_fe);
268
269 mutex_lock(&priv->fe_lock);
270
271 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
272 if (priv->active_fe == active_fe)
273 priv->active_fe = -1;
274
275 mutex_unlock(&priv->fe_lock);
276
277 return;
278}
279
280/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
281u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
282{
283 return div_u64(dividend + (divisor / 2), divisor);
284}
285
286static int cxd2820r_set_frontend(struct dvb_frontend *fe,
287 struct dvb_frontend_parameters *p)
288{
289 struct cxd2820r_priv *priv = fe->demodulator_priv;
290 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
291 int ret;
292 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
293
294 if (fe->ops.info.type == FE_OFDM) {
295 /* DVB-T/T2 */
296 ret = cxd2820r_lock(priv, 0);
297 if (ret)
298 return ret;
299
300 switch (priv->delivery_system) {
301 case SYS_UNDEFINED:
302 if (c->delivery_system == SYS_DVBT) {
303 /* SLEEP => DVB-T */
304 ret = cxd2820r_set_frontend_t(fe, p);
305 } else {
306 /* SLEEP => DVB-T2 */
307 ret = cxd2820r_set_frontend_t2(fe, p);
308 }
309 break;
310 case SYS_DVBT:
311 if (c->delivery_system == SYS_DVBT) {
312 /* DVB-T => DVB-T */
313 ret = cxd2820r_set_frontend_t(fe, p);
314 } else if (c->delivery_system == SYS_DVBT2) {
315 /* DVB-T => DVB-T2 */
316 ret = cxd2820r_sleep_t(fe);
317 ret = cxd2820r_set_frontend_t2(fe, p);
318 }
319 break;
320 case SYS_DVBT2:
321 if (c->delivery_system == SYS_DVBT2) {
322 /* DVB-T2 => DVB-T2 */
323 ret = cxd2820r_set_frontend_t2(fe, p);
324 } else if (c->delivery_system == SYS_DVBT) {
325 /* DVB-T2 => DVB-T */
326 ret = cxd2820r_sleep_t2(fe);
327 ret = cxd2820r_set_frontend_t(fe, p);
328 }
329 break;
330 default:
331 dbg("%s: error state=%d", __func__,
332 priv->delivery_system);
333 ret = -EINVAL;
334 }
335 } else {
336 /* DVB-C */
337 ret = cxd2820r_lock(priv, 1);
338 if (ret)
339 return ret;
340
341 ret = cxd2820r_set_frontend_c(fe, p);
342 }
343
344 return ret;
345}
346
347static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
348{
349 struct cxd2820r_priv *priv = fe->demodulator_priv;
350 int ret;
351 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
352
353 if (fe->ops.info.type == FE_OFDM) {
354 /* DVB-T/T2 */
355 ret = cxd2820r_lock(priv, 0);
356 if (ret)
357 return ret;
358
359 switch (fe->dtv_property_cache.delivery_system) {
360 case SYS_DVBT:
361 ret = cxd2820r_read_status_t(fe, status);
362 break;
363 case SYS_DVBT2:
364 ret = cxd2820r_read_status_t2(fe, status);
365 break;
366 default:
367 ret = -EINVAL;
368 }
369 } else {
370 /* DVB-C */
371 ret = cxd2820r_lock(priv, 1);
372 if (ret)
373 return ret;
374
375 ret = cxd2820r_read_status_c(fe, status);
376 }
377
378 return ret;
379}
380
381static int cxd2820r_get_frontend(struct dvb_frontend *fe,
382 struct dvb_frontend_parameters *p)
383{
384 struct cxd2820r_priv *priv = fe->demodulator_priv;
385 int ret;
386 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
387
388 if (fe->ops.info.type == FE_OFDM) {
389 /* DVB-T/T2 */
390 ret = cxd2820r_lock(priv, 0);
391 if (ret)
392 return ret;
393
394 switch (fe->dtv_property_cache.delivery_system) {
395 case SYS_DVBT:
396 ret = cxd2820r_get_frontend_t(fe, p);
397 break;
398 case SYS_DVBT2:
399 ret = cxd2820r_get_frontend_t2(fe, p);
400 break;
401 default:
402 ret = -EINVAL;
403 }
404 } else {
405 /* DVB-C */
406 ret = cxd2820r_lock(priv, 1);
407 if (ret)
408 return ret;
409
410 ret = cxd2820r_get_frontend_c(fe, p);
411 }
412
413 return ret;
414}
415
416static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
417{
418 struct cxd2820r_priv *priv = fe->demodulator_priv;
419 int ret;
420 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
421
422 if (fe->ops.info.type == FE_OFDM) {
423 /* DVB-T/T2 */
424 ret = cxd2820r_lock(priv, 0);
425 if (ret)
426 return ret;
427
428 switch (fe->dtv_property_cache.delivery_system) {
429 case SYS_DVBT:
430 ret = cxd2820r_read_ber_t(fe, ber);
431 break;
432 case SYS_DVBT2:
433 ret = cxd2820r_read_ber_t2(fe, ber);
434 break;
435 default:
436 ret = -EINVAL;
437 }
438 } else {
439 /* DVB-C */
440 ret = cxd2820r_lock(priv, 1);
441 if (ret)
442 return ret;
443
444 ret = cxd2820r_read_ber_c(fe, ber);
445 }
446
447 return ret;
448}
449
450static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
451{
452 struct cxd2820r_priv *priv = fe->demodulator_priv;
453 int ret;
454 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
455
456 if (fe->ops.info.type == FE_OFDM) {
457 /* DVB-T/T2 */
458 ret = cxd2820r_lock(priv, 0);
459 if (ret)
460 return ret;
461
462 switch (fe->dtv_property_cache.delivery_system) {
463 case SYS_DVBT:
464 ret = cxd2820r_read_signal_strength_t(fe, strength);
465 break;
466 case SYS_DVBT2:
467 ret = cxd2820r_read_signal_strength_t2(fe, strength);
468 break;
469 default:
470 ret = -EINVAL;
471 }
472 } else {
473 /* DVB-C */
474 ret = cxd2820r_lock(priv, 1);
475 if (ret)
476 return ret;
477
478 ret = cxd2820r_read_signal_strength_c(fe, strength);
479 }
480
481 return ret;
482}
483
484static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
485{
486 struct cxd2820r_priv *priv = fe->demodulator_priv;
487 int ret;
488 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
489
490 if (fe->ops.info.type == FE_OFDM) {
491 /* DVB-T/T2 */
492 ret = cxd2820r_lock(priv, 0);
493 if (ret)
494 return ret;
495
496 switch (fe->dtv_property_cache.delivery_system) {
497 case SYS_DVBT:
498 ret = cxd2820r_read_snr_t(fe, snr);
499 break;
500 case SYS_DVBT2:
501 ret = cxd2820r_read_snr_t2(fe, snr);
502 break;
503 default:
504 ret = -EINVAL;
505 }
506 } else {
507 /* DVB-C */
508 ret = cxd2820r_lock(priv, 1);
509 if (ret)
510 return ret;
511
512 ret = cxd2820r_read_snr_c(fe, snr);
513 }
514
515 return ret;
516}
517
518static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
519{
520 struct cxd2820r_priv *priv = fe->demodulator_priv;
521 int ret;
522 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
523
524 if (fe->ops.info.type == FE_OFDM) {
525 /* DVB-T/T2 */
526 ret = cxd2820r_lock(priv, 0);
527 if (ret)
528 return ret;
529
530 switch (fe->dtv_property_cache.delivery_system) {
531 case SYS_DVBT:
532 ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
533 break;
534 case SYS_DVBT2:
535 ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
536 break;
537 default:
538 ret = -EINVAL;
539 }
540 } else {
541 /* DVB-C */
542 ret = cxd2820r_lock(priv, 1);
543 if (ret)
544 return ret;
545
546 ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
547 }
548
549 return ret;
550}
551
552static int cxd2820r_init(struct dvb_frontend *fe)
553{
554 struct cxd2820r_priv *priv = fe->demodulator_priv;
555 int ret;
556 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
557
558 priv->delivery_system = SYS_UNDEFINED;
559 /* delivery system is unknown at that (init) phase */
560
561 if (fe->ops.info.type == FE_OFDM) {
562 /* DVB-T/T2 */
563 ret = cxd2820r_lock(priv, 0);
564 if (ret)
565 return ret;
566
567 ret = cxd2820r_init_t(fe);
568 } else {
569 /* DVB-C */
570 ret = cxd2820r_lock(priv, 1);
571 if (ret)
572 return ret;
573
574 ret = cxd2820r_init_c(fe);
575 }
576
577 return ret;
578}
579
580static int cxd2820r_sleep(struct dvb_frontend *fe)
581{
582 struct cxd2820r_priv *priv = fe->demodulator_priv;
583 int ret;
584 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
585
586 if (fe->ops.info.type == FE_OFDM) {
587 /* DVB-T/T2 */
588 ret = cxd2820r_lock(priv, 0);
589 if (ret)
590 return ret;
591
592 switch (fe->dtv_property_cache.delivery_system) {
593 case SYS_DVBT:
594 ret = cxd2820r_sleep_t(fe);
595 break;
596 case SYS_DVBT2:
597 ret = cxd2820r_sleep_t2(fe);
598 break;
599 default:
600 ret = -EINVAL;
601 }
602
603 cxd2820r_unlock(priv, 0);
604 } else {
605 /* DVB-C */
606 ret = cxd2820r_lock(priv, 1);
607 if (ret)
608 return ret;
609
610 ret = cxd2820r_sleep_c(fe);
611
612 cxd2820r_unlock(priv, 1);
613 }
614
615 return ret;
616}
617
618static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
619 struct dvb_frontend_tune_settings *s)
620{
621 struct cxd2820r_priv *priv = fe->demodulator_priv;
622 int ret;
623 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
624
625 if (fe->ops.info.type == FE_OFDM) {
626 /* DVB-T/T2 */
627 ret = cxd2820r_lock(priv, 0);
628 if (ret)
629 return ret;
630
631 switch (fe->dtv_property_cache.delivery_system) {
632 case SYS_DVBT:
633 ret = cxd2820r_get_tune_settings_t(fe, s);
634 break;
635 case SYS_DVBT2:
636 ret = cxd2820r_get_tune_settings_t2(fe, s);
637 break;
638 default:
639 ret = -EINVAL;
640 }
641 } else {
642 /* DVB-C */
643 ret = cxd2820r_lock(priv, 1);
644 if (ret)
645 return ret;
646
647 ret = cxd2820r_get_tune_settings_c(fe, s);
648 }
649
650 return ret;
651}
652
653static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe,
654 struct dvb_frontend_parameters *p)
655{
656 struct cxd2820r_priv *priv = fe->demodulator_priv;
657 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
658 int ret, i;
659 fe_status_t status = 0;
660 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
661
662 /* switch between DVB-T and DVB-T2 when tune fails */
663 if (priv->last_tune_failed) {
664 if (priv->delivery_system == SYS_DVBT)
665 c->delivery_system = SYS_DVBT2;
666 else
667 c->delivery_system = SYS_DVBT;
668 }
669
670 /* set frontend */
671 ret = cxd2820r_set_frontend(fe, p);
672 if (ret)
673 goto error;
674
675
676 /* frontend lock wait loop count */
677 switch (priv->delivery_system) {
678 case SYS_DVBT:
679 i = 20;
680 break;
681 case SYS_DVBT2:
682 i = 40;
683 break;
684 case SYS_UNDEFINED:
685 default:
686 i = 0;
687 break;
688 }
689
690 /* wait frontend lock */
691 for (; i > 0; i--) {
692 dbg("%s: LOOP=%d", __func__, i);
693 msleep(50);
694 ret = cxd2820r_read_status(fe, &status);
695 if (ret)
696 goto error;
697
698 if (status & FE_HAS_SIGNAL)
699 break;
700 }
701
702 /* check if we have a valid signal */
703 if (status) {
704 priv->last_tune_failed = 0;
705 return DVBFE_ALGO_SEARCH_SUCCESS;
706 } else {
707 priv->last_tune_failed = 1;
708 return DVBFE_ALGO_SEARCH_AGAIN;
709 }
710
711error:
712 dbg("%s: failed:%d", __func__, ret);
713 return DVBFE_ALGO_SEARCH_ERROR;
714}
715
716static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
717{
718 return DVBFE_ALGO_CUSTOM;
719}
720
721static void cxd2820r_release(struct dvb_frontend *fe)
722{
723 struct cxd2820r_priv *priv = fe->demodulator_priv;
724 dbg("%s", __func__);
725
726 if (fe->ops.info.type == FE_OFDM) {
727 i2c_del_adapter(&priv->tuner_i2c_adapter);
728 kfree(priv);
729 }
730
731 return;
732}
733
734static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter)
735{
736 return I2C_FUNC_I2C;
737}
738
739static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
740 struct i2c_msg msg[], int num)
741{
742 struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
743 u8 obuf[msg[0].len + 2];
744 struct i2c_msg msg2[2] = {
745 {
746 .addr = priv->cfg.i2c_address,
747 .flags = 0,
748 .len = sizeof(obuf),
749 .buf = obuf,
750 }, {
751 .addr = priv->cfg.i2c_address,
752 .flags = I2C_M_RD,
753 .len = msg[1].len,
754 .buf = msg[1].buf,
755 }
756 };
757
758 obuf[0] = 0x09;
759 obuf[1] = (msg[0].addr << 1);
760 if (num == 2) { /* I2C read */
761 obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
762 msg2[0].len = sizeof(obuf) - 1; /* maybe HW bug ? */
763 }
764 memcpy(&obuf[2], msg[0].buf, msg[0].len);
765
766 return i2c_transfer(priv->i2c, msg2, num);
767}
768
769static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
770 .master_xfer = cxd2820r_tuner_i2c_xfer,
771 .functionality = cxd2820r_tuner_i2c_func,
772};
773
774struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
775{
776 struct cxd2820r_priv *priv = fe->demodulator_priv;
777 return &priv->tuner_i2c_adapter;
778}
779EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
780
781static struct dvb_frontend_ops cxd2820r_ops[2];
782
783struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
784 struct i2c_adapter *i2c, struct dvb_frontend *fe)
785{
786 int ret;
787 struct cxd2820r_priv *priv = NULL;
788 u8 tmp;
789
790 if (fe == NULL) {
791 /* FE0 */
792 /* allocate memory for the internal priv */
793 priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL);
794 if (priv == NULL)
795 goto error;
796
797 /* setup the priv */
798 priv->i2c = i2c;
799 memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config));
800 mutex_init(&priv->fe_lock);
801
802 priv->active_fe = -1; /* NONE */
803
804 /* check if the demod is there */
805 priv->bank[0] = priv->bank[1] = 0xff;
806 ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
807 dbg("%s: chip id=%02x", __func__, tmp);
808 if (ret || tmp != 0xe1)
809 goto error;
810
811 /* create frontends */
812 memcpy(&priv->fe[0].ops, &cxd2820r_ops[0],
813 sizeof(struct dvb_frontend_ops));
814 memcpy(&priv->fe[1].ops, &cxd2820r_ops[1],
815 sizeof(struct dvb_frontend_ops));
816
817 priv->fe[0].demodulator_priv = priv;
818 priv->fe[1].demodulator_priv = priv;
819
820 /* create tuner i2c adapter */
821 strlcpy(priv->tuner_i2c_adapter.name,
822 "CXD2820R tuner I2C adapter",
823 sizeof(priv->tuner_i2c_adapter.name));
824 priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
825 priv->tuner_i2c_adapter.algo_data = NULL;
826 i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
827 if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
828 err("tuner I2C bus could not be initialized");
829 goto error;
830 }
831
832 return &priv->fe[0];
833
834 } else {
835 /* FE1: FE0 given as pointer, just return FE1 we have
836 * already created */
837 priv = fe->demodulator_priv;
838 return &priv->fe[1];
839 }
840
841error:
842 kfree(priv);
843 return NULL;
844}
845EXPORT_SYMBOL(cxd2820r_attach);
846
847static struct dvb_frontend_ops cxd2820r_ops[2] = {
848 {
849 /* DVB-T/T2 */
850 .info = {
851 .name = "Sony CXD2820R (DVB-T/T2)",
852 .type = FE_OFDM,
853 .caps =
854 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
855 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
856 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
857 FE_CAN_QPSK | FE_CAN_QAM_16 |
858 FE_CAN_QAM_64 | FE_CAN_QAM_256 |
859 FE_CAN_QAM_AUTO |
860 FE_CAN_TRANSMISSION_MODE_AUTO |
861 FE_CAN_GUARD_INTERVAL_AUTO |
862 FE_CAN_HIERARCHY_AUTO |
863 FE_CAN_MUTE_TS |
864 FE_CAN_2G_MODULATION
865 },
866
867 .release = cxd2820r_release,
868 .init = cxd2820r_init,
869 .sleep = cxd2820r_sleep,
870
871 .get_tune_settings = cxd2820r_get_tune_settings,
872
873 .get_frontend = cxd2820r_get_frontend,
874
875 .get_frontend_algo = cxd2820r_get_frontend_algo,
876 .search = cxd2820r_search,
877
878 .read_status = cxd2820r_read_status,
879 .read_snr = cxd2820r_read_snr,
880 .read_ber = cxd2820r_read_ber,
881 .read_ucblocks = cxd2820r_read_ucblocks,
882 .read_signal_strength = cxd2820r_read_signal_strength,
883 },
884 {
885 /* DVB-C */
886 .info = {
887 .name = "Sony CXD2820R (DVB-C)",
888 .type = FE_QAM,
889 .caps =
890 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
891 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
892 FE_CAN_FEC_AUTO
893 },
894
895 .release = cxd2820r_release,
896 .init = cxd2820r_init,
897 .sleep = cxd2820r_sleep,
898
899 .get_tune_settings = cxd2820r_get_tune_settings,
900
901 .set_frontend = cxd2820r_set_frontend,
902 .get_frontend = cxd2820r_get_frontend,
903
904 .read_status = cxd2820r_read_status,
905 .read_snr = cxd2820r_read_snr,
906 .read_ber = cxd2820r_read_ber,
907 .read_ucblocks = cxd2820r_read_ucblocks,
908 .read_signal_strength = cxd2820r_read_signal_strength,
909 },
910};
911
912
913MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
914MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
915MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h
new file mode 100644
index 000000000000..25adbeefa6d3
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_priv.h
@@ -0,0 +1,166 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#ifndef CXD2820R_PRIV_H
23#define CXD2820R_PRIV_H
24
25#include <linux/dvb/version.h>
26#include "dvb_frontend.h"
27#include "dvb_math.h"
28#include "cxd2820r.h"
29
30#define LOG_PREFIX "cxd2820r"
31
32#undef dbg
33#define dbg(f, arg...) \
34 if (cxd2820r_debug) \
35 printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
36#undef err
37#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
38#undef info
39#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
40#undef warn
41#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
42
43struct reg_val_mask {
44 u32 reg;
45 u8 val;
46 u8 mask;
47};
48
49struct cxd2820r_priv {
50 struct i2c_adapter *i2c;
51 struct dvb_frontend fe[2];
52 struct cxd2820r_config cfg;
53 struct i2c_adapter tuner_i2c_adapter;
54
55 struct mutex fe_lock; /* FE lock */
56 int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
57
58 int ber_running:1;
59
60 u8 bank[2];
61 u8 gpio[3];
62
63 fe_delivery_system_t delivery_system;
64 int last_tune_failed:1; /* for switch between T and T2 tune */
65};
66
67/* cxd2820r_core.c */
68
69extern int cxd2820r_debug;
70
71int cxd2820r_gpio(struct dvb_frontend *fe);
72
73int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
74 u8 mask);
75
76int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
77 int len);
78
79u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
80
81int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
82 int len);
83
84int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
85 int len);
86
87int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val);
88
89int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val);
90
91/* cxd2820r_c.c */
92
93int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
94 struct dvb_frontend_parameters *p);
95
96int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
97 struct dvb_frontend_parameters *params);
98
99int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status);
100
101int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
102
103int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
104
105int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
106
107int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
108
109int cxd2820r_init_c(struct dvb_frontend *fe);
110
111int cxd2820r_sleep_c(struct dvb_frontend *fe);
112
113int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
114 struct dvb_frontend_tune_settings *s);
115
116/* cxd2820r_t.c */
117
118int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
119 struct dvb_frontend_parameters *p);
120
121int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
122 struct dvb_frontend_parameters *params);
123
124int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status);
125
126int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
127
128int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
129
130int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
131
132int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
133
134int cxd2820r_init_t(struct dvb_frontend *fe);
135
136int cxd2820r_sleep_t(struct dvb_frontend *fe);
137
138int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
139 struct dvb_frontend_tune_settings *s);
140
141/* cxd2820r_t2.c */
142
143int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
144 struct dvb_frontend_parameters *p);
145
146int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
147 struct dvb_frontend_parameters *params);
148
149int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status);
150
151int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
152
153int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
154
155int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
156
157int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
158
159int cxd2820r_init_t2(struct dvb_frontend *fe);
160
161int cxd2820r_sleep_t2(struct dvb_frontend *fe);
162
163int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
164 struct dvb_frontend_tune_settings *s);
165
166#endif /* CXD2820R_PRIV_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
new file mode 100644
index 000000000000..6582564c930c
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_t.c
@@ -0,0 +1,449 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *p)
26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
29 int ret, i;
30 u32 if_khz, if_ctl;
31 u64 num;
32 u8 buf[3], bw_param;
33 u8 bw_params1[][5] = {
34 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
35 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
36 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
37 };
38 u8 bw_params2[][2] = {
39 { 0x1f, 0xdc }, /* 6 MHz */
40 { 0x12, 0xf8 }, /* 7 MHz */
41 { 0x01, 0xe0 }, /* 8 MHz */
42 };
43 struct reg_val_mask tab[] = {
44 { 0x00080, 0x00, 0xff },
45 { 0x00081, 0x03, 0xff },
46 { 0x00085, 0x07, 0xff },
47 { 0x00088, 0x01, 0xff },
48
49 { 0x00070, priv->cfg.ts_mode, 0xff },
50 { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
51 { 0x000a5, 0x00, 0x01 },
52 { 0x00082, 0x20, 0x60 },
53 { 0x000c2, 0xc3, 0xff },
54 { 0x0016a, 0x50, 0xff },
55 { 0x00427, 0x41, 0xff },
56 };
57
58 dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
59
60 /* update GPIOs */
61 ret = cxd2820r_gpio(fe);
62 if (ret)
63 goto error;
64
65 /* program tuner */
66 if (fe->ops.tuner_ops.set_params)
67 fe->ops.tuner_ops.set_params(fe, p);
68
69 if (priv->delivery_system != SYS_DVBT) {
70 for (i = 0; i < ARRAY_SIZE(tab); i++) {
71 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
72 tab[i].val, tab[i].mask);
73 if (ret)
74 goto error;
75 }
76 }
77
78 priv->delivery_system = SYS_DVBT;
79 priv->ber_running = 0; /* tune stops BER counter */
80
81 switch (c->bandwidth_hz) {
82 case 6000000:
83 if_khz = priv->cfg.if_dvbt_6;
84 i = 0;
85 bw_param = 2;
86 break;
87 case 7000000:
88 if_khz = priv->cfg.if_dvbt_7;
89 i = 1;
90 bw_param = 1;
91 break;
92 case 8000000:
93 if_khz = priv->cfg.if_dvbt_8;
94 i = 2;
95 bw_param = 0;
96 break;
97 default:
98 return -EINVAL;
99 }
100
101 num = if_khz;
102 num *= 0x1000000;
103 if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
104 buf[0] = ((if_ctl >> 16) & 0xff);
105 buf[1] = ((if_ctl >> 8) & 0xff);
106 buf[2] = ((if_ctl >> 0) & 0xff);
107
108 ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
109 if (ret)
110 goto error;
111
112 ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5);
113 if (ret)
114 goto error;
115
116 ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
117 if (ret)
118 goto error;
119
120 ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2);
121 if (ret)
122 goto error;
123
124 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
125 if (ret)
126 goto error;
127
128 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
129 if (ret)
130 goto error;
131
132 return ret;
133error:
134 dbg("%s: failed:%d", __func__, ret);
135 return ret;
136}
137
138int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
139 struct dvb_frontend_parameters *p)
140{
141 struct cxd2820r_priv *priv = fe->demodulator_priv;
142 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
143 int ret;
144 u8 buf[2];
145
146 ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
147 if (ret)
148 goto error;
149
150 switch ((buf[0] >> 6) & 0x03) {
151 case 0:
152 c->modulation = QPSK;
153 break;
154 case 1:
155 c->modulation = QAM_16;
156 break;
157 case 2:
158 c->modulation = QAM_64;
159 break;
160 }
161
162 switch ((buf[1] >> 1) & 0x03) {
163 case 0:
164 c->transmission_mode = TRANSMISSION_MODE_2K;
165 break;
166 case 1:
167 c->transmission_mode = TRANSMISSION_MODE_8K;
168 break;
169 }
170
171 switch ((buf[1] >> 3) & 0x03) {
172 case 0:
173 c->guard_interval = GUARD_INTERVAL_1_32;
174 break;
175 case 1:
176 c->guard_interval = GUARD_INTERVAL_1_16;
177 break;
178 case 2:
179 c->guard_interval = GUARD_INTERVAL_1_8;
180 break;
181 case 3:
182 c->guard_interval = GUARD_INTERVAL_1_4;
183 break;
184 }
185
186 switch ((buf[0] >> 3) & 0x07) {
187 case 0:
188 c->hierarchy = HIERARCHY_NONE;
189 break;
190 case 1:
191 c->hierarchy = HIERARCHY_1;
192 break;
193 case 2:
194 c->hierarchy = HIERARCHY_2;
195 break;
196 case 3:
197 c->hierarchy = HIERARCHY_4;
198 break;
199 }
200
201 switch ((buf[0] >> 0) & 0x07) {
202 case 0:
203 c->code_rate_HP = FEC_1_2;
204 break;
205 case 1:
206 c->code_rate_HP = FEC_2_3;
207 break;
208 case 2:
209 c->code_rate_HP = FEC_3_4;
210 break;
211 case 3:
212 c->code_rate_HP = FEC_5_6;
213 break;
214 case 4:
215 c->code_rate_HP = FEC_7_8;
216 break;
217 }
218
219 switch ((buf[1] >> 5) & 0x07) {
220 case 0:
221 c->code_rate_LP = FEC_1_2;
222 break;
223 case 1:
224 c->code_rate_LP = FEC_2_3;
225 break;
226 case 2:
227 c->code_rate_LP = FEC_3_4;
228 break;
229 case 3:
230 c->code_rate_LP = FEC_5_6;
231 break;
232 case 4:
233 c->code_rate_LP = FEC_7_8;
234 break;
235 }
236
237 ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
238 if (ret)
239 goto error;
240
241 switch ((buf[0] >> 0) & 0x01) {
242 case 0:
243 c->inversion = INVERSION_OFF;
244 break;
245 case 1:
246 c->inversion = INVERSION_ON;
247 break;
248 }
249
250 return ret;
251error:
252 dbg("%s: failed:%d", __func__, ret);
253 return ret;
254}
255
256int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
257{
258 struct cxd2820r_priv *priv = fe->demodulator_priv;
259 int ret;
260 u8 buf[3], start_ber = 0;
261 *ber = 0;
262
263 if (priv->ber_running) {
264 ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
265 if (ret)
266 goto error;
267
268 if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
269 *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
270 start_ber = 1;
271 }
272 } else {
273 priv->ber_running = 1;
274 start_ber = 1;
275 }
276
277 if (start_ber) {
278 /* (re)start BER */
279 ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
280 if (ret)
281 goto error;
282 }
283
284 return ret;
285error:
286 dbg("%s: failed:%d", __func__, ret);
287 return ret;
288}
289
290int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
291 u16 *strength)
292{
293 struct cxd2820r_priv *priv = fe->demodulator_priv;
294 int ret;
295 u8 buf[2];
296 u16 tmp;
297
298 ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
299 if (ret)
300 goto error;
301
302 tmp = (buf[0] & 0x0f) << 8 | buf[1];
303 tmp = ~tmp & 0x0fff;
304
305 /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
306 *strength = tmp * 0xffff / 0x0fff;
307
308 return ret;
309error:
310 dbg("%s: failed:%d", __func__, ret);
311 return ret;
312}
313
314int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
315{
316 struct cxd2820r_priv *priv = fe->demodulator_priv;
317 int ret;
318 u8 buf[2];
319 u16 tmp;
320 /* report SNR in dB * 10 */
321
322 ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
323 if (ret)
324 goto error;
325
326 tmp = (buf[0] & 0x1f) << 8 | buf[1];
327 #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
328 if (tmp)
329 *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
330 / 100);
331 else
332 *snr = 0;
333
334 dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
335
336 return ret;
337error:
338 dbg("%s: failed:%d", __func__, ret);
339 return ret;
340}
341
342int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
343{
344 *ucblocks = 0;
345 /* no way to read ? */
346 return 0;
347}
348
349int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
350{
351 struct cxd2820r_priv *priv = fe->demodulator_priv;
352 int ret;
353 u8 buf[4];
354 *status = 0;
355
356 ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
357 if (ret)
358 goto error;
359
360 if ((buf[0] & 0x07) == 6) {
361 ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
362 if (ret)
363 goto error;
364
365 if (((buf[1] >> 3) & 0x01) == 1) {
366 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
367 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
368 } else {
369 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
370 FE_HAS_VITERBI | FE_HAS_SYNC;
371 }
372 } else {
373 ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
374 if (ret)
375 goto error;
376
377 if ((buf[2] & 0x0f) >= 4) {
378 ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
379 if (ret)
380 goto error;
381
382 if (((buf[3] >> 4) & 0x01) == 1)
383 *status |= FE_HAS_SIGNAL;
384 }
385 }
386
387 dbg("%s: lock=%02x %02x %02x %02x", __func__,
388 buf[0], buf[1], buf[2], buf[3]);
389
390 return ret;
391error:
392 dbg("%s: failed:%d", __func__, ret);
393 return ret;
394}
395
396int cxd2820r_init_t(struct dvb_frontend *fe)
397{
398 struct cxd2820r_priv *priv = fe->demodulator_priv;
399 int ret;
400
401 ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
402 if (ret)
403 goto error;
404
405 return ret;
406error:
407 dbg("%s: failed:%d", __func__, ret);
408 return ret;
409}
410
411int cxd2820r_sleep_t(struct dvb_frontend *fe)
412{
413 struct cxd2820r_priv *priv = fe->demodulator_priv;
414 int ret, i;
415 struct reg_val_mask tab[] = {
416 { 0x000ff, 0x1f, 0xff },
417 { 0x00085, 0x00, 0xff },
418 { 0x00088, 0x01, 0xff },
419 { 0x00081, 0x00, 0xff },
420 { 0x00080, 0x00, 0xff },
421 };
422
423 dbg("%s", __func__);
424
425 priv->delivery_system = SYS_UNDEFINED;
426
427 for (i = 0; i < ARRAY_SIZE(tab); i++) {
428 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
429 tab[i].mask);
430 if (ret)
431 goto error;
432 }
433
434 return ret;
435error:
436 dbg("%s: failed:%d", __func__, ret);
437 return ret;
438}
439
440int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
441 struct dvb_frontend_tune_settings *s)
442{
443 s->min_delay_ms = 500;
444 s->step_size = fe->ops.info.frequency_stepsize * 2;
445 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
446
447 return 0;
448}
449
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
new file mode 100644
index 000000000000..c47b35c8acf1
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_t2.c
@@ -0,0 +1,423 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *params)
26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
29 int ret, i;
30 u32 if_khz, if_ctl;
31 u64 num;
32 u8 buf[3], bw_param;
33 u8 bw_params1[][5] = {
34 { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */
35 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
36 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
37 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
38 };
39 struct reg_val_mask tab[] = {
40 { 0x00080, 0x02, 0xff },
41 { 0x00081, 0x20, 0xff },
42 { 0x00085, 0x07, 0xff },
43 { 0x00088, 0x01, 0xff },
44 { 0x02069, 0x01, 0xff },
45
46 { 0x0207f, 0x2a, 0xff },
47 { 0x02082, 0x0a, 0xff },
48 { 0x02083, 0x0a, 0xff },
49 { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
50 { 0x02070, priv->cfg.ts_mode, 0xff },
51 { 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
52 { 0x02567, 0x07, 0x0f },
53 { 0x02569, 0x03, 0x03 },
54 { 0x02595, 0x1a, 0xff },
55 { 0x02596, 0x50, 0xff },
56 { 0x02a8c, 0x00, 0xff },
57 { 0x02a8d, 0x34, 0xff },
58 { 0x02a45, 0x06, 0x07 },
59 { 0x03f10, 0x0d, 0xff },
60 { 0x03f11, 0x02, 0xff },
61 { 0x03f12, 0x01, 0xff },
62 { 0x03f23, 0x2c, 0xff },
63 { 0x03f51, 0x13, 0xff },
64 { 0x03f52, 0x01, 0xff },
65 { 0x03f53, 0x00, 0xff },
66 { 0x027e6, 0x14, 0xff },
67 { 0x02786, 0x02, 0x07 },
68 { 0x02787, 0x40, 0xe0 },
69 { 0x027ef, 0x10, 0x18 },
70 };
71
72 dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
73
74 /* update GPIOs */
75 ret = cxd2820r_gpio(fe);
76 if (ret)
77 goto error;
78
79 /* program tuner */
80 if (fe->ops.tuner_ops.set_params)
81 fe->ops.tuner_ops.set_params(fe, params);
82
83 if (priv->delivery_system != SYS_DVBT2) {
84 for (i = 0; i < ARRAY_SIZE(tab); i++) {
85 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
86 tab[i].val, tab[i].mask);
87 if (ret)
88 goto error;
89 }
90 }
91
92 priv->delivery_system = SYS_DVBT2;
93
94 switch (c->bandwidth_hz) {
95 case 5000000:
96 if_khz = priv->cfg.if_dvbt2_5;
97 i = 0;
98 bw_param = 3;
99 break;
100 case 6000000:
101 if_khz = priv->cfg.if_dvbt2_6;
102 i = 1;
103 bw_param = 2;
104 break;
105 case 7000000:
106 if_khz = priv->cfg.if_dvbt2_7;
107 i = 2;
108 bw_param = 1;
109 break;
110 case 8000000:
111 if_khz = priv->cfg.if_dvbt2_8;
112 i = 3;
113 bw_param = 0;
114 break;
115 default:
116 return -EINVAL;
117 }
118
119 num = if_khz;
120 num *= 0x1000000;
121 if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
122 buf[0] = ((if_ctl >> 16) & 0xff);
123 buf[1] = ((if_ctl >> 8) & 0xff);
124 buf[2] = ((if_ctl >> 0) & 0xff);
125
126 ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
127 if (ret)
128 goto error;
129
130 ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5);
131 if (ret)
132 goto error;
133
134 ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0);
135 if (ret)
136 goto error;
137
138 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
139 if (ret)
140 goto error;
141
142 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
143 if (ret)
144 goto error;
145
146 return ret;
147error:
148 dbg("%s: failed:%d", __func__, ret);
149 return ret;
150
151}
152
153int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
154 struct dvb_frontend_parameters *p)
155{
156 struct cxd2820r_priv *priv = fe->demodulator_priv;
157 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
158 int ret;
159 u8 buf[2];
160
161 ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2);
162 if (ret)
163 goto error;
164
165 switch ((buf[0] >> 0) & 0x07) {
166 case 0:
167 c->transmission_mode = TRANSMISSION_MODE_2K;
168 break;
169 case 1:
170 c->transmission_mode = TRANSMISSION_MODE_8K;
171 break;
172 case 2:
173 c->transmission_mode = TRANSMISSION_MODE_4K;
174 break;
175 case 3:
176 c->transmission_mode = TRANSMISSION_MODE_1K;
177 break;
178 case 4:
179 c->transmission_mode = TRANSMISSION_MODE_16K;
180 break;
181 case 5:
182 c->transmission_mode = TRANSMISSION_MODE_32K;
183 break;
184 }
185
186 switch ((buf[1] >> 4) & 0x07) {
187 case 0:
188 c->guard_interval = GUARD_INTERVAL_1_32;
189 break;
190 case 1:
191 c->guard_interval = GUARD_INTERVAL_1_16;
192 break;
193 case 2:
194 c->guard_interval = GUARD_INTERVAL_1_8;
195 break;
196 case 3:
197 c->guard_interval = GUARD_INTERVAL_1_4;
198 break;
199 case 4:
200 c->guard_interval = GUARD_INTERVAL_1_128;
201 break;
202 case 5:
203 c->guard_interval = GUARD_INTERVAL_19_128;
204 break;
205 case 6:
206 c->guard_interval = GUARD_INTERVAL_19_256;
207 break;
208 }
209
210 ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2);
211 if (ret)
212 goto error;
213
214 switch ((buf[0] >> 0) & 0x07) {
215 case 0:
216 c->fec_inner = FEC_1_2;
217 break;
218 case 1:
219 c->fec_inner = FEC_3_5;
220 break;
221 case 2:
222 c->fec_inner = FEC_2_3;
223 break;
224 case 3:
225 c->fec_inner = FEC_3_4;
226 break;
227 case 4:
228 c->fec_inner = FEC_4_5;
229 break;
230 case 5:
231 c->fec_inner = FEC_5_6;
232 break;
233 }
234
235 switch ((buf[1] >> 0) & 0x07) {
236 case 0:
237 c->modulation = QPSK;
238 break;
239 case 1:
240 c->modulation = QAM_16;
241 break;
242 case 2:
243 c->modulation = QAM_64;
244 break;
245 case 3:
246 c->modulation = QAM_256;
247 break;
248 }
249
250 ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]);
251 if (ret)
252 goto error;
253
254 switch ((buf[0] >> 4) & 0x01) {
255 case 0:
256 c->inversion = INVERSION_OFF;
257 break;
258 case 1:
259 c->inversion = INVERSION_ON;
260 break;
261 }
262
263 return ret;
264error:
265 dbg("%s: failed:%d", __func__, ret);
266 return ret;
267}
268
269int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
270{
271 struct cxd2820r_priv *priv = fe->demodulator_priv;
272 int ret;
273 u8 buf[1];
274 *status = 0;
275
276 ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]);
277 if (ret)
278 goto error;
279
280 if ((buf[0] & 0x07) == 6) {
281 if (((buf[0] >> 5) & 0x01) == 1) {
282 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
283 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
284 } else {
285 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
286 FE_HAS_VITERBI | FE_HAS_SYNC;
287 }
288 }
289
290 dbg("%s: lock=%02x", __func__, buf[0]);
291
292 return ret;
293error:
294 dbg("%s: failed:%d", __func__, ret);
295 return ret;
296}
297
298int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
299{
300 struct cxd2820r_priv *priv = fe->demodulator_priv;
301 int ret;
302 u8 buf[4];
303 unsigned int errbits;
304 *ber = 0;
305 /* FIXME: correct calculation */
306
307 ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
308 if (ret)
309 goto error;
310
311 if ((buf[0] >> 4) & 0x01) {
312 errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
313 buf[2] << 8 | buf[3];
314
315 if (errbits)
316 *ber = errbits * 64 / 16588800;
317 }
318
319 return ret;
320error:
321 dbg("%s: failed:%d", __func__, ret);
322 return ret;
323}
324
325int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
326 u16 *strength)
327{
328 struct cxd2820r_priv *priv = fe->demodulator_priv;
329 int ret;
330 u8 buf[2];
331 u16 tmp;
332
333 ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
334 if (ret)
335 goto error;
336
337 tmp = (buf[0] & 0x0f) << 8 | buf[1];
338 tmp = ~tmp & 0x0fff;
339
340 /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
341 *strength = tmp * 0xffff / 0x0fff;
342
343 return ret;
344error:
345 dbg("%s: failed:%d", __func__, ret);
346 return ret;
347}
348
349int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
350{
351 struct cxd2820r_priv *priv = fe->demodulator_priv;
352 int ret;
353 u8 buf[2];
354 u16 tmp;
355 /* report SNR in dB * 10 */
356
357 ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
358 if (ret)
359 goto error;
360
361 tmp = (buf[0] & 0x0f) << 8 | buf[1];
362 #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
363 if (tmp)
364 *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
365 / 100);
366 else
367 *snr = 0;
368
369 dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
370
371 return ret;
372error:
373 dbg("%s: failed:%d", __func__, ret);
374 return ret;
375}
376
377int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
378{
379 *ucblocks = 0;
380 /* no way to read ? */
381 return 0;
382}
383
384int cxd2820r_sleep_t2(struct dvb_frontend *fe)
385{
386 struct cxd2820r_priv *priv = fe->demodulator_priv;
387 int ret, i;
388 struct reg_val_mask tab[] = {
389 { 0x000ff, 0x1f, 0xff },
390 { 0x00085, 0x00, 0xff },
391 { 0x00088, 0x01, 0xff },
392 { 0x02069, 0x00, 0xff },
393 { 0x00081, 0x00, 0xff },
394 { 0x00080, 0x00, 0xff },
395 };
396
397 dbg("%s", __func__);
398
399 for (i = 0; i < ARRAY_SIZE(tab); i++) {
400 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
401 tab[i].mask);
402 if (ret)
403 goto error;
404 }
405
406 priv->delivery_system = SYS_UNDEFINED;
407
408 return ret;
409error:
410 dbg("%s: failed:%d", __func__, ret);
411 return ret;
412}
413
414int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
415 struct dvb_frontend_tune_settings *s)
416{
417 s->min_delay_ms = 1500;
418 s->step_size = fe->ops.info.frequency_stepsize * 2;
419 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
420
421 return 0;
422}
423
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index d4e466a90e43..1d47d4da7d4c 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -73,27 +73,47 @@ struct dib0070_state {
73 73
74 u8 wbd_gain_current; 74 u8 wbd_gain_current;
75 u16 wbd_offset_3_3[2]; 75 u16 wbd_offset_3_3[2];
76
77 /* for the I2C transfer */
78 struct i2c_msg msg[2];
79 u8 i2c_write_buffer[3];
80 u8 i2c_read_buffer[2];
76}; 81};
77 82
78static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) 83static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
79{ 84{
80 u8 b[2]; 85 state->i2c_write_buffer[0] = reg;
81 struct i2c_msg msg[2] = { 86
82 { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 }, 87 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
83 { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, 88 state->msg[0].addr = state->cfg->i2c_address;
84 }; 89 state->msg[0].flags = 0;
85 if (i2c_transfer(state->i2c, msg, 2) != 2) { 90 state->msg[0].buf = state->i2c_write_buffer;
91 state->msg[0].len = 1;
92 state->msg[1].addr = state->cfg->i2c_address;
93 state->msg[1].flags = I2C_M_RD;
94 state->msg[1].buf = state->i2c_read_buffer;
95 state->msg[1].len = 2;
96
97 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
86 printk(KERN_WARNING "DiB0070 I2C read failed\n"); 98 printk(KERN_WARNING "DiB0070 I2C read failed\n");
87 return 0; 99 return 0;
88 } 100 }
89 return (b[0] << 8) | b[1]; 101 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
90} 102}
91 103
92static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) 104static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
93{ 105{
94 u8 b[3] = { reg, val >> 8, val & 0xff }; 106 state->i2c_write_buffer[0] = reg;
95 struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; 107 state->i2c_write_buffer[1] = val >> 8;
96 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 108 state->i2c_write_buffer[2] = val & 0xff;
109
110 memset(state->msg, 0, sizeof(struct i2c_msg));
111 state->msg[0].addr = state->cfg->i2c_address;
112 state->msg[0].flags = 0;
113 state->msg[0].buf = state->i2c_write_buffer;
114 state->msg[0].len = 3;
115
116 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
97 printk(KERN_WARNING "DiB0070 I2C write failed\n"); 117 printk(KERN_WARNING "DiB0070 I2C write failed\n");
98 return -EREMOTEIO; 118 return -EREMOTEIO;
99 } 119 }
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index 52ff1a252a90..c9c935ae41e4 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -191,6 +191,11 @@ struct dib0090_state {
191 u8 wbd_calibration_gain; 191 u8 wbd_calibration_gain;
192 const struct dib0090_wbd_slope *current_wbd_table; 192 const struct dib0090_wbd_slope *current_wbd_table;
193 u16 wbdmux; 193 u16 wbdmux;
194
195 /* for the I2C transfer */
196 struct i2c_msg msg[2];
197 u8 i2c_write_buffer[3];
198 u8 i2c_read_buffer[2];
194}; 199};
195 200
196struct dib0090_fw_state { 201struct dib0090_fw_state {
@@ -198,27 +203,48 @@ struct dib0090_fw_state {
198 struct dvb_frontend *fe; 203 struct dvb_frontend *fe;
199 struct dib0090_identity identity; 204 struct dib0090_identity identity;
200 const struct dib0090_config *config; 205 const struct dib0090_config *config;
206
207 /* for the I2C transfer */
208 struct i2c_msg msg;
209 u8 i2c_write_buffer[2];
210 u8 i2c_read_buffer[2];
201}; 211};
202 212
203static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) 213static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
204{ 214{
205 u8 b[2]; 215 state->i2c_write_buffer[0] = reg;
206 struct i2c_msg msg[2] = { 216
207 {.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1}, 217 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
208 {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, 218 state->msg[0].addr = state->config->i2c_address;
209 }; 219 state->msg[0].flags = 0;
210 if (i2c_transfer(state->i2c, msg, 2) != 2) { 220 state->msg[0].buf = state->i2c_write_buffer;
221 state->msg[0].len = 1;
222 state->msg[1].addr = state->config->i2c_address;
223 state->msg[1].flags = I2C_M_RD;
224 state->msg[1].buf = state->i2c_read_buffer;
225 state->msg[1].len = 2;
226
227 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
211 printk(KERN_WARNING "DiB0090 I2C read failed\n"); 228 printk(KERN_WARNING "DiB0090 I2C read failed\n");
212 return 0; 229 return 0;
213 } 230 }
214 return (b[0] << 8) | b[1]; 231
232 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
215} 233}
216 234
217static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) 235static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
218{ 236{
219 u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; 237 state->i2c_write_buffer[0] = reg & 0xff;
220 struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; 238 state->i2c_write_buffer[1] = val >> 8;
221 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 239 state->i2c_write_buffer[2] = val & 0xff;
240
241 memset(state->msg, 0, sizeof(struct i2c_msg));
242 state->msg[0].addr = state->config->i2c_address;
243 state->msg[0].flags = 0;
244 state->msg[0].buf = state->i2c_write_buffer;
245 state->msg[0].len = 3;
246
247 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
222 printk(KERN_WARNING "DiB0090 I2C write failed\n"); 248 printk(KERN_WARNING "DiB0090 I2C write failed\n");
223 return -EREMOTEIO; 249 return -EREMOTEIO;
224 } 250 }
@@ -227,20 +253,31 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
227 253
228static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) 254static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
229{ 255{
230 u8 b[2]; 256 state->i2c_write_buffer[0] = reg;
231 struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 }; 257
232 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 258 memset(&state->msg, 0, sizeof(struct i2c_msg));
259 state->msg.addr = reg;
260 state->msg.flags = I2C_M_RD;
261 state->msg.buf = state->i2c_read_buffer;
262 state->msg.len = 2;
263 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
233 printk(KERN_WARNING "DiB0090 I2C read failed\n"); 264 printk(KERN_WARNING "DiB0090 I2C read failed\n");
234 return 0; 265 return 0;
235 } 266 }
236 return (b[0] << 8) | b[1]; 267 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
237} 268}
238 269
239static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) 270static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
240{ 271{
241 u8 b[2] = { val >> 8, val & 0xff }; 272 state->i2c_write_buffer[0] = val >> 8;
242 struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 }; 273 state->i2c_write_buffer[1] = val & 0xff;
243 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 274
275 memset(&state->msg, 0, sizeof(struct i2c_msg));
276 state->msg.addr = reg;
277 state->msg.flags = 0;
278 state->msg.buf = state->i2c_write_buffer;
279 state->msg.len = 2;
280 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
244 printk(KERN_WARNING "DiB0090 I2C write failed\n"); 281 printk(KERN_WARNING "DiB0090 I2C write failed\n");
245 return -EREMOTEIO; 282 return -EREMOTEIO;
246 } 283 }
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index 289a79837f24..79cb1c20df24 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -50,6 +50,11 @@ struct dib7000m_state {
50 u16 revision; 50 u16 revision;
51 51
52 u8 agc_state; 52 u8 agc_state;
53
54 /* for the I2C transfer */
55 struct i2c_msg msg[2];
56 u8 i2c_write_buffer[4];
57 u8 i2c_read_buffer[2];
53}; 58};
54 59
55enum dib7000m_power_mode { 60enum dib7000m_power_mode {
@@ -64,29 +69,39 @@ enum dib7000m_power_mode {
64 69
65static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) 70static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
66{ 71{
67 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; 72 state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
68 u8 rb[2]; 73 state->i2c_write_buffer[1] = reg & 0xff;
69 struct i2c_msg msg[2] = { 74
70 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, 75 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
71 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, 76 state->msg[0].addr = state->i2c_addr >> 1;
72 }; 77 state->msg[0].flags = 0;
73 78 state->msg[0].buf = state->i2c_write_buffer;
74 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 79 state->msg[0].len = 2;
80 state->msg[1].addr = state->i2c_addr >> 1;
81 state->msg[1].flags = I2C_M_RD;
82 state->msg[1].buf = state->i2c_read_buffer;
83 state->msg[1].len = 2;
84
85 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
75 dprintk("i2c read error on %d",reg); 86 dprintk("i2c read error on %d",reg);
76 87
77 return (rb[0] << 8) | rb[1]; 88 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
78} 89}
79 90
80static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) 91static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
81{ 92{
82 u8 b[4] = { 93 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
83 (reg >> 8) & 0xff, reg & 0xff, 94 state->i2c_write_buffer[1] = reg & 0xff;
84 (val >> 8) & 0xff, val & 0xff, 95 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
85 }; 96 state->i2c_write_buffer[3] = val & 0xff;
86 struct i2c_msg msg = { 97
87 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 98 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
88 }; 99 state->msg[0].addr = state->i2c_addr >> 1;
89 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 100 state->msg[0].flags = 0;
101 state->msg[0].buf = state->i2c_write_buffer;
102 state->msg[0].len = 4;
103
104 return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
90} 105}
91static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) 106static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
92{ 107{
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 900af60b9d36..0c9f40c2a251 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -63,6 +63,11 @@ struct dib7000p_state {
63 63
64 u16 tuner_enable; 64 u16 tuner_enable;
65 struct i2c_adapter dib7090_tuner_adap; 65 struct i2c_adapter dib7090_tuner_adap;
66
67 /* for the I2C transfer */
68 struct i2c_msg msg[2];
69 u8 i2c_write_buffer[4];
70 u8 i2c_read_buffer[2];
66}; 71};
67 72
68enum dib7000p_power_mode { 73enum dib7000p_power_mode {
@@ -76,29 +81,39 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
76 81
77static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) 82static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
78{ 83{
79 u8 wb[2] = { reg >> 8, reg & 0xff }; 84 state->i2c_write_buffer[0] = reg >> 8;
80 u8 rb[2]; 85 state->i2c_write_buffer[1] = reg & 0xff;
81 struct i2c_msg msg[2] = { 86
82 {.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, 87 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
83 {.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2}, 88 state->msg[0].addr = state->i2c_addr >> 1;
84 }; 89 state->msg[0].flags = 0;
90 state->msg[0].buf = state->i2c_write_buffer;
91 state->msg[0].len = 2;
92 state->msg[1].addr = state->i2c_addr >> 1;
93 state->msg[1].flags = I2C_M_RD;
94 state->msg[1].buf = state->i2c_read_buffer;
95 state->msg[1].len = 2;
85 96
86 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 97 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
87 dprintk("i2c read error on %d", reg); 98 dprintk("i2c read error on %d", reg);
88 99
89 return (rb[0] << 8) | rb[1]; 100 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
90} 101}
91 102
92static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) 103static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
93{ 104{
94 u8 b[4] = { 105 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
95 (reg >> 8) & 0xff, reg & 0xff, 106 state->i2c_write_buffer[1] = reg & 0xff;
96 (val >> 8) & 0xff, val & 0xff, 107 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
97 }; 108 state->i2c_write_buffer[3] = val & 0xff;
98 struct i2c_msg msg = { 109
99 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 110 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
100 }; 111 state->msg[0].addr = state->i2c_addr >> 1;
101 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 112 state->msg[0].flags = 0;
113 state->msg[0].buf = state->i2c_write_buffer;
114 state->msg[0].len = 4;
115
116 return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
102} 117}
103 118
104static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf) 119static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
@@ -1550,11 +1565,24 @@ static void dib7000p_release(struct dvb_frontend *demod)
1550 1565
1551int dib7000pc_detection(struct i2c_adapter *i2c_adap) 1566int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1552{ 1567{
1553 u8 tx[2], rx[2]; 1568 u8 *tx, *rx;
1554 struct i2c_msg msg[2] = { 1569 struct i2c_msg msg[2] = {
1555 {.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2}, 1570 {.addr = 18 >> 1, .flags = 0, .len = 2},
1556 {.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2}, 1571 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1557 }; 1572 };
1573 int ret = 0;
1574
1575 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1576 if (!tx)
1577 return -ENOMEM;
1578 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1579 if (!rx) {
1580 goto rx_memory_error;
1581 ret = -ENOMEM;
1582 }
1583
1584 msg[0].buf = tx;
1585 msg[1].buf = rx;
1558 1586
1559 tx[0] = 0x03; 1587 tx[0] = 0x03;
1560 tx[1] = 0x00; 1588 tx[1] = 0x00;
@@ -1574,7 +1602,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1574 } 1602 }
1575 1603
1576 dprintk("-D- DiB7000PC not detected"); 1604 dprintk("-D- DiB7000PC not detected");
1577 return 0; 1605
1606 kfree(rx);
1607rx_memory_error:
1608 kfree(tx);
1609 return ret;
1578} 1610}
1579EXPORT_SYMBOL(dib7000pc_detection); 1611EXPORT_SYMBOL(dib7000pc_detection);
1580 1612
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index c1c3e26906e2..7d2ea112ae2b 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -35,6 +35,8 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
35struct i2c_device { 35struct i2c_device {
36 struct i2c_adapter *adap; 36 struct i2c_adapter *adap;
37 u8 addr; 37 u8 addr;
38 u8 *i2c_write_buffer;
39 u8 *i2c_read_buffer;
38}; 40};
39 41
40struct dib8000_state { 42struct dib8000_state {
@@ -70,6 +72,11 @@ struct dib8000_state {
70 u32 status; 72 u32 status;
71 73
72 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; 74 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
75
76 /* for the I2C transfer */
77 struct i2c_msg msg[2];
78 u8 i2c_write_buffer[4];
79 u8 i2c_read_buffer[2];
73}; 80};
74 81
75enum dib8000_power_mode { 82enum dib8000_power_mode {
@@ -79,22 +86,41 @@ enum dib8000_power_mode {
79 86
80static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) 87static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
81{ 88{
82 u8 wb[2] = { reg >> 8, reg & 0xff };
83 u8 rb[2];
84 struct i2c_msg msg[2] = { 89 struct i2c_msg msg[2] = {
85 {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2}, 90 {.addr = i2c->addr >> 1, .flags = 0,
86 {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2}, 91 .buf = i2c->i2c_write_buffer, .len = 2},
92 {.addr = i2c->addr >> 1, .flags = I2C_M_RD,
93 .buf = i2c->i2c_read_buffer, .len = 2},
87 }; 94 };
88 95
96 msg[0].buf[0] = reg >> 8;
97 msg[0].buf[1] = reg & 0xff;
98
89 if (i2c_transfer(i2c->adap, msg, 2) != 2) 99 if (i2c_transfer(i2c->adap, msg, 2) != 2)
90 dprintk("i2c read error on %d", reg); 100 dprintk("i2c read error on %d", reg);
91 101
92 return (rb[0] << 8) | rb[1]; 102 return (msg[1].buf[0] << 8) | msg[1].buf[1];
93} 103}
94 104
95static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) 105static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
96{ 106{
97 return dib8000_i2c_read16(&state->i2c, reg); 107 state->i2c_write_buffer[0] = reg >> 8;
108 state->i2c_write_buffer[1] = reg & 0xff;
109
110 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
111 state->msg[0].addr = state->i2c.addr >> 1;
112 state->msg[0].flags = 0;
113 state->msg[0].buf = state->i2c_write_buffer;
114 state->msg[0].len = 2;
115 state->msg[1].addr = state->i2c.addr >> 1;
116 state->msg[1].flags = I2C_M_RD;
117 state->msg[1].buf = state->i2c_read_buffer;
118 state->msg[1].len = 2;
119
120 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
121 dprintk("i2c read error on %d", reg);
122
123 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
98} 124}
99 125
100static u32 dib8000_read32(struct dib8000_state *state, u16 reg) 126static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
@@ -109,19 +135,34 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
109 135
110static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) 136static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
111{ 137{
112 u8 b[4] = { 138 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
113 (reg >> 8) & 0xff, reg & 0xff, 139 .buf = i2c->i2c_write_buffer, .len = 4};
114 (val >> 8) & 0xff, val & 0xff, 140 int ret = 0;
115 }; 141
116 struct i2c_msg msg = { 142 msg.buf[0] = (reg >> 8) & 0xff;
117 .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4 143 msg.buf[1] = reg & 0xff;
118 }; 144 msg.buf[2] = (val >> 8) & 0xff;
119 return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 145 msg.buf[3] = val & 0xff;
146
147 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
148
149 return ret;
120} 150}
121 151
122static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) 152static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
123{ 153{
124 return dib8000_i2c_write16(&state->i2c, reg, val); 154 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
155 state->i2c_write_buffer[1] = reg & 0xff;
156 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
157 state->i2c_write_buffer[3] = val & 0xff;
158
159 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
160 state->msg[0].addr = state->i2c.addr >> 1;
161 state->msg[0].flags = 0;
162 state->msg[0].buf = state->i2c_write_buffer;
163 state->msg[0].len = 4;
164
165 return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
125} 166}
126 167
127static const s16 coeff_2k_sb_1seg_dqpsk[8] = { 168static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
@@ -980,30 +1021,31 @@ static void dib8000_update_timf(struct dib8000_state *state)
980 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); 1021 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
981} 1022}
982 1023
1024static const u16 adc_target_16dB[11] = {
1025 (1 << 13) - 825 - 117,
1026 (1 << 13) - 837 - 117,
1027 (1 << 13) - 811 - 117,
1028 (1 << 13) - 766 - 117,
1029 (1 << 13) - 737 - 117,
1030 (1 << 13) - 693 - 117,
1031 (1 << 13) - 648 - 117,
1032 (1 << 13) - 619 - 117,
1033 (1 << 13) - 575 - 117,
1034 (1 << 13) - 531 - 117,
1035 (1 << 13) - 501 - 117
1036};
1037static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1038
983static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching) 1039static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
984{ 1040{
985 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0; 1041 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
986 u8 guard, crate, constellation, timeI; 1042 u8 guard, crate, constellation, timeI;
987 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
988 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled 1043 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
989 const s16 *ncoeff = NULL, *ana_fe; 1044 const s16 *ncoeff = NULL, *ana_fe;
990 u16 tmcc_pow = 0; 1045 u16 tmcc_pow = 0;
991 u16 coff_pow = 0x2800; 1046 u16 coff_pow = 0x2800;
992 u16 init_prbs = 0xfff; 1047 u16 init_prbs = 0xfff;
993 u16 ana_gain = 0; 1048 u16 ana_gain = 0;
994 u16 adc_target_16dB[11] = {
995 (1 << 13) - 825 - 117,
996 (1 << 13) - 837 - 117,
997 (1 << 13) - 811 - 117,
998 (1 << 13) - 766 - 117,
999 (1 << 13) - 737 - 117,
1000 (1 << 13) - 693 - 117,
1001 (1 << 13) - 648 - 117,
1002 (1 << 13) - 619 - 117,
1003 (1 << 13) - 575 - 117,
1004 (1 << 13) - 531 - 117,
1005 (1 << 13) - 501 - 117
1006 };
1007 1049
1008 if (state->ber_monitored_layer != LAYER_ALL) 1050 if (state->ber_monitored_layer != LAYER_ALL)
1009 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); 1051 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
@@ -2379,10 +2421,22 @@ EXPORT_SYMBOL(dib8000_get_slave_frontend);
2379 2421
2380int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) 2422int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2381{ 2423{
2382 int k = 0; 2424 int k = 0, ret = 0;
2383 u8 new_addr = 0; 2425 u8 new_addr = 0;
2384 struct i2c_device client = {.adap = host }; 2426 struct i2c_device client = {.adap = host };
2385 2427
2428 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2429 if (!client.i2c_write_buffer) {
2430 dprintk("%s: not enough memory", __func__);
2431 return -ENOMEM;
2432 }
2433 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2434 if (!client.i2c_read_buffer) {
2435 dprintk("%s: not enough memory", __func__);
2436 ret = -ENOMEM;
2437 goto error_memory;
2438 }
2439
2386 for (k = no_of_demods - 1; k >= 0; k--) { 2440 for (k = no_of_demods - 1; k >= 0; k--) {
2387 /* designated i2c address */ 2441 /* designated i2c address */
2388 new_addr = first_addr + (k << 1); 2442 new_addr = first_addr + (k << 1);
@@ -2394,7 +2448,8 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
2394 client.addr = default_addr; 2448 client.addr = default_addr;
2395 if (dib8000_identify(&client) == 0) { 2449 if (dib8000_identify(&client) == 0) {
2396 dprintk("#%d: not identified", k); 2450 dprintk("#%d: not identified", k);
2397 return -EINVAL; 2451 ret = -EINVAL;
2452 goto error;
2398 } 2453 }
2399 } 2454 }
2400 2455
@@ -2420,7 +2475,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
2420 dib8000_i2c_write16(&client, 1286, 0); 2475 dib8000_i2c_write16(&client, 1286, 0);
2421 } 2476 }
2422 2477
2423 return 0; 2478error:
2479 kfree(client.i2c_read_buffer);
2480error_memory:
2481 kfree(client.i2c_write_buffer);
2482
2483 return ret;
2424} 2484}
2425 2485
2426EXPORT_SYMBOL(dib8000_i2c_enumeration); 2486EXPORT_SYMBOL(dib8000_i2c_enumeration);
@@ -2519,6 +2579,8 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
2519 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); 2579 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2520 state->i2c.adap = i2c_adap; 2580 state->i2c.adap = i2c_adap;
2521 state->i2c.addr = i2c_addr; 2581 state->i2c.addr = i2c_addr;
2582 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
2583 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
2522 state->gpio_val = cfg->gpio_val; 2584 state->gpio_val = cfg->gpio_val;
2523 state->gpio_dir = cfg->gpio_dir; 2585 state->gpio_dir = cfg->gpio_dir;
2524 2586
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
index 91518761a2da..a0855883b5ce 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -27,6 +27,8 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
27struct i2c_device { 27struct i2c_device {
28 struct i2c_adapter *i2c_adap; 28 struct i2c_adapter *i2c_adap;
29 u8 i2c_addr; 29 u8 i2c_addr;
30 u8 *i2c_read_buffer;
31 u8 *i2c_write_buffer;
30}; 32};
31 33
32/* lock */ 34/* lock */
@@ -92,11 +94,16 @@ struct dib9000_state {
92 94
93 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; 95 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
94 u16 component_bus_speed; 96 u16 component_bus_speed;
97
98 /* for the I2C transfer */
99 struct i2c_msg msg[2];
100 u8 i2c_write_buffer[255];
101 u8 i2c_read_buffer[255];
95}; 102};
96 103
97u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0 106 0, 0, 0, 0, 0, 0, 0, 0
100}; 107};
101 108
102enum dib9000_power_mode { 109enum dib9000_power_mode {
@@ -217,25 +224,33 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32
217 u32 chunk_size = 126; 224 u32 chunk_size = 126;
218 u32 l; 225 u32 l;
219 int ret; 226 int ret;
220 u8 wb[2] = { reg >> 8, reg & 0xff };
221 struct i2c_msg msg[2] = {
222 {.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
223 {.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len},
224 };
225 227
226 if (state->platform.risc.fw_is_running && (reg < 1024)) 228 if (state->platform.risc.fw_is_running && (reg < 1024))
227 return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len); 229 return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
228 230
231 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
232 state->msg[0].addr = state->i2c.i2c_addr >> 1;
233 state->msg[0].flags = 0;
234 state->msg[0].buf = state->i2c_write_buffer;
235 state->msg[0].len = 2;
236 state->msg[1].addr = state->i2c.i2c_addr >> 1;
237 state->msg[1].flags = I2C_M_RD;
238 state->msg[1].buf = b;
239 state->msg[1].len = len;
240
241 state->i2c_write_buffer[0] = reg >> 8;
242 state->i2c_write_buffer[1] = reg & 0xff;
243
229 if (attribute & DATA_BUS_ACCESS_MODE_8BIT) 244 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
230 wb[0] |= (1 << 5); 245 state->i2c_write_buffer[0] |= (1 << 5);
231 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) 246 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
232 wb[0] |= (1 << 4); 247 state->i2c_write_buffer[0] |= (1 << 4);
233 248
234 do { 249 do {
235 l = len < chunk_size ? len : chunk_size; 250 l = len < chunk_size ? len : chunk_size;
236 msg[1].len = l; 251 state->msg[1].len = l;
237 msg[1].buf = b; 252 state->msg[1].buf = b;
238 ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0; 253 ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
239 if (ret != 0) { 254 if (ret != 0) {
240 dprintk("i2c read error on %d", reg); 255 dprintk("i2c read error on %d", reg);
241 return -EREMOTEIO; 256 return -EREMOTEIO;
@@ -253,50 +268,47 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32
253 268
254static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg) 269static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
255{ 270{
256 u8 b[2];
257 u8 wb[2] = { reg >> 8, reg & 0xff };
258 struct i2c_msg msg[2] = { 271 struct i2c_msg msg[2] = {
259 {.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, 272 {.addr = i2c->i2c_addr >> 1, .flags = 0,
260 {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2}, 273 .buf = i2c->i2c_write_buffer, .len = 2},
274 {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
275 .buf = i2c->i2c_read_buffer, .len = 2},
261 }; 276 };
262 277
278 i2c->i2c_write_buffer[0] = reg >> 8;
279 i2c->i2c_write_buffer[1] = reg & 0xff;
280
263 if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) { 281 if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
264 dprintk("read register %x error", reg); 282 dprintk("read register %x error", reg);
265 return 0; 283 return 0;
266 } 284 }
267 285
268 return (b[0] << 8) | b[1]; 286 return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
269} 287}
270 288
271static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg) 289static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
272{ 290{
273 u8 b[2]; 291 if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
274 if (dib9000_read16_attr(state, reg, b, 2, 0) != 0)
275 return 0; 292 return 0;
276 return (b[0] << 8 | b[1]); 293 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
277} 294}
278 295
279static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute) 296static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
280{ 297{
281 u8 b[2]; 298 if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
282 if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0) 299 attribute) != 0)
283 return 0; 300 return 0;
284 return (b[0] << 8 | b[1]); 301 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
285} 302}
286 303
287#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) 304#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
288 305
289static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute) 306static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
290{ 307{
291 u8 b[255];
292 u32 chunk_size = 126; 308 u32 chunk_size = 126;
293 u32 l; 309 u32 l;
294 int ret; 310 int ret;
295 311
296 struct i2c_msg msg = {
297 .addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2
298 };
299
300 if (state->platform.risc.fw_is_running && (reg < 1024)) { 312 if (state->platform.risc.fw_is_running && (reg < 1024)) {
301 if (dib9000_risc_apb_access_write 313 if (dib9000_risc_apb_access_write
302 (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0) 314 (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
@@ -304,20 +316,26 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *
304 return 0; 316 return 0;
305 } 317 }
306 318
307 b[0] = (reg >> 8) & 0xff; 319 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
308 b[1] = (reg) & 0xff; 320 state->msg[0].addr = state->i2c.i2c_addr >> 1;
321 state->msg[0].flags = 0;
322 state->msg[0].buf = state->i2c_write_buffer;
323 state->msg[0].len = len + 2;
324
325 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
326 state->i2c_write_buffer[1] = (reg) & 0xff;
309 327
310 if (attribute & DATA_BUS_ACCESS_MODE_8BIT) 328 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
311 b[0] |= (1 << 5); 329 state->i2c_write_buffer[0] |= (1 << 5);
312 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) 330 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
313 b[0] |= (1 << 4); 331 state->i2c_write_buffer[0] |= (1 << 4);
314 332
315 do { 333 do {
316 l = len < chunk_size ? len : chunk_size; 334 l = len < chunk_size ? len : chunk_size;
317 msg.len = l + 2; 335 state->msg[0].len = l + 2;
318 memcpy(&b[2], buf, l); 336 memcpy(&state->i2c_write_buffer[2], buf, l);
319 337
320 ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 338 ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
321 339
322 buf += l; 340 buf += l;
323 len -= l; 341 len -= l;
@@ -331,11 +349,16 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *
331 349
332static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) 350static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
333{ 351{
334 u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff };
335 struct i2c_msg msg = { 352 struct i2c_msg msg = {
336 .addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 353 .addr = i2c->i2c_addr >> 1, .flags = 0,
354 .buf = i2c->i2c_write_buffer, .len = 4
337 }; 355 };
338 356
357 i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
358 i2c->i2c_write_buffer[1] = reg & 0xff;
359 i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
360 i2c->i2c_write_buffer[3] = val & 0xff;
361
339 return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 362 return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
340} 363}
341 364
@@ -1015,8 +1038,8 @@ static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
1015 return 0; 1038 return 0;
1016 dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i); 1039 dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
1017 do { 1040 do {
1018 dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1); 1041 dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
1019 } while (i && index_loop--); 1042 } while (state->i2c_read_buffer[0] && index_loop--);
1020 1043
1021 if (index_loop > 0) 1044 if (index_loop > 0)
1022 return 0; 1045 return 0;
@@ -1139,7 +1162,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1139 1162
1140 s8 intlv_native; 1163 s8 intlv_native;
1141 }; 1164 };
1142 struct dibDVBTChannel ch; 1165 struct dibDVBTChannel *ch;
1143 int ret = 0; 1166 int ret = 0;
1144 1167
1145 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1168 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
@@ -1148,9 +1171,12 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1148 ret = -EIO; 1171 ret = -EIO;
1149 } 1172 }
1150 1173
1151 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel)); 1174 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
1175 state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
1176 ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
1177
1152 1178
1153 switch (ch.spectrum_inversion & 0x7) { 1179 switch (ch->spectrum_inversion & 0x7) {
1154 case 1: 1180 case 1:
1155 state->fe[0]->dtv_property_cache.inversion = INVERSION_ON; 1181 state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
1156 break; 1182 break;
@@ -1162,7 +1188,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1162 state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO; 1188 state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
1163 break; 1189 break;
1164 } 1190 }
1165 switch (ch.nfft) { 1191 switch (ch->nfft) {
1166 case 0: 1192 case 0:
1167 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K; 1193 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1168 break; 1194 break;
@@ -1177,7 +1203,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1177 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO; 1203 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
1178 break; 1204 break;
1179 } 1205 }
1180 switch (ch.guard) { 1206 switch (ch->guard) {
1181 case 0: 1207 case 0:
1182 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32; 1208 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1183 break; 1209 break;
@@ -1195,7 +1221,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1195 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO; 1221 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
1196 break; 1222 break;
1197 } 1223 }
1198 switch (ch.constellation) { 1224 switch (ch->constellation) {
1199 case 2: 1225 case 2:
1200 state->fe[0]->dtv_property_cache.modulation = QAM_64; 1226 state->fe[0]->dtv_property_cache.modulation = QAM_64;
1201 break; 1227 break;
@@ -1210,7 +1236,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1210 state->fe[0]->dtv_property_cache.modulation = QAM_AUTO; 1236 state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
1211 break; 1237 break;
1212 } 1238 }
1213 switch (ch.hrch) { 1239 switch (ch->hrch) {
1214 case 0: 1240 case 0:
1215 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE; 1241 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
1216 break; 1242 break;
@@ -1222,7 +1248,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1222 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO; 1248 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
1223 break; 1249 break;
1224 } 1250 }
1225 switch (ch.code_rate_hp) { 1251 switch (ch->code_rate_hp) {
1226 case 1: 1252 case 1:
1227 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2; 1253 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
1228 break; 1254 break;
@@ -1243,7 +1269,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
1243 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO; 1269 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
1244 break; 1270 break;
1245 } 1271 }
1246 switch (ch.code_rate_lp) { 1272 switch (ch->code_rate_lp) {
1247 case 1: 1273 case 1:
1248 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2; 1274 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
1249 break; 1275 break;
@@ -1439,9 +1465,10 @@ static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_paramete
1439 break; 1465 break;
1440 case CT_DEMOD_STEP_1: 1466 case CT_DEMOD_STEP_1:
1441 if (search) 1467 if (search)
1442 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1); 1468 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
1443 else 1469 else
1444 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1); 1470 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
1471 i = (s8)state->i2c_read_buffer[0];
1445 switch (i) { /* something happened */ 1472 switch (i) { /* something happened */
1446 case 0: 1473 case 0:
1447 break; 1474 break;
@@ -2038,14 +2065,17 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2038static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) 2065static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2039{ 2066{
2040 struct dib9000_state *state = fe->demodulator_priv; 2067 struct dib9000_state *state = fe->demodulator_priv;
2041 u16 c[16]; 2068 u16 *c;
2042 2069
2043 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2070 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2044 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) 2071 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2045 return -EIO; 2072 return -EIO;
2046 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); 2073 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
2074 state->i2c_read_buffer, 16 * 2);
2047 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2075 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2048 2076
2077 c = (u16 *)state->i2c_read_buffer;
2078
2049 *ber = c[10] << 16 | c[11]; 2079 *ber = c[10] << 16 | c[11];
2050 return 0; 2080 return 0;
2051} 2081}
@@ -2054,7 +2084,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2054{ 2084{
2055 struct dib9000_state *state = fe->demodulator_priv; 2085 struct dib9000_state *state = fe->demodulator_priv;
2056 u8 index_frontend; 2086 u8 index_frontend;
2057 u16 c[16]; 2087 u16 *c = (u16 *)state->i2c_read_buffer;
2058 u16 val; 2088 u16 val;
2059 2089
2060 *strength = 0; 2090 *strength = 0;
@@ -2069,7 +2099,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2069 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2099 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2070 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) 2100 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2071 return -EIO; 2101 return -EIO;
2072 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); 2102 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2073 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2103 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2074 2104
2075 val = 65535 - c[4]; 2105 val = 65535 - c[4];
@@ -2083,14 +2113,14 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2083static u32 dib9000_get_snr(struct dvb_frontend *fe) 2113static u32 dib9000_get_snr(struct dvb_frontend *fe)
2084{ 2114{
2085 struct dib9000_state *state = fe->demodulator_priv; 2115 struct dib9000_state *state = fe->demodulator_priv;
2086 u16 c[16]; 2116 u16 *c = (u16 *)state->i2c_read_buffer;
2087 u32 n, s, exp; 2117 u32 n, s, exp;
2088 u16 val; 2118 u16 val;
2089 2119
2090 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2120 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2091 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) 2121 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2092 return -EIO; 2122 return -EIO;
2093 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); 2123 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2094 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2124 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2095 2125
2096 val = c[7]; 2126 val = c[7];
@@ -2137,12 +2167,12 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2137static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) 2167static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2138{ 2168{
2139 struct dib9000_state *state = fe->demodulator_priv; 2169 struct dib9000_state *state = fe->demodulator_priv;
2140 u16 c[16]; 2170 u16 *c = (u16 *)state->i2c_read_buffer;
2141 2171
2142 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2172 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2143 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) 2173 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2144 return -EIO; 2174 return -EIO;
2145 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); 2175 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2146 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2176 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2147 2177
2148 *unc = c[12]; 2178 *unc = c[12];
@@ -2151,10 +2181,22 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2151 2181
2152int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr) 2182int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
2153{ 2183{
2154 int k = 0; 2184 int k = 0, ret = 0;
2155 u8 new_addr = 0; 2185 u8 new_addr = 0;
2156 struct i2c_device client = {.i2c_adap = i2c }; 2186 struct i2c_device client = {.i2c_adap = i2c };
2157 2187
2188 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2189 if (!client.i2c_write_buffer) {
2190 dprintk("%s: not enough memory", __func__);
2191 return -ENOMEM;
2192 }
2193 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2194 if (!client.i2c_read_buffer) {
2195 dprintk("%s: not enough memory", __func__);
2196 ret = -ENOMEM;
2197 goto error_memory;
2198 }
2199
2158 client.i2c_addr = default_addr + 16; 2200 client.i2c_addr = default_addr + 16;
2159 dib9000_i2c_write16(&client, 1796, 0x0); 2201 dib9000_i2c_write16(&client, 1796, 0x0);
2160 2202
@@ -2178,7 +2220,8 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul
2178 client.i2c_addr = default_addr; 2220 client.i2c_addr = default_addr;
2179 if (dib9000_identify(&client) == 0) { 2221 if (dib9000_identify(&client) == 0) {
2180 dprintk("DiB9000 #%d: not identified", k); 2222 dprintk("DiB9000 #%d: not identified", k);
2181 return -EIO; 2223 ret = -EIO;
2224 goto error;
2182 } 2225 }
2183 } 2226 }
2184 2227
@@ -2196,7 +2239,12 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul
2196 dib9000_i2c_write16(&client, 1795, 0); 2239 dib9000_i2c_write16(&client, 1795, 0);
2197 } 2240 }
2198 2241
2199 return 0; 2242error:
2243 kfree(client.i2c_read_buffer);
2244error_memory:
2245 kfree(client.i2c_write_buffer);
2246
2247 return ret;
2200} 2248}
2201EXPORT_SYMBOL(dib9000_i2c_enumeration); 2249EXPORT_SYMBOL(dib9000_i2c_enumeration);
2202 2250
@@ -2255,12 +2303,16 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c
2255 if (st == NULL) 2303 if (st == NULL)
2256 return NULL; 2304 return NULL;
2257 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL); 2305 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2258 if (fe == NULL) 2306 if (fe == NULL) {
2307 kfree(st);
2259 return NULL; 2308 return NULL;
2309 }
2260 2310
2261 memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config)); 2311 memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
2262 st->i2c.i2c_adap = i2c_adap; 2312 st->i2c.i2c_adap = i2c_adap;
2263 st->i2c.i2c_addr = i2c_addr; 2313 st->i2c.i2c_addr = i2c_addr;
2314 st->i2c.i2c_write_buffer = st->i2c_write_buffer;
2315 st->i2c.i2c_read_buffer = st->i2c_read_buffer;
2264 2316
2265 st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS; 2317 st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
2266 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES; 2318 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index f6938f97feb4..dc5d17a67579 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -10,30 +10,39 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
10 10
11static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) 11static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
12{ 12{
13 u8 b[4] = { 13 mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
14 (reg >> 8) & 0xff, reg & 0xff, 14 mst->i2c_write_buffer[1] = reg & 0xff;
15 (val >> 8) & 0xff, val & 0xff, 15 mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
16 }; 16 mst->i2c_write_buffer[3] = val & 0xff;
17 struct i2c_msg msg = { 17
18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4 18 memset(mst->msg, 0, sizeof(struct i2c_msg));
19 }; 19 mst->msg[0].addr = mst->i2c_addr;
20 20 mst->msg[0].flags = 0;
21 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 21 mst->msg[0].buf = mst->i2c_write_buffer;
22 mst->msg[0].len = 4;
23
24 return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
22} 25}
23 26
24static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) 27static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
25{ 28{
26 u8 wb[2] = { reg >> 8, reg & 0xff }; 29 mst->i2c_write_buffer[0] = reg >> 8;
27 u8 rb[2]; 30 mst->i2c_write_buffer[1] = reg & 0xff;
28 struct i2c_msg msg[2] = { 31
29 {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2}, 32 memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
30 {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2}, 33 mst->msg[0].addr = mst->i2c_addr;
31 }; 34 mst->msg[0].flags = 0;
32 35 mst->msg[0].buf = mst->i2c_write_buffer;
33 if (i2c_transfer(mst->i2c_adap, msg, 2) != 2) 36 mst->msg[0].len = 2;
37 mst->msg[1].addr = mst->i2c_addr;
38 mst->msg[1].flags = I2C_M_RD;
39 mst->msg[1].buf = mst->i2c_read_buffer;
40 mst->msg[1].len = 2;
41
42 if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
34 dprintk("i2c read error on %d", reg); 43 dprintk("i2c read error on %d", reg);
35 44
36 return (rb[0] << 8) | rb[1]; 45 return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
37} 46}
38 47
39static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) 48static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
@@ -248,26 +257,32 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
248 struct i2c_msg msg[], int num) 257 struct i2c_msg msg[], int num)
249{ 258{
250 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); 259 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
251 struct i2c_msg m[2 + num];
252 u8 tx_open[4], tx_close[4];
253 260
254 memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); 261 if (num > 32) {
262 dprintk("%s: too much I2C message to be transmitted (%i).\
263 Maximum is 32", __func__, num);
264 return -ENOMEM;
265 }
266
267 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
255 268
256 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); 269 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
257 270
258 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); 271 /* open the gate */
259 m[0].addr = mst->i2c_addr; 272 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
260 m[0].buf = tx_open; 273 mst->msg[0].addr = mst->i2c_addr;
261 m[0].len = 4; 274 mst->msg[0].buf = &mst->i2c_write_buffer[0];
275 mst->msg[0].len = 4;
262 276
263 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); 277 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
264 278
265 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); 279 /* close the gate */
266 m[num + 1].addr = mst->i2c_addr; 280 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
267 m[num + 1].buf = tx_close; 281 mst->msg[num + 1].addr = mst->i2c_addr;
268 m[num + 1].len = 4; 282 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
283 mst->msg[num + 1].len = 4;
269 284
270 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; 285 return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
271} 286}
272 287
273static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { 288static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
@@ -279,26 +294,32 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
279 struct i2c_msg msg[], int num) 294 struct i2c_msg msg[], int num)
280{ 295{
281 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); 296 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
282 struct i2c_msg m[2 + num];
283 u8 tx_open[4], tx_close[4];
284 297
285 memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); 298 if (num > 32) {
299 dprintk("%s: too much I2C message to be transmitted (%i).\
300 Maximum is 32", __func__, num);
301 return -ENOMEM;
302 }
303
304 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
286 305
287 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); 306 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
288 307
289 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); 308 /* open the gate */
290 m[0].addr = mst->i2c_addr; 309 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
291 m[0].buf = tx_open; 310 mst->msg[0].addr = mst->i2c_addr;
292 m[0].len = 4; 311 mst->msg[0].buf = &mst->i2c_write_buffer[0];
312 mst->msg[0].len = 4;
293 313
294 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); 314 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
295 315
296 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); 316 /* close the gate */
297 m[num + 1].addr = mst->i2c_addr; 317 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
298 m[num + 1].buf = tx_close; 318 mst->msg[num + 1].addr = mst->i2c_addr;
299 m[num + 1].len = 4; 319 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
320 mst->msg[num + 1].len = 4;
300 321
301 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; 322 return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
302} 323}
303 324
304static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { 325static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 977d343369aa..f031165c0459 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -28,6 +28,11 @@ struct dibx000_i2c_master {
28 u8 i2c_addr; 28 u8 i2c_addr;
29 29
30 u16 base_reg; 30 u16 base_reg;
31
32 /* for the I2C transfer */
33 struct i2c_msg msg[34];
34 u8 i2c_write_buffer[8];
35 u8 i2c_read_buffer[2];
31}; 36};
32 37
33extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, 38extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
deleted file mode 100644
index 536f02b17338..000000000000
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ /dev/null
@@ -1,1511 +0,0 @@
1/*
2 * Driver for Micronas drx397xD demodulator
3 *
4 * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#define DEBUG /* uncomment if you want debugging output */
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/delay.h>
27#include <linux/string.h>
28#include <linux/firmware.h>
29#include <linux/slab.h>
30#include <asm/div64.h>
31
32#include "dvb_frontend.h"
33#include "drx397xD.h"
34
35static const char mod_name[] = "drx397xD";
36
37#define MAX_CLOCK_DRIFT 200 /* maximal 200 PPM allowed */
38
39#define F_SET_0D0h 1
40#define F_SET_0D4h 2
41
42enum fw_ix {
43#define _FW_ENTRY(a, b, c) b
44#include "drx397xD_fw.h"
45};
46
47/* chip specifics */
48struct drx397xD_state {
49 struct i2c_adapter *i2c;
50 struct dvb_frontend frontend;
51 struct drx397xD_config config;
52 enum fw_ix chip_rev;
53 int flags;
54 u32 bandwidth_parm; /* internal bandwidth conversions */
55 u32 f_osc; /* w90: actual osc frequency [Hz] */
56};
57
58/* Firmware */
59static const char *blob_name[] = {
60#define _BLOB_ENTRY(a, b) a
61#include "drx397xD_fw.h"
62};
63
64enum blob_ix {
65#define _BLOB_ENTRY(a, b) b
66#include "drx397xD_fw.h"
67};
68
69static struct {
70 const char *name;
71 const struct firmware *file;
72 rwlock_t lock;
73 int refcnt;
74 const u8 *data[ARRAY_SIZE(blob_name)];
75} fw[] = {
76#define _FW_ENTRY(a, b, c) { \
77 .name = a, \
78 .file = NULL, \
79 .lock = __RW_LOCK_UNLOCKED(fw[c].lock), \
80 .refcnt = 0, \
81 .data = { } }
82#include "drx397xD_fw.h"
83};
84
85/* use only with writer lock acquired */
86static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix)
87{
88 memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
89 if (fw[ix].file)
90 release_firmware(fw[ix].file);
91}
92
93static void drx_release_fw(struct drx397xD_state *s)
94{
95 enum fw_ix ix = s->chip_rev;
96
97 pr_debug("%s\n", __func__);
98
99 write_lock(&fw[ix].lock);
100 if (fw[ix].refcnt) {
101 fw[ix].refcnt--;
102 if (fw[ix].refcnt == 0)
103 _drx_release_fw(s, ix);
104 }
105 write_unlock(&fw[ix].lock);
106}
107
108static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix)
109{
110 const u8 *data;
111 size_t size, len;
112 int i = 0, j, rc = -EINVAL;
113
114 pr_debug("%s\n", __func__);
115
116 if (ix < 0 || ix >= ARRAY_SIZE(fw))
117 return -EINVAL;
118 s->chip_rev = ix;
119
120 write_lock(&fw[ix].lock);
121 if (fw[ix].file) {
122 rc = 0;
123 goto exit_ok;
124 }
125 memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
126
127 rc = request_firmware(&fw[ix].file, fw[ix].name, s->i2c->dev.parent);
128 if (rc != 0) {
129 printk(KERN_ERR "%s: Firmware \"%s\" not available\n",
130 mod_name, fw[ix].name);
131 goto exit_err;
132 }
133
134 if (!fw[ix].file->data || fw[ix].file->size < 10)
135 goto exit_corrupt;
136
137 data = fw[ix].file->data;
138 size = fw[ix].file->size;
139
140 if (data[i++] != 2) /* check firmware version */
141 goto exit_corrupt;
142
143 do {
144 switch (data[i++]) {
145 case 0x00: /* bytecode */
146 if (i >= size)
147 break;
148 i += data[i];
149 case 0x01: /* reset */
150 case 0x02: /* sleep */
151 i++;
152 break;
153 case 0xfe: /* name */
154 len = strnlen(&data[i], size - i);
155 if (i + len + 1 >= size)
156 goto exit_corrupt;
157 if (data[i + len + 1] != 0)
158 goto exit_corrupt;
159 for (j = 0; j < ARRAY_SIZE(blob_name); j++) {
160 if (strcmp(blob_name[j], &data[i]) == 0) {
161 fw[ix].data[j] = &data[i + len + 1];
162 pr_debug("Loading %s\n", blob_name[j]);
163 }
164 }
165 i += len + 1;
166 break;
167 case 0xff: /* file terminator */
168 if (i == size) {
169 rc = 0;
170 goto exit_ok;
171 }
172 default:
173 goto exit_corrupt;
174 }
175 } while (i < size);
176
177exit_corrupt:
178 printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
179exit_err:
180 _drx_release_fw(s, ix);
181 fw[ix].refcnt--;
182exit_ok:
183 fw[ix].refcnt++;
184 write_unlock(&fw[ix].lock);
185
186 return rc;
187}
188
189/* i2c bus IO */
190static int write_fw(struct drx397xD_state *s, enum blob_ix ix)
191{
192 const u8 *data;
193 int len, rc = 0, i = 0;
194 struct i2c_msg msg = {
195 .addr = s->config.demod_address,
196 .flags = 0
197 };
198
199 if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
200 pr_debug("%s drx_fw_ix_t out of range\n", __func__);
201 return -EINVAL;
202 }
203 pr_debug("%s %s\n", __func__, blob_name[ix]);
204
205 read_lock(&fw[s->chip_rev].lock);
206 data = fw[s->chip_rev].data[ix];
207 if (!data) {
208 rc = -EINVAL;
209 goto exit_rc;
210 }
211
212 for (;;) {
213 switch (data[i++]) {
214 case 0: /* bytecode */
215 len = data[i++];
216 msg.len = len;
217 msg.buf = (__u8 *) &data[i];
218 if (i2c_transfer(s->i2c, &msg, 1) != 1) {
219 rc = -EIO;
220 goto exit_rc;
221 }
222 i += len;
223 break;
224 case 1: /* reset */
225 case 2: /* sleep */
226 i++;
227 break;
228 default:
229 goto exit_rc;
230 }
231 }
232exit_rc:
233 read_unlock(&fw[s->chip_rev].lock);
234
235 return rc;
236}
237
238/* Function is not endian safe, use the RD16 wrapper below */
239static int _read16(struct drx397xD_state *s, __le32 i2c_adr)
240{
241 int rc;
242 u8 a[4];
243 __le16 v;
244 struct i2c_msg msg[2] = {
245 {
246 .addr = s->config.demod_address,
247 .flags = 0,
248 .buf = a,
249 .len = sizeof(a)
250 }, {
251 .addr = s->config.demod_address,
252 .flags = I2C_M_RD,
253 .buf = (u8 *)&v,
254 .len = sizeof(v)
255 }
256 };
257
258 *(__le32 *) a = i2c_adr;
259
260 rc = i2c_transfer(s->i2c, msg, 2);
261 if (rc != 2)
262 return -EIO;
263
264 return le16_to_cpu(v);
265}
266
267/* Function is not endian safe, use the WR16.. wrappers below */
268static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val)
269{
270 u8 a[6];
271 int rc;
272 struct i2c_msg msg = {
273 .addr = s->config.demod_address,
274 .flags = 0,
275 .buf = a,
276 .len = sizeof(a)
277 };
278
279 *(__le32 *)a = i2c_adr;
280 *(__le16 *)&a[4] = val;
281
282 rc = i2c_transfer(s->i2c, &msg, 1);
283 if (rc != 1)
284 return -EIO;
285
286 return 0;
287}
288
289#define WR16(ss, adr, val) \
290 _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
291#define WR16_E0(ss, adr, val) \
292 _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
293#define RD16(ss, adr) \
294 _read16(ss, I2C_ADR_C0(adr))
295
296#define EXIT_RC(cmd) \
297 if ((rc = (cmd)) < 0) \
298 goto exit_rc
299
300/* Tuner callback */
301static int PLL_Set(struct drx397xD_state *s,
302 struct dvb_frontend_parameters *fep, int *df_tuner)
303{
304 struct dvb_frontend *fe = &s->frontend;
305 u32 f_tuner, f = fep->frequency;
306 int rc;
307
308 pr_debug("%s\n", __func__);
309
310 if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
311 (f < s->frontend.ops.tuner_ops.info.frequency_min))
312 return -EINVAL;
313
314 *df_tuner = 0;
315 if (!s->frontend.ops.tuner_ops.set_params ||
316 !s->frontend.ops.tuner_ops.get_frequency)
317 return -ENOSYS;
318
319 rc = s->frontend.ops.tuner_ops.set_params(fe, fep);
320 if (rc < 0)
321 return rc;
322
323 rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner);
324 if (rc < 0)
325 return rc;
326
327 *df_tuner = f_tuner - f;
328 pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f,
329 f_tuner);
330
331 return 0;
332}
333
334/* Demodulator helper functions */
335static int SC_WaitForReady(struct drx397xD_state *s)
336{
337 int cnt = 1000;
338 int rc;
339
340 pr_debug("%s\n", __func__);
341
342 while (cnt--) {
343 rc = RD16(s, 0x820043);
344 if (rc == 0)
345 return 0;
346 }
347
348 return -1;
349}
350
351static int SC_SendCommand(struct drx397xD_state *s, int cmd)
352{
353 int rc;
354
355 pr_debug("%s\n", __func__);
356
357 WR16(s, 0x820043, cmd);
358 SC_WaitForReady(s);
359 rc = RD16(s, 0x820042);
360 if ((rc & 0xffff) == 0xffff)
361 return -1;
362
363 return 0;
364}
365
366static int HI_Command(struct drx397xD_state *s, u16 cmd)
367{
368 int rc, cnt = 1000;
369
370 pr_debug("%s\n", __func__);
371
372 rc = WR16(s, 0x420032, cmd);
373 if (rc < 0)
374 return rc;
375
376 do {
377 rc = RD16(s, 0x420032);
378 if (rc == 0) {
379 rc = RD16(s, 0x420031);
380 return rc;
381 }
382 if (rc < 0)
383 return rc;
384 } while (--cnt);
385
386 return rc;
387}
388
389static int HI_CfgCommand(struct drx397xD_state *s)
390{
391
392 pr_debug("%s\n", __func__);
393
394 WR16(s, 0x420033, 0x3973);
395 WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */
396 WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */
397 WR16(s, 0x420036, s->config.demod_address << 1);
398 WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */
399 /* WR16(s, 0x420033, 0x3973); */
400 if ((s->config.w56 & 8) == 0)
401 return HI_Command(s, 3);
402
403 return WR16(s, 0x420032, 0x3);
404}
405
406static const u8 fastIncrDecLUT_15273[] = {
407 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14,
408 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f
409};
410
411static const u8 slowIncrDecLUT_15272[] = {
412 3, 4, 4, 5, 6
413};
414
415static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
416{
417 u16 w06 = agc->w06;
418 u16 w08 = agc->w08;
419 u16 w0A = agc->w0A;
420 u16 w0C = agc->w0C;
421 int quot, rem, i, rc = -EINVAL;
422
423 pr_debug("%s\n", __func__);
424
425 if (agc->w04 > 0x3ff)
426 goto exit_rc;
427
428 if (agc->d00 == 1) {
429 EXIT_RC(RD16(s, 0x0c20010));
430 rc &= ~0x10;
431 EXIT_RC(WR16(s, 0x0c20010, rc));
432 return WR16(s, 0x0c20030, agc->w04 & 0x7ff);
433 }
434
435 if (agc->d00 != 0)
436 goto exit_rc;
437 if (w0A < w08)
438 goto exit_rc;
439 if (w0A > 0x3ff)
440 goto exit_rc;
441 if (w0C > 0x3ff)
442 goto exit_rc;
443 if (w06 > 0x3ff)
444 goto exit_rc;
445
446 EXIT_RC(RD16(s, 0x0c20010));
447 rc |= 0x10;
448 EXIT_RC(WR16(s, 0x0c20010, rc));
449
450 EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff));
451 EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1));
452 EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff));
453
454 quot = w0C / 113;
455 rem = w0C % 113;
456 if (quot <= 8) {
457 quot = 8 - quot;
458 } else {
459 quot = 0;
460 rem += 113;
461 }
462
463 EXIT_RC(WR16(s, 0x0c20024, quot));
464
465 i = fastIncrDecLUT_15273[rem / 8];
466 EXIT_RC(WR16(s, 0x0c2002d, i));
467 EXIT_RC(WR16(s, 0x0c2002e, i));
468
469 i = slowIncrDecLUT_15272[rem / 28];
470 EXIT_RC(WR16(s, 0x0c2002b, i));
471 rc = WR16(s, 0x0c2002c, i);
472exit_rc:
473 return rc;
474}
475
476static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
477{
478 u16 w04 = agc->w04;
479 u16 w06 = agc->w06;
480 int rc = -1;
481
482 pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06);
483
484 if (w04 > 0x3ff)
485 goto exit_rc;
486
487 switch (agc->d00) {
488 case 1:
489 if (w04 == 0x3ff)
490 w04 = 0x400;
491
492 EXIT_RC(WR16(s, 0x0c20036, w04));
493 s->config.w9C &= ~2;
494 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
495 EXIT_RC(RD16(s, 0x0c20010));
496 rc &= 0xbfdf;
497 EXIT_RC(WR16(s, 0x0c20010, rc));
498 EXIT_RC(RD16(s, 0x0c20013));
499 rc &= ~2;
500 break;
501 case 0:
502 /* loc_8000659 */
503 s->config.w9C &= ~2;
504 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
505 EXIT_RC(RD16(s, 0x0c20010));
506 rc &= 0xbfdf;
507 rc |= 0x4000;
508 EXIT_RC(WR16(s, 0x0c20010, rc));
509 EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f));
510 EXIT_RC(RD16(s, 0x0c20013));
511 rc &= ~2;
512 break;
513 default:
514 s->config.w9C |= 2;
515 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
516 EXIT_RC(RD16(s, 0x0c20010));
517 rc &= 0xbfdf;
518 EXIT_RC(WR16(s, 0x0c20010, rc));
519
520 EXIT_RC(WR16(s, 0x0c20036, 0));
521
522 EXIT_RC(RD16(s, 0x0c20013));
523 rc |= 2;
524 }
525 rc = WR16(s, 0x0c20013, rc);
526
527exit_rc:
528 return rc;
529}
530
531static int GetLockStatus(struct drx397xD_state *s, int *lockstat)
532{
533 int rc;
534
535 *lockstat = 0;
536
537 rc = RD16(s, 0x082004b);
538 if (rc < 0)
539 return rc;
540
541 if (s->config.d60 != 2)
542 return 0;
543
544 if ((rc & 7) == 7)
545 *lockstat |= 1;
546 if ((rc & 3) == 3)
547 *lockstat |= 2;
548 if (rc & 1)
549 *lockstat |= 4;
550 return 0;
551}
552
553static int CorrectSysClockDeviation(struct drx397xD_state *s)
554{
555 int rc = -EINVAL;
556 int lockstat;
557 u32 clk, clk_limit;
558
559 pr_debug("%s\n", __func__);
560
561 if (s->config.d5C == 0) {
562 EXIT_RC(WR16(s, 0x08200e8, 0x010));
563 EXIT_RC(WR16(s, 0x08200e9, 0x113));
564 s->config.d5C = 1;
565 return rc;
566 }
567 if (s->config.d5C != 1)
568 goto exit_rc;
569
570 rc = RD16(s, 0x0820048);
571
572 rc = GetLockStatus(s, &lockstat);
573 if (rc < 0)
574 goto exit_rc;
575 if ((lockstat & 1) == 0)
576 goto exit_rc;
577
578 EXIT_RC(WR16(s, 0x0420033, 0x200));
579 EXIT_RC(WR16(s, 0x0420034, 0xc5));
580 EXIT_RC(WR16(s, 0x0420035, 0x10));
581 EXIT_RC(WR16(s, 0x0420036, 0x1));
582 EXIT_RC(WR16(s, 0x0420037, 0xa));
583 EXIT_RC(HI_Command(s, 6));
584 EXIT_RC(RD16(s, 0x0420040));
585 clk = rc;
586 EXIT_RC(RD16(s, 0x0420041));
587 clk |= rc << 16;
588
589 if (clk <= 0x26ffff)
590 goto exit_rc;
591 if (clk > 0x610000)
592 goto exit_rc;
593
594 if (!s->bandwidth_parm)
595 return -EINVAL;
596
597 /* round & convert to Hz */
598 clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21;
599 clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000;
600
601 if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
602 s->f_osc = clk;
603 pr_debug("%s: osc %d %d [Hz]\n", __func__,
604 s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
605 }
606 rc = WR16(s, 0x08200e8, 0);
607
608exit_rc:
609 return rc;
610}
611
612static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
613{
614 int rc, si, bp;
615
616 pr_debug("%s\n", __func__);
617
618 si = s->config.wA0;
619 if (s->config.w98 == 0) {
620 si |= 1;
621 bp = 0;
622 } else {
623 si &= ~1;
624 bp = 0x200;
625 }
626 if (s->config.w9A == 0)
627 si |= 0x80;
628 else
629 si &= ~0x80;
630
631 EXIT_RC(WR16(s, 0x2150045, 0));
632 EXIT_RC(WR16(s, 0x2150010, si));
633 EXIT_RC(WR16(s, 0x2150011, bp));
634 rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
635
636exit_rc:
637 return rc;
638}
639
640static int drx_tune(struct drx397xD_state *s,
641 struct dvb_frontend_parameters *fep)
642{
643 u16 v22 = 0;
644 u16 v1C = 0;
645 u16 v1A = 0;
646 u16 v18 = 0;
647 u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
648 u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
649
650 int rc, df_tuner = 0;
651 int a, b, c, d;
652 pr_debug("%s %d\n", __func__, s->config.d60);
653
654 if (s->config.d60 != 2)
655 goto set_tuner;
656 rc = CorrectSysClockDeviation(s);
657 if (rc < 0)
658 goto set_tuner;
659
660 s->config.d60 = 1;
661 rc = ConfigureMPEGOutput(s, 0);
662 if (rc < 0)
663 goto set_tuner;
664set_tuner:
665
666 rc = PLL_Set(s, fep, &df_tuner);
667 if (rc < 0) {
668 printk(KERN_ERR "Error in pll_set\n");
669 goto exit_rc;
670 }
671 msleep(200);
672
673 a = rc = RD16(s, 0x2150016);
674 if (rc < 0)
675 goto exit_rc;
676 b = rc = RD16(s, 0x2150010);
677 if (rc < 0)
678 goto exit_rc;
679 c = rc = RD16(s, 0x2150034);
680 if (rc < 0)
681 goto exit_rc;
682 d = rc = RD16(s, 0x2150035);
683 if (rc < 0)
684 goto exit_rc;
685 rc = WR16(s, 0x2150014, c);
686 rc = WR16(s, 0x2150015, d);
687 rc = WR16(s, 0x2150010, 0);
688 rc = WR16(s, 0x2150000, 2);
689 rc = WR16(s, 0x2150036, 0x0fff);
690 rc = WR16(s, 0x2150016, a);
691
692 rc = WR16(s, 0x2150010, 2);
693 rc = WR16(s, 0x2150007, 0);
694 rc = WR16(s, 0x2150000, 1);
695 rc = WR16(s, 0x2110000, 0);
696 rc = WR16(s, 0x0800000, 0);
697 rc = WR16(s, 0x2800000, 0);
698 rc = WR16(s, 0x2110010, 0x664);
699
700 rc = write_fw(s, DRXD_ResetECRAM);
701 rc = WR16(s, 0x2110000, 1);
702
703 rc = write_fw(s, DRXD_InitSC);
704 if (rc < 0)
705 goto exit_rc;
706
707 rc = SetCfgIfAgc(s, &s->config.ifagc);
708 if (rc < 0)
709 goto exit_rc;
710
711 rc = SetCfgRfAgc(s, &s->config.rfagc);
712 if (rc < 0)
713 goto exit_rc;
714
715 if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K)
716 v22 = 1;
717 switch (fep->u.ofdm.transmission_mode) {
718 case TRANSMISSION_MODE_8K:
719 edi = 1;
720 if (s->chip_rev == DRXD_FW_B1)
721 break;
722
723 rc = WR16(s, 0x2010010, 0);
724 if (rc < 0)
725 break;
726 v1C = 0x63;
727 v1A = 0x53;
728 v18 = 0x43;
729 break;
730 default:
731 edi = 0;
732 if (s->chip_rev == DRXD_FW_B1)
733 break;
734
735 rc = WR16(s, 0x2010010, 1);
736 if (rc < 0)
737 break;
738
739 v1C = 0x61;
740 v1A = 0x47;
741 v18 = 0x41;
742 }
743
744 switch (fep->u.ofdm.guard_interval) {
745 case GUARD_INTERVAL_1_4:
746 edi |= 0x0c;
747 break;
748 case GUARD_INTERVAL_1_8:
749 edi |= 0x08;
750 break;
751 case GUARD_INTERVAL_1_16:
752 edi |= 0x04;
753 break;
754 case GUARD_INTERVAL_1_32:
755 break;
756 default:
757 v22 |= 2;
758 }
759
760 ebx = 0;
761 ebp = 0;
762 v20 = 0;
763 v1E = 0;
764 v16 = 0;
765 v14 = 0;
766 v12 = 0;
767 v10 = 0;
768 v0E = 0;
769
770 switch (fep->u.ofdm.hierarchy_information) {
771 case HIERARCHY_1:
772 edi |= 0x40;
773 if (s->chip_rev == DRXD_FW_B1)
774 break;
775 rc = WR16(s, 0x1c10047, 1);
776 if (rc < 0)
777 goto exit_rc;
778 rc = WR16(s, 0x2010012, 1);
779 if (rc < 0)
780 goto exit_rc;
781 ebx = 0x19f;
782 ebp = 0x1fb;
783 v20 = 0x0c0;
784 v1E = 0x195;
785 v16 = 0x1d6;
786 v14 = 0x1ef;
787 v12 = 4;
788 v10 = 5;
789 v0E = 5;
790 break;
791 case HIERARCHY_2:
792 edi |= 0x80;
793 if (s->chip_rev == DRXD_FW_B1)
794 break;
795 rc = WR16(s, 0x1c10047, 2);
796 if (rc < 0)
797 goto exit_rc;
798 rc = WR16(s, 0x2010012, 2);
799 if (rc < 0)
800 goto exit_rc;
801 ebx = 0x08f;
802 ebp = 0x12f;
803 v20 = 0x0c0;
804 v1E = 0x11e;
805 v16 = 0x1d6;
806 v14 = 0x15e;
807 v12 = 4;
808 v10 = 5;
809 v0E = 5;
810 break;
811 case HIERARCHY_4:
812 edi |= 0xc0;
813 if (s->chip_rev == DRXD_FW_B1)
814 break;
815 rc = WR16(s, 0x1c10047, 3);
816 if (rc < 0)
817 goto exit_rc;
818 rc = WR16(s, 0x2010012, 3);
819 if (rc < 0)
820 goto exit_rc;
821 ebx = 0x14d;
822 ebp = 0x197;
823 v20 = 0x0c0;
824 v1E = 0x1ce;
825 v16 = 0x1d6;
826 v14 = 0x11a;
827 v12 = 4;
828 v10 = 6;
829 v0E = 5;
830 break;
831 default:
832 v22 |= 8;
833 if (s->chip_rev == DRXD_FW_B1)
834 break;
835 rc = WR16(s, 0x1c10047, 0);
836 if (rc < 0)
837 goto exit_rc;
838 rc = WR16(s, 0x2010012, 0);
839 if (rc < 0)
840 goto exit_rc;
841 /* QPSK QAM16 QAM64 */
842 ebx = 0x19f; /* 62 */
843 ebp = 0x1fb; /* 15 */
844 v20 = 0x16a; /* 62 */
845 v1E = 0x195; /* 62 */
846 v16 = 0x1bb; /* 15 */
847 v14 = 0x1ef; /* 15 */
848 v12 = 5; /* 16 */
849 v10 = 5; /* 16 */
850 v0E = 5; /* 16 */
851 }
852
853 switch (fep->u.ofdm.constellation) {
854 default:
855 v22 |= 4;
856 case QPSK:
857 if (s->chip_rev == DRXD_FW_B1)
858 break;
859
860 rc = WR16(s, 0x1c10046, 0);
861 if (rc < 0)
862 goto exit_rc;
863 rc = WR16(s, 0x2010011, 0);
864 if (rc < 0)
865 goto exit_rc;
866 rc = WR16(s, 0x201001a, 0x10);
867 if (rc < 0)
868 goto exit_rc;
869 rc = WR16(s, 0x201001b, 0);
870 if (rc < 0)
871 goto exit_rc;
872 rc = WR16(s, 0x201001c, 0);
873 if (rc < 0)
874 goto exit_rc;
875 rc = WR16(s, 0x1c10062, v20);
876 if (rc < 0)
877 goto exit_rc;
878 rc = WR16(s, 0x1c1002a, v1C);
879 if (rc < 0)
880 goto exit_rc;
881 rc = WR16(s, 0x1c10015, v16);
882 if (rc < 0)
883 goto exit_rc;
884 rc = WR16(s, 0x1c10016, v12);
885 if (rc < 0)
886 goto exit_rc;
887 break;
888 case QAM_16:
889 edi |= 0x10;
890 if (s->chip_rev == DRXD_FW_B1)
891 break;
892
893 rc = WR16(s, 0x1c10046, 1);
894 if (rc < 0)
895 goto exit_rc;
896 rc = WR16(s, 0x2010011, 1);
897 if (rc < 0)
898 goto exit_rc;
899 rc = WR16(s, 0x201001a, 0x10);
900 if (rc < 0)
901 goto exit_rc;
902 rc = WR16(s, 0x201001b, 4);
903 if (rc < 0)
904 goto exit_rc;
905 rc = WR16(s, 0x201001c, 0);
906 if (rc < 0)
907 goto exit_rc;
908 rc = WR16(s, 0x1c10062, v1E);
909 if (rc < 0)
910 goto exit_rc;
911 rc = WR16(s, 0x1c1002a, v1A);
912 if (rc < 0)
913 goto exit_rc;
914 rc = WR16(s, 0x1c10015, v14);
915 if (rc < 0)
916 goto exit_rc;
917 rc = WR16(s, 0x1c10016, v10);
918 if (rc < 0)
919 goto exit_rc;
920 break;
921 case QAM_64:
922 edi |= 0x20;
923 rc = WR16(s, 0x1c10046, 2);
924 if (rc < 0)
925 goto exit_rc;
926 rc = WR16(s, 0x2010011, 2);
927 if (rc < 0)
928 goto exit_rc;
929 rc = WR16(s, 0x201001a, 0x20);
930 if (rc < 0)
931 goto exit_rc;
932 rc = WR16(s, 0x201001b, 8);
933 if (rc < 0)
934 goto exit_rc;
935 rc = WR16(s, 0x201001c, 2);
936 if (rc < 0)
937 goto exit_rc;
938 rc = WR16(s, 0x1c10062, ebx);
939 if (rc < 0)
940 goto exit_rc;
941 rc = WR16(s, 0x1c1002a, v18);
942 if (rc < 0)
943 goto exit_rc;
944 rc = WR16(s, 0x1c10015, ebp);
945 if (rc < 0)
946 goto exit_rc;
947 rc = WR16(s, 0x1c10016, v0E);
948 if (rc < 0)
949 goto exit_rc;
950 break;
951 }
952
953 if (s->config.s20d24 == 1) {
954 rc = WR16(s, 0x2010013, 0);
955 } else {
956 rc = WR16(s, 0x2010013, 1);
957 edi |= 0x1000;
958 }
959
960 switch (fep->u.ofdm.code_rate_HP) {
961 default:
962 v22 |= 0x10;
963 case FEC_1_2:
964 if (s->chip_rev == DRXD_FW_B1)
965 break;
966 rc = WR16(s, 0x2090011, 0);
967 break;
968 case FEC_2_3:
969 edi |= 0x200;
970 if (s->chip_rev == DRXD_FW_B1)
971 break;
972 rc = WR16(s, 0x2090011, 1);
973 break;
974 case FEC_3_4:
975 edi |= 0x400;
976 if (s->chip_rev == DRXD_FW_B1)
977 break;
978 rc = WR16(s, 0x2090011, 2);
979 break;
980 case FEC_5_6: /* 5 */
981 edi |= 0x600;
982 if (s->chip_rev == DRXD_FW_B1)
983 break;
984 rc = WR16(s, 0x2090011, 3);
985 break;
986 case FEC_7_8: /* 7 */
987 edi |= 0x800;
988 if (s->chip_rev == DRXD_FW_B1)
989 break;
990 rc = WR16(s, 0x2090011, 4);
991 break;
992 };
993 if (rc < 0)
994 goto exit_rc;
995
996 switch (fep->u.ofdm.bandwidth) {
997 default:
998 rc = -EINVAL;
999 goto exit_rc;
1000 case BANDWIDTH_8_MHZ: /* 0 */
1001 case BANDWIDTH_AUTO:
1002 rc = WR16(s, 0x0c2003f, 0x32);
1003 s->bandwidth_parm = ebx = 0x8b8249;
1004 edx = 0;
1005 break;
1006 case BANDWIDTH_7_MHZ:
1007 rc = WR16(s, 0x0c2003f, 0x3b);
1008 s->bandwidth_parm = ebx = 0x7a1200;
1009 edx = 0x4807;
1010 break;
1011 case BANDWIDTH_6_MHZ:
1012 rc = WR16(s, 0x0c2003f, 0x47);
1013 s->bandwidth_parm = ebx = 0x68a1b6;
1014 edx = 0x0f07;
1015 break;
1016 };
1017
1018 if (rc < 0)
1019 goto exit_rc;
1020
1021 rc = WR16(s, 0x08200ec, edx);
1022 if (rc < 0)
1023 goto exit_rc;
1024
1025 rc = RD16(s, 0x0820050);
1026 if (rc < 0)
1027 goto exit_rc;
1028 rc = WR16(s, 0x0820050, rc);
1029
1030 {
1031 /* Configure bandwidth specific factor */
1032 ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1),
1033 (u64)ebx) - 0x800000;
1034 EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff));
1035 EXIT_RC(WR16(s, 0x0c50011, ebx >> 16));
1036
1037 /* drx397xD oscillator calibration */
1038 ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) +
1039 (s->f_osc >> 1), (u64)s->f_osc);
1040 }
1041 ebx &= 0xfffffff;
1042 if (fep->inversion == INVERSION_ON)
1043 ebx = 0x10000000 - ebx;
1044
1045 EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff));
1046 EXIT_RC(WR16(s, 0x0c30011, ebx >> 16));
1047
1048 EXIT_RC(WR16(s, 0x0800000, 1));
1049 EXIT_RC(RD16(s, 0x0800000));
1050
1051
1052 EXIT_RC(SC_WaitForReady(s));
1053 EXIT_RC(WR16(s, 0x0820042, 0));
1054 EXIT_RC(WR16(s, 0x0820041, v22));
1055 EXIT_RC(WR16(s, 0x0820040, edi));
1056 EXIT_RC(SC_SendCommand(s, 3));
1057
1058 rc = RD16(s, 0x0800000);
1059
1060 SC_WaitForReady(s);
1061 WR16(s, 0x0820042, 0);
1062 WR16(s, 0x0820041, 1);
1063 WR16(s, 0x0820040, 1);
1064 SC_SendCommand(s, 1);
1065
1066
1067 rc = WR16(s, 0x2150000, 2);
1068 rc = WR16(s, 0x2150016, a);
1069 rc = WR16(s, 0x2150010, 4);
1070 rc = WR16(s, 0x2150036, 0);
1071 rc = WR16(s, 0x2150000, 1);
1072 s->config.d60 = 2;
1073
1074exit_rc:
1075 return rc;
1076}
1077
1078/*******************************************************************************
1079 * DVB interface
1080 ******************************************************************************/
1081
1082static int drx397x_init(struct dvb_frontend *fe)
1083{
1084 struct drx397xD_state *s = fe->demodulator_priv;
1085 int rc;
1086
1087 pr_debug("%s\n", __func__);
1088
1089 s->config.rfagc.d00 = 2; /* 0x7c */
1090 s->config.rfagc.w04 = 0;
1091 s->config.rfagc.w06 = 0x3ff;
1092
1093 s->config.ifagc.d00 = 0; /* 0x68 */
1094 s->config.ifagc.w04 = 0;
1095 s->config.ifagc.w06 = 140;
1096 s->config.ifagc.w08 = 0;
1097 s->config.ifagc.w0A = 0x3ff;
1098 s->config.ifagc.w0C = 0x388;
1099
1100 /* for signal strength calculations */
1101 s->config.ss76 = 820;
1102 s->config.ss78 = 2200;
1103 s->config.ss7A = 150;
1104
1105 /* HI_CfgCommand */
1106 s->config.w50 = 4;
1107 s->config.w52 = 9;
1108
1109 s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */
1110 s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */
1111 s->config.w92 = 12000;
1112
1113 s->config.w9C = 0x000e;
1114 s->config.w9E = 0x0000;
1115
1116 /* ConfigureMPEGOutput params */
1117 s->config.wA0 = 4;
1118 s->config.w98 = 1;
1119 s->config.w9A = 1;
1120
1121 /* get chip revision */
1122 rc = RD16(s, 0x2410019);
1123 if (rc < 0)
1124 return -ENODEV;
1125
1126 if (rc == 0) {
1127 printk(KERN_INFO "%s: chip revision A2\n", mod_name);
1128 rc = drx_load_fw(s, DRXD_FW_A2);
1129 } else {
1130
1131 rc = (rc >> 12) - 3;
1132 switch (rc) {
1133 case 1:
1134 s->flags |= F_SET_0D4h;
1135 case 0:
1136 case 4:
1137 s->flags |= F_SET_0D0h;
1138 break;
1139 case 2:
1140 case 5:
1141 break;
1142 case 3:
1143 s->flags |= F_SET_0D4h;
1144 break;
1145 default:
1146 return -ENODEV;
1147 };
1148 printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc);
1149 rc = drx_load_fw(s, DRXD_FW_B1);
1150 }
1151 if (rc < 0)
1152 goto error;
1153
1154 rc = WR16(s, 0x0420033, 0x3973);
1155 if (rc < 0)
1156 goto error;
1157
1158 rc = HI_Command(s, 2);
1159
1160 msleep(1);
1161
1162 if (s->chip_rev == DRXD_FW_A2) {
1163 rc = WR16(s, 0x043012d, 0x47F);
1164 if (rc < 0)
1165 goto error;
1166 }
1167 rc = WR16_E0(s, 0x0400000, 0);
1168 if (rc < 0)
1169 goto error;
1170
1171 if (s->config.w92 > 20000 || s->config.w92 % 4000) {
1172 printk(KERN_ERR "%s: invalid osc frequency\n", mod_name);
1173 rc = -1;
1174 goto error;
1175 }
1176
1177 rc = WR16(s, 0x2410010, 1);
1178 if (rc < 0)
1179 goto error;
1180 rc = WR16(s, 0x2410011, 0x15);
1181 if (rc < 0)
1182 goto error;
1183 rc = WR16(s, 0x2410012, s->config.w92 / 4000);
1184 if (rc < 0)
1185 goto error;
1186#ifdef ORIG_FW
1187 rc = WR16(s, 0x2410015, 2);
1188 if (rc < 0)
1189 goto error;
1190#endif
1191 rc = WR16(s, 0x2410017, 0x3973);
1192 if (rc < 0)
1193 goto error;
1194
1195 s->f_osc = s->config.f_osc * 1000; /* initial estimator */
1196
1197 s->config.w56 = 1;
1198
1199 rc = HI_CfgCommand(s);
1200 if (rc < 0)
1201 goto error;
1202
1203 rc = write_fw(s, DRXD_InitAtomicRead);
1204 if (rc < 0)
1205 goto error;
1206
1207 if (s->chip_rev == DRXD_FW_A2) {
1208 rc = WR16(s, 0x2150013, 0);
1209 if (rc < 0)
1210 goto error;
1211 }
1212
1213 rc = WR16_E0(s, 0x0400002, 0);
1214 if (rc < 0)
1215 goto error;
1216 rc = WR16(s, 0x0400002, 0);
1217 if (rc < 0)
1218 goto error;
1219
1220 if (s->chip_rev == DRXD_FW_A2) {
1221 rc = write_fw(s, DRXD_ResetCEFR);
1222 if (rc < 0)
1223 goto error;
1224 }
1225 rc = write_fw(s, DRXD_microcode);
1226 if (rc < 0)
1227 goto error;
1228
1229 s->config.w9C = 0x0e;
1230 if (s->flags & F_SET_0D0h) {
1231 s->config.w9C = 0;
1232 rc = RD16(s, 0x0c20010);
1233 if (rc < 0)
1234 goto write_DRXD_InitFE_1;
1235
1236 rc &= ~0x1000;
1237 rc = WR16(s, 0x0c20010, rc);
1238 if (rc < 0)
1239 goto write_DRXD_InitFE_1;
1240
1241 rc = RD16(s, 0x0c20011);
1242 if (rc < 0)
1243 goto write_DRXD_InitFE_1;
1244
1245 rc &= ~0x8;
1246 rc = WR16(s, 0x0c20011, rc);
1247 if (rc < 0)
1248 goto write_DRXD_InitFE_1;
1249
1250 rc = WR16(s, 0x0c20012, 1);
1251 }
1252
1253write_DRXD_InitFE_1:
1254
1255 rc = write_fw(s, DRXD_InitFE_1);
1256 if (rc < 0)
1257 goto error;
1258
1259 rc = 1;
1260 if (s->chip_rev == DRXD_FW_B1) {
1261 if (s->flags & F_SET_0D0h)
1262 rc = 0;
1263 } else {
1264 if (s->flags & F_SET_0D0h)
1265 rc = 4;
1266 }
1267
1268 rc = WR16(s, 0x0C20012, rc);
1269 if (rc < 0)
1270 goto error;
1271
1272 rc = WR16(s, 0x0C20013, s->config.w9E);
1273 if (rc < 0)
1274 goto error;
1275 rc = WR16(s, 0x0C20015, s->config.w9C);
1276 if (rc < 0)
1277 goto error;
1278
1279 rc = write_fw(s, DRXD_InitFE_2);
1280 if (rc < 0)
1281 goto error;
1282 rc = write_fw(s, DRXD_InitFT);
1283 if (rc < 0)
1284 goto error;
1285 rc = write_fw(s, DRXD_InitCP);
1286 if (rc < 0)
1287 goto error;
1288 rc = write_fw(s, DRXD_InitCE);
1289 if (rc < 0)
1290 goto error;
1291 rc = write_fw(s, DRXD_InitEQ);
1292 if (rc < 0)
1293 goto error;
1294 rc = write_fw(s, DRXD_InitEC);
1295 if (rc < 0)
1296 goto error;
1297 rc = write_fw(s, DRXD_InitSC);
1298 if (rc < 0)
1299 goto error;
1300
1301 rc = SetCfgIfAgc(s, &s->config.ifagc);
1302 if (rc < 0)
1303 goto error;
1304
1305 rc = SetCfgRfAgc(s, &s->config.rfagc);
1306 if (rc < 0)
1307 goto error;
1308
1309 rc = ConfigureMPEGOutput(s, 1);
1310 rc = WR16(s, 0x08201fe, 0x0017);
1311 rc = WR16(s, 0x08201ff, 0x0101);
1312
1313 s->config.d5C = 0;
1314 s->config.d60 = 1;
1315 s->config.d48 = 1;
1316
1317error:
1318 return rc;
1319}
1320
1321static int drx397x_get_frontend(struct dvb_frontend *fe,
1322 struct dvb_frontend_parameters *params)
1323{
1324 return 0;
1325}
1326
1327static int drx397x_set_frontend(struct dvb_frontend *fe,
1328 struct dvb_frontend_parameters *params)
1329{
1330 struct drx397xD_state *s = fe->demodulator_priv;
1331
1332 s->config.s20d24 = 1;
1333
1334 return drx_tune(s, params);
1335}
1336
1337static int drx397x_get_tune_settings(struct dvb_frontend *fe,
1338 struct dvb_frontend_tune_settings
1339 *fe_tune_settings)
1340{
1341 fe_tune_settings->min_delay_ms = 10000;
1342 fe_tune_settings->step_size = 0;
1343 fe_tune_settings->max_drift = 0;
1344
1345 return 0;
1346}
1347
1348static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status)
1349{
1350 struct drx397xD_state *s = fe->demodulator_priv;
1351 int lockstat;
1352
1353 GetLockStatus(s, &lockstat);
1354
1355 *status = 0;
1356 if (lockstat & 2) {
1357 CorrectSysClockDeviation(s);
1358 ConfigureMPEGOutput(s, 1);
1359 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
1360 }
1361 if (lockstat & 4)
1362 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
1363
1364 return 0;
1365}
1366
1367static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
1368{
1369 *ber = 0;
1370
1371 return 0;
1372}
1373
1374static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr)
1375{
1376 *snr = 0;
1377
1378 return 0;
1379}
1380
1381static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1382{
1383 struct drx397xD_state *s = fe->demodulator_priv;
1384 int rc;
1385
1386 if (s->config.ifagc.d00 == 2) {
1387 *strength = 0xffff;
1388 return 0;
1389 }
1390 rc = RD16(s, 0x0c20035);
1391 if (rc < 0) {
1392 *strength = 0;
1393 return 0;
1394 }
1395 rc &= 0x3ff;
1396 /* Signal strength is calculated using the following formula:
1397 *
1398 * a = 2200 * 150 / (2200 + 150);
1399 * a = a * 3300 / (a + 820);
1400 * b = 2200 * 3300 / (2200 + 820);
1401 * c = (((b-a) * rc) >> 10 + a) << 4;
1402 * strength = ~c & 0xffff;
1403 *
1404 * The following does the same but with less rounding errors:
1405 */
1406 *strength = ~(7720 + (rc * 30744 >> 10));
1407
1408 return 0;
1409}
1410
1411static int drx397x_read_ucblocks(struct dvb_frontend *fe,
1412 unsigned int *ucblocks)
1413{
1414 *ucblocks = 0;
1415
1416 return 0;
1417}
1418
1419static int drx397x_sleep(struct dvb_frontend *fe)
1420{
1421 return 0;
1422}
1423
1424static void drx397x_release(struct dvb_frontend *fe)
1425{
1426 struct drx397xD_state *s = fe->demodulator_priv;
1427 printk(KERN_INFO "%s: release demodulator\n", mod_name);
1428 if (s) {
1429 drx_release_fw(s);
1430 kfree(s);
1431 }
1432
1433}
1434
1435static struct dvb_frontend_ops drx397x_ops = {
1436
1437 .info = {
1438 .name = "Micronas DRX397xD DVB-T Frontend",
1439 .type = FE_OFDM,
1440 .frequency_min = 47125000,
1441 .frequency_max = 855250000,
1442 .frequency_stepsize = 166667,
1443 .frequency_tolerance = 0,
1444 .caps = /* 0x0C01B2EAE */
1445 FE_CAN_FEC_1_2 | /* = 0x2, */
1446 FE_CAN_FEC_2_3 | /* = 0x4, */
1447 FE_CAN_FEC_3_4 | /* = 0x8, */
1448 FE_CAN_FEC_5_6 | /* = 0x20, */
1449 FE_CAN_FEC_7_8 | /* = 0x80, */
1450 FE_CAN_FEC_AUTO | /* = 0x200, */
1451 FE_CAN_QPSK | /* = 0x400, */
1452 FE_CAN_QAM_16 | /* = 0x800, */
1453 FE_CAN_QAM_64 | /* = 0x2000, */
1454 FE_CAN_QAM_AUTO | /* = 0x10000, */
1455 FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */
1456 FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */
1457 FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */
1458 FE_CAN_RECOVER | /* = 0x40000000, */
1459 FE_CAN_MUTE_TS /* = 0x80000000 */
1460 },
1461
1462 .release = drx397x_release,
1463 .init = drx397x_init,
1464 .sleep = drx397x_sleep,
1465
1466 .set_frontend = drx397x_set_frontend,
1467 .get_tune_settings = drx397x_get_tune_settings,
1468 .get_frontend = drx397x_get_frontend,
1469
1470 .read_status = drx397x_read_status,
1471 .read_snr = drx397x_read_snr,
1472 .read_signal_strength = drx397x_read_signal_strength,
1473 .read_ber = drx397x_read_ber,
1474 .read_ucblocks = drx397x_read_ucblocks,
1475};
1476
1477struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
1478 struct i2c_adapter *i2c)
1479{
1480 struct drx397xD_state *state;
1481
1482 /* allocate memory for the internal state */
1483 state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
1484 if (!state)
1485 goto error;
1486
1487 /* setup the state */
1488 state->i2c = i2c;
1489 memcpy(&state->config, config, sizeof(struct drx397xD_config));
1490
1491 /* check if the demod is there */
1492 if (RD16(state, 0x2410019) < 0)
1493 goto error;
1494
1495 /* create dvb_frontend */
1496 memcpy(&state->frontend.ops, &drx397x_ops,
1497 sizeof(struct dvb_frontend_ops));
1498 state->frontend.demodulator_priv = state;
1499
1500 return &state->frontend;
1501error:
1502 kfree(state);
1503
1504 return NULL;
1505}
1506EXPORT_SYMBOL(drx397xD_attach);
1507
1508MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
1509MODULE_AUTHOR("Henk Vergonet");
1510MODULE_LICENSE("GPL");
1511
diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h
deleted file mode 100644
index ba05d17290c6..000000000000
--- a/drivers/media/dvb/frontends/drx397xD.h
+++ /dev/null
@@ -1,130 +0,0 @@
1/*
2 * Driver for Micronas DVB-T drx397xD demodulator
3 *
4 * Copyright (C) 2007 Henk vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef _DRX397XD_H_INCLUDED
23#define _DRX397XD_H_INCLUDED
24
25#include <linux/dvb/frontend.h>
26
27#define DRX_F_STEPSIZE 166667
28#define DRX_F_OFFSET 36000000
29
30#define I2C_ADR_C0(x) \
31( cpu_to_le32( \
32 (u32)( \
33 (((u32)(x) & (u32)0x000000ffUL) ) | \
34 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
35 (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \
36 ( (u32)0x00c00000UL) \
37 )) \
38)
39
40#define I2C_ADR_E0(x) \
41( cpu_to_le32( \
42 (u32)( \
43 (((u32)(x) & (u32)0x000000ffUL) ) | \
44 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
45 (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \
46 ( (u32)0x00e00000UL) \
47 )) \
48)
49
50struct drx397xD_CfgRfAgc /* 0x7c */
51{
52 int d00; /* 2 */
53 u16 w04;
54 u16 w06;
55};
56
57struct drx397xD_CfgIfAgc /* 0x68 */
58{
59 int d00; /* 0 */
60 u16 w04; /* 0 */
61 u16 w06;
62 u16 w08;
63 u16 w0A;
64 u16 w0C;
65};
66
67struct drx397xD_s20 {
68 int d04;
69 u32 d18;
70 u32 d1C;
71 u32 d20;
72 u32 d14;
73 u32 d24;
74 u32 d0C;
75 u32 d08;
76};
77
78struct drx397xD_config
79{
80 /* demodulator's I2C address */
81 u8 demod_address; /* 0x0f */
82
83 struct drx397xD_CfgIfAgc ifagc; /* 0x68 */
84 struct drx397xD_CfgRfAgc rfagc; /* 0x7c */
85 u32 s20d24;
86
87 /* HI_CfgCommand parameters */
88 u16 w50, w52, /* w54, */ w56;
89
90 int d5C;
91 int d60;
92 int d48;
93 int d28;
94
95 u32 f_if; /* d14: intermediate frequency [Hz] */
96 /* 36000000 on Cinergy 2400i DT */
97 /* 42800000 on Pinnacle Hybrid PRO 330e */
98
99 u16 f_osc; /* s66: 48000 oscillator frequency [kHz] */
100
101 u16 w92; /* 20000 */
102
103 u16 wA0;
104 u16 w98;
105 u16 w9A;
106
107 u16 w9C; /* 0xe0 */
108 u16 w9E; /* 0x00 */
109
110 /* used for signal strength calculations in
111 drx397x_read_signal_strength
112 */
113 u16 ss78; // 2200
114 u16 ss7A; // 150
115 u16 ss76; // 820
116};
117
118#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE))
119extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
120 struct i2c_adapter *i2c);
121#else
122static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
123 struct i2c_adapter *i2c)
124{
125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
126 return NULL;
127}
128#endif /* CONFIG_DVB_DRX397XD */
129
130#endif /* _DRX397XD_H_INCLUDED */
diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h
deleted file mode 100644
index c8b44c1e807f..000000000000
--- a/drivers/media/dvb/frontends/drx397xD_fw.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Firmware definitions for Micronas drx397xD
3 *
4 * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifdef _FW_ENTRY
21 _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0, DRXD_FW_A2 ),
22 _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1, DRXD_FW_B1 ),
23#undef _FW_ENTRY
24#endif /* _FW_ENTRY */
25
26#ifdef _BLOB_ENTRY
27 _BLOB_ENTRY("InitAtomicRead", DRXD_InitAtomicRead = 0 ),
28 _BLOB_ENTRY("InitCE", DRXD_InitCE ),
29 _BLOB_ENTRY("InitCP", DRXD_InitCP ),
30 _BLOB_ENTRY("InitEC", DRXD_InitEC ),
31 _BLOB_ENTRY("InitEQ", DRXD_InitEQ ),
32 _BLOB_ENTRY("InitFE_1", DRXD_InitFE_1 ),
33 _BLOB_ENTRY("InitFE_2", DRXD_InitFE_2 ),
34 _BLOB_ENTRY("InitFT", DRXD_InitFT ),
35 _BLOB_ENTRY("InitSC", DRXD_InitSC ),
36 _BLOB_ENTRY("ResetCEFR", DRXD_ResetCEFR ),
37 _BLOB_ENTRY("ResetECRAM", DRXD_ResetECRAM ),
38 _BLOB_ENTRY("microcode", DRXD_microcode ),
39#undef _BLOB_ENTRY
40#endif /* _BLOB_ENTRY */
diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb/frontends/drxd.h
new file mode 100644
index 000000000000..7113535844f2
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd.h
@@ -0,0 +1,61 @@
1/*
2 * drxd.h: DRXD DVB-T demodulator driver
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef _DRXD_H_
25#define _DRXD_H_
26
27#include <linux/types.h>
28#include <linux/i2c.h>
29
30struct drxd_config {
31 u8 index;
32
33 u8 pll_address;
34 u8 pll_type;
35#define DRXD_PLL_NONE 0
36#define DRXD_PLL_DTT7520X 1
37#define DRXD_PLL_MT3X0823 2
38
39 u32 clock;
40 u8 insert_rs_byte;
41
42 u8 demod_address;
43 u8 demoda_address;
44 u8 demod_revision;
45
46 /* If the tuner is not behind an i2c gate, be sure to flip this bit
47 or else the i2c bus could get wedged */
48 u8 disable_i2c_gate_ctrl;
49
50 u32 IF;
51 int (*pll_set) (void *priv, void *priv_params,
52 u8 pll_addr, u8 demoda_addr, s32 *off);
53 s16(*osc_deviation) (void *priv, s16 dev, int flag);
54};
55
56extern
57struct dvb_frontend *drxd_attach(const struct drxd_config *config,
58 void *priv, struct i2c_adapter *i2c,
59 struct device *dev);
60extern int drxd_config_i2c(struct dvb_frontend *, int);
61#endif
diff --git a/drivers/media/dvb/frontends/drxd_firm.c b/drivers/media/dvb/frontends/drxd_firm.c
new file mode 100644
index 000000000000..5418b0b1dadc
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_firm.c
@@ -0,0 +1,929 @@
1/*
2 * drxd_firm.c : DRXD firmware tables
3 *
4 * Copyright (C) 2006-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24/* TODO: generate this file with a script from a settings file */
25
26/* Contains A2 firmware version: 1.4.2
27 * Contains B1 firmware version: 3.3.33
28 * Contains settings from driver 1.4.23
29*/
30
31#include "drxd_firm.h"
32
33#define ADDRESS(x) ((x) & 0xFF), (((x)>>8) & 0xFF), (((x)>>16) & 0xFF), (((x)>>24) & 0xFF)
34#define LENGTH(x) ((x) & 0xFF), (((x)>>8) & 0xFF)
35
36/* Is written via block write, must be little endian */
37#define DATA16(x) ((x) & 0xFF), (((x)>>8) & 0xFF)
38
39#define WRBLOCK(a, l) ADDRESS(a), LENGTH(l)
40#define WR16(a, d) ADDRESS(a), LENGTH(1), DATA16(d)
41
42#define END_OF_TABLE 0xFF, 0xFF, 0xFF, 0xFF
43
44/* HI firmware patches */
45
46#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
47#define HI_TR_FUNC_SIZE 9 /* size of this function in instruction words */
48
49u8 DRXD_InitAtomicRead[] = {
50 WRBLOCK(HI_TR_FUNC_ADDR, HI_TR_FUNC_SIZE),
51 0x26, 0x00, /* 0 -> ring.rdy; */
52 0x60, 0x04, /* r0rami.dt -> ring.xba; */
53 0x61, 0x04, /* r0rami.dt -> ring.xad; */
54 0xE3, 0x07, /* HI_RA_RAM_USR_BEGIN -> ring.iad; */
55 0x40, 0x00, /* (long immediate) */
56 0x64, 0x04, /* r0rami.dt -> ring.len; */
57 0x65, 0x04, /* r0rami.dt -> ring.ctl; */
58 0x26, 0x00, /* 0 -> ring.rdy; */
59 0x38, 0x00, /* 0 -> jumps.ad; */
60 END_OF_TABLE
61};
62
63/* Pins D0 and D1 of the parallel MPEG output can be used
64 to set the I2C address of a device. */
65
66#define HI_RST_FUNC_ADDR (HI_IF_RAM_USR_BEGIN__A + HI_TR_FUNC_SIZE)
67#define HI_RST_FUNC_SIZE 54 /* size of this function in instruction words */
68
69/* D0 Version */
70u8 DRXD_HiI2cPatch_1[] = {
71 WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
72 0xC8, 0x07, 0x01, 0x00, /* MASK -> reg0.dt; */
73 0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
74 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
75 0xA2, 0x00, /* M_BNK_ID_DAT -> ring.iba; */
76 0x23, 0x00, /* &data -> ring.iad; */
77 0x24, 0x00, /* 0 -> ring.len; */
78 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
79 0x26, 0x00, /* 0 -> ring.rdy; */
80 0x42, 0x00, /* &data+1 -> w0ram.ad; */
81 0xC0, 0x07, 0xFF, 0x0F, /* -1 -> w0ram.dt; */
82 0x63, 0x00, /* &data+1 -> ring.iad; */
83 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
84 0x26, 0x00, /* 0 -> ring.rdy; */
85 0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad; */
86 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
87 0x26, 0x00, /* 0 -> ring.rdy; */
88 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
89 0x23, 0x00, /* &data -> ring.iad; */
90 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
91 0x26, 0x00, /* 0 -> ring.rdy; */
92 0x42, 0x00, /* &data+1 -> w0ram.ad; */
93 0x0F, 0x04, /* r0ram.dt -> and.op; */
94 0x1C, 0x06, /* reg0.dt -> and.tr; */
95 0xCF, 0x04, /* and.rs -> add.op; */
96 0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr; */
97 0xD0, 0x04, /* add.rs -> add.tr; */
98 0xC8, 0x04, /* add.rs -> reg0.dt; */
99 0x60, 0x00, /* reg0.dt -> w0ram.dt; */
100 0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad; */
101 0x01, 0x00, /* 0 -> w0rami.dt; */
102 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
103 0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad; */
104 0x01, 0x00, /* 0 -> w0rami.dt; */
105 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
106 0xC2, 0x07, 0x30, 0x00, /* CMD_BASE -> w0rami.ad; */
107 0x01, 0x00, /* 0 -> w0rami.dt; */
108 0x01, 0x00, /* 0 -> w0rami.dt; */
109 0x01, 0x00, /* 0 -> w0rami.dt; */
110 0x68, 0x00, /* M_IC_SEL_PT1 -> i2c.sel; */
111 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
112 0x28, 0x00, /* M_IC_SEL_PT0 -> i2c.sel; */
113 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
114 0xF8, 0x07, 0x2F, 0x00, /* 0x2F -> jumps.ad; */
115
116 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
117 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
118 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
119 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
120 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
121 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
122 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
123 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
124
125 /* Force quick and dirty reset */
126 WR16(B_HI_CT_REG_COMM_STATE__A, 0),
127 END_OF_TABLE
128};
129
130/* D0,D1 Version */
131u8 DRXD_HiI2cPatch_3[] = {
132 WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
133 0xC8, 0x07, 0x03, 0x00, /* MASK -> reg0.dt; */
134 0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
135 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
136 0xA2, 0x00, /* M_BNK_ID_DAT -> ring.iba; */
137 0x23, 0x00, /* &data -> ring.iad; */
138 0x24, 0x00, /* 0 -> ring.len; */
139 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
140 0x26, 0x00, /* 0 -> ring.rdy; */
141 0x42, 0x00, /* &data+1 -> w0ram.ad; */
142 0xC0, 0x07, 0xFF, 0x0F, /* -1 -> w0ram.dt; */
143 0x63, 0x00, /* &data+1 -> ring.iad; */
144 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
145 0x26, 0x00, /* 0 -> ring.rdy; */
146 0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad; */
147 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
148 0x26, 0x00, /* 0 -> ring.rdy; */
149 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
150 0x23, 0x00, /* &data -> ring.iad; */
151 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
152 0x26, 0x00, /* 0 -> ring.rdy; */
153 0x42, 0x00, /* &data+1 -> w0ram.ad; */
154 0x0F, 0x04, /* r0ram.dt -> and.op; */
155 0x1C, 0x06, /* reg0.dt -> and.tr; */
156 0xCF, 0x04, /* and.rs -> add.op; */
157 0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr; */
158 0xD0, 0x04, /* add.rs -> add.tr; */
159 0xC8, 0x04, /* add.rs -> reg0.dt; */
160 0x60, 0x00, /* reg0.dt -> w0ram.dt; */
161 0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad; */
162 0x01, 0x00, /* 0 -> w0rami.dt; */
163 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
164 0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad; */
165 0x01, 0x00, /* 0 -> w0rami.dt; */
166 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
167 0xC2, 0x07, 0x30, 0x00, /* CMD_BASE -> w0rami.ad; */
168 0x01, 0x00, /* 0 -> w0rami.dt; */
169 0x01, 0x00, /* 0 -> w0rami.dt; */
170 0x01, 0x00, /* 0 -> w0rami.dt; */
171 0x68, 0x00, /* M_IC_SEL_PT1 -> i2c.sel; */
172 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
173 0x28, 0x00, /* M_IC_SEL_PT0 -> i2c.sel; */
174 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
175 0xF8, 0x07, 0x2F, 0x00, /* 0x2F -> jumps.ad; */
176
177 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
178 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
179 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
180 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
181 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
182 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
183 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
184 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
185
186 /* Force quick and dirty reset */
187 WR16(B_HI_CT_REG_COMM_STATE__A, 0),
188 END_OF_TABLE
189};
190
191u8 DRXD_ResetCEFR[] = {
192 WRBLOCK(CE_REG_FR_TREAL00__A, 57),
193 0x52, 0x00, /* CE_REG_FR_TREAL00__A */
194 0x00, 0x00, /* CE_REG_FR_TIMAG00__A */
195 0x52, 0x00, /* CE_REG_FR_TREAL01__A */
196 0x00, 0x00, /* CE_REG_FR_TIMAG01__A */
197 0x52, 0x00, /* CE_REG_FR_TREAL02__A */
198 0x00, 0x00, /* CE_REG_FR_TIMAG02__A */
199 0x52, 0x00, /* CE_REG_FR_TREAL03__A */
200 0x00, 0x00, /* CE_REG_FR_TIMAG03__A */
201 0x52, 0x00, /* CE_REG_FR_TREAL04__A */
202 0x00, 0x00, /* CE_REG_FR_TIMAG04__A */
203 0x52, 0x00, /* CE_REG_FR_TREAL05__A */
204 0x00, 0x00, /* CE_REG_FR_TIMAG05__A */
205 0x52, 0x00, /* CE_REG_FR_TREAL06__A */
206 0x00, 0x00, /* CE_REG_FR_TIMAG06__A */
207 0x52, 0x00, /* CE_REG_FR_TREAL07__A */
208 0x00, 0x00, /* CE_REG_FR_TIMAG07__A */
209 0x52, 0x00, /* CE_REG_FR_TREAL08__A */
210 0x00, 0x00, /* CE_REG_FR_TIMAG08__A */
211 0x52, 0x00, /* CE_REG_FR_TREAL09__A */
212 0x00, 0x00, /* CE_REG_FR_TIMAG09__A */
213 0x52, 0x00, /* CE_REG_FR_TREAL10__A */
214 0x00, 0x00, /* CE_REG_FR_TIMAG10__A */
215 0x52, 0x00, /* CE_REG_FR_TREAL11__A */
216 0x00, 0x00, /* CE_REG_FR_TIMAG11__A */
217
218 0x52, 0x00, /* CE_REG_FR_MID_TAP__A */
219
220 0x0B, 0x00, /* CE_REG_FR_SQS_G00__A */
221 0x0B, 0x00, /* CE_REG_FR_SQS_G01__A */
222 0x0B, 0x00, /* CE_REG_FR_SQS_G02__A */
223 0x0B, 0x00, /* CE_REG_FR_SQS_G03__A */
224 0x0B, 0x00, /* CE_REG_FR_SQS_G04__A */
225 0x0B, 0x00, /* CE_REG_FR_SQS_G05__A */
226 0x0B, 0x00, /* CE_REG_FR_SQS_G06__A */
227 0x0B, 0x00, /* CE_REG_FR_SQS_G07__A */
228 0x0B, 0x00, /* CE_REG_FR_SQS_G08__A */
229 0x0B, 0x00, /* CE_REG_FR_SQS_G09__A */
230 0x0B, 0x00, /* CE_REG_FR_SQS_G10__A */
231 0x0B, 0x00, /* CE_REG_FR_SQS_G11__A */
232 0x0B, 0x00, /* CE_REG_FR_SQS_G12__A */
233
234 0xFF, 0x01, /* CE_REG_FR_RIO_G00__A */
235 0x90, 0x01, /* CE_REG_FR_RIO_G01__A */
236 0x0B, 0x01, /* CE_REG_FR_RIO_G02__A */
237 0xC8, 0x00, /* CE_REG_FR_RIO_G03__A */
238 0xA0, 0x00, /* CE_REG_FR_RIO_G04__A */
239 0x85, 0x00, /* CE_REG_FR_RIO_G05__A */
240 0x72, 0x00, /* CE_REG_FR_RIO_G06__A */
241 0x64, 0x00, /* CE_REG_FR_RIO_G07__A */
242 0x59, 0x00, /* CE_REG_FR_RIO_G08__A */
243 0x50, 0x00, /* CE_REG_FR_RIO_G09__A */
244 0x49, 0x00, /* CE_REG_FR_RIO_G10__A */
245
246 0x10, 0x00, /* CE_REG_FR_MODE__A */
247 0x78, 0x00, /* CE_REG_FR_SQS_TRH__A */
248 0x00, 0x00, /* CE_REG_FR_RIO_GAIN__A */
249 0x00, 0x02, /* CE_REG_FR_BYPASS__A */
250 0x0D, 0x00, /* CE_REG_FR_PM_SET__A */
251 0x07, 0x00, /* CE_REG_FR_ERR_SH__A */
252 0x04, 0x00, /* CE_REG_FR_MAN_SH__A */
253 0x06, 0x00, /* CE_REG_FR_TAP_SH__A */
254
255 END_OF_TABLE
256};
257
258u8 DRXD_InitFEA2_1[] = {
259 WRBLOCK(FE_AD_REG_PD__A, 3),
260 0x00, 0x00, /* FE_AD_REG_PD__A */
261 0x01, 0x00, /* FE_AD_REG_INVEXT__A */
262 0x00, 0x00, /* FE_AD_REG_CLKNEG__A */
263
264 WRBLOCK(FE_AG_REG_DCE_AUR_CNT__A, 2),
265 0x10, 0x00, /* FE_AG_REG_DCE_AUR_CNT__A */
266 0x10, 0x00, /* FE_AG_REG_DCE_RUR_CNT__A */
267
268 WRBLOCK(FE_AG_REG_ACE_AUR_CNT__A, 2),
269 0x0E, 0x00, /* FE_AG_REG_ACE_AUR_CNT__A */
270 0x00, 0x00, /* FE_AG_REG_ACE_RUR_CNT__A */
271
272 WRBLOCK(FE_AG_REG_EGC_FLA_RGN__A, 5),
273 0x04, 0x00, /* FE_AG_REG_EGC_FLA_RGN__A */
274 0x1F, 0x00, /* FE_AG_REG_EGC_SLO_RGN__A */
275 0x00, 0x00, /* FE_AG_REG_EGC_JMP_PSN__A */
276 0x00, 0x00, /* FE_AG_REG_EGC_FLA_INC__A */
277 0x00, 0x00, /* FE_AG_REG_EGC_FLA_DEC__A */
278
279 WRBLOCK(FE_AG_REG_GC1_AGC_MAX__A, 2),
280 0xFF, 0x01, /* FE_AG_REG_GC1_AGC_MAX__A */
281 0x00, 0xFE, /* FE_AG_REG_GC1_AGC_MIN__A */
282
283 WRBLOCK(FE_AG_REG_IND_WIN__A, 29),
284 0x00, 0x00, /* FE_AG_REG_IND_WIN__A */
285 0x05, 0x00, /* FE_AG_REG_IND_THD_LOL__A */
286 0x0F, 0x00, /* FE_AG_REG_IND_THD_HIL__A */
287 0x00, 0x00, /* FE_AG_REG_IND_DEL__A don't care */
288 0x1E, 0x00, /* FE_AG_REG_IND_PD1_WRI__A */
289 0x0C, 0x00, /* FE_AG_REG_PDA_AUR_CNT__A */
290 0x00, 0x00, /* FE_AG_REG_PDA_RUR_CNT__A */
291 0x00, 0x00, /* FE_AG_REG_PDA_AVE_DAT__A don't care */
292 0x00, 0x00, /* FE_AG_REG_PDC_RUR_CNT__A */
293 0x01, 0x00, /* FE_AG_REG_PDC_SET_LVL__A */
294 0x02, 0x00, /* FE_AG_REG_PDC_FLA_RGN__A */
295 0x00, 0x00, /* FE_AG_REG_PDC_JMP_PSN__A don't care */
296 0xFF, 0xFF, /* FE_AG_REG_PDC_FLA_STP__A */
297 0xFF, 0xFF, /* FE_AG_REG_PDC_SLO_STP__A */
298 0x00, 0x1F, /* FE_AG_REG_PDC_PD2_WRI__A don't care */
299 0x00, 0x00, /* FE_AG_REG_PDC_MAP_DAT__A don't care */
300 0x02, 0x00, /* FE_AG_REG_PDC_MAX__A */
301 0x0C, 0x00, /* FE_AG_REG_TGA_AUR_CNT__A */
302 0x00, 0x00, /* FE_AG_REG_TGA_RUR_CNT__A */
303 0x00, 0x00, /* FE_AG_REG_TGA_AVE_DAT__A don't care */
304 0x00, 0x00, /* FE_AG_REG_TGC_RUR_CNT__A */
305 0x22, 0x00, /* FE_AG_REG_TGC_SET_LVL__A */
306 0x15, 0x00, /* FE_AG_REG_TGC_FLA_RGN__A */
307 0x00, 0x00, /* FE_AG_REG_TGC_JMP_PSN__A don't care */
308 0x01, 0x00, /* FE_AG_REG_TGC_FLA_STP__A */
309 0x0A, 0x00, /* FE_AG_REG_TGC_SLO_STP__A */
310 0x00, 0x00, /* FE_AG_REG_TGC_MAP_DAT__A don't care */
311 0x10, 0x00, /* FE_AG_REG_FGA_AUR_CNT__A */
312 0x10, 0x00, /* FE_AG_REG_FGA_RUR_CNT__A */
313
314 WRBLOCK(FE_AG_REG_BGC_FGC_WRI__A, 2),
315 0x00, 0x00, /* FE_AG_REG_BGC_FGC_WRI__A */
316 0x00, 0x00, /* FE_AG_REG_BGC_CGC_WRI__A */
317
318 WRBLOCK(FE_FD_REG_SCL__A, 3),
319 0x05, 0x00, /* FE_FD_REG_SCL__A */
320 0x03, 0x00, /* FE_FD_REG_MAX_LEV__A */
321 0x05, 0x00, /* FE_FD_REG_NR__A */
322
323 WRBLOCK(FE_CF_REG_SCL__A, 5),
324 0x16, 0x00, /* FE_CF_REG_SCL__A */
325 0x04, 0x00, /* FE_CF_REG_MAX_LEV__A */
326 0x06, 0x00, /* FE_CF_REG_NR__A */
327 0x00, 0x00, /* FE_CF_REG_IMP_VAL__A */
328 0x01, 0x00, /* FE_CF_REG_MEAS_VAL__A */
329
330 WRBLOCK(FE_CU_REG_FRM_CNT_RST__A, 2),
331 0x00, 0x08, /* FE_CU_REG_FRM_CNT_RST__A */
332 0x00, 0x00, /* FE_CU_REG_FRM_CNT_STR__A */
333
334 END_OF_TABLE
335};
336
337 /* with PGA */
338/* WR16COND( DRXD_WITH_PGA, FE_AG_REG_AG_PGA_MODE__A , 0x0004), */
339 /* without PGA */
340/* WR16COND( DRXD_WITHOUT_PGA, FE_AG_REG_AG_PGA_MODE__A , 0x0001), */
341/* WR16(FE_AG_REG_AG_AGC_SIO__A, (extAttr -> FeAgRegAgAgcSio), 0x0000 );*/
342/* WR16(FE_AG_REG_AG_PWD__A ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
343
344u8 DRXD_InitFEA2_2[] = {
345 WR16(FE_AG_REG_CDR_RUR_CNT__A, 0x0010),
346 WR16(FE_AG_REG_FGM_WRI__A, 48),
347 /* Activate measurement, activate scale */
348 WR16(FE_FD_REG_MEAS_VAL__A, 0x0001),
349
350 WR16(FE_CU_REG_COMM_EXEC__A, 0x0001),
351 WR16(FE_CF_REG_COMM_EXEC__A, 0x0001),
352 WR16(FE_IF_REG_COMM_EXEC__A, 0x0001),
353 WR16(FE_FD_REG_COMM_EXEC__A, 0x0001),
354 WR16(FE_FS_REG_COMM_EXEC__A, 0x0001),
355 WR16(FE_AD_REG_COMM_EXEC__A, 0x0001),
356 WR16(FE_AG_REG_COMM_EXEC__A, 0x0001),
357 WR16(FE_AG_REG_AG_MODE_LOP__A, 0x895E),
358
359 END_OF_TABLE
360};
361
362u8 DRXD_InitFEB1_1[] = {
363 WR16(B_FE_AD_REG_PD__A, 0x0000),
364 WR16(B_FE_AD_REG_CLKNEG__A, 0x0000),
365 WR16(B_FE_AG_REG_BGC_FGC_WRI__A, 0x0000),
366 WR16(B_FE_AG_REG_BGC_CGC_WRI__A, 0x0000),
367 WR16(B_FE_AG_REG_AG_MODE_LOP__A, 0x000a),
368 WR16(B_FE_AG_REG_IND_PD1_WRI__A, 35),
369 WR16(B_FE_AG_REG_IND_WIN__A, 0),
370 WR16(B_FE_AG_REG_IND_THD_LOL__A, 8),
371 WR16(B_FE_AG_REG_IND_THD_HIL__A, 8),
372 WR16(B_FE_CF_REG_IMP_VAL__A, 1),
373 WR16(B_FE_AG_REG_EGC_FLA_RGN__A, 7),
374 END_OF_TABLE
375};
376
377 /* with PGA */
378/* WR16(B_FE_AG_REG_AG_PGA_MODE__A , 0x0000, 0x0000); */
379 /* without PGA */
380/* WR16(B_FE_AG_REG_AG_PGA_MODE__A ,
381 B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);*/
382 /* WR16(B_FE_AG_REG_AG_AGC_SIO__A,(extAttr -> FeAgRegAgAgcSio), 0x0000 );*//*added HS 23-05-2005 */
383/* WR16(B_FE_AG_REG_AG_PWD__A ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
384
385u8 DRXD_InitFEB1_2[] = {
386 WR16(B_FE_COMM_EXEC__A, 0x0001),
387
388 /* RF-AGC setup */
389 WR16(B_FE_AG_REG_PDA_AUR_CNT__A, 0x0C),
390 WR16(B_FE_AG_REG_PDC_SET_LVL__A, 0x01),
391 WR16(B_FE_AG_REG_PDC_FLA_RGN__A, 0x02),
392 WR16(B_FE_AG_REG_PDC_FLA_STP__A, 0xFFFF),
393 WR16(B_FE_AG_REG_PDC_SLO_STP__A, 0xFFFF),
394 WR16(B_FE_AG_REG_PDC_MAX__A, 0x02),
395 WR16(B_FE_AG_REG_TGA_AUR_CNT__A, 0x0C),
396 WR16(B_FE_AG_REG_TGC_SET_LVL__A, 0x22),
397 WR16(B_FE_AG_REG_TGC_FLA_RGN__A, 0x15),
398 WR16(B_FE_AG_REG_TGC_FLA_STP__A, 0x01),
399 WR16(B_FE_AG_REG_TGC_SLO_STP__A, 0x0A),
400
401 WR16(B_FE_CU_REG_DIV_NFC_CLP__A, 0),
402 WR16(B_FE_CU_REG_CTR_NFC_OCR__A, 25000),
403 WR16(B_FE_CU_REG_CTR_NFC_ICR__A, 1),
404 END_OF_TABLE
405};
406
407u8 DRXD_InitCPA2[] = {
408 WRBLOCK(CP_REG_BR_SPL_OFFSET__A, 2),
409 0x07, 0x00, /* CP_REG_BR_SPL_OFFSET__A */
410 0x0A, 0x00, /* CP_REG_BR_STR_DEL__A */
411
412 WRBLOCK(CP_REG_RT_ANG_INC0__A, 4),
413 0x00, 0x00, /* CP_REG_RT_ANG_INC0__A */
414 0x00, 0x00, /* CP_REG_RT_ANG_INC1__A */
415 0x03, 0x00, /* CP_REG_RT_DETECT_ENA__A */
416 0x03, 0x00, /* CP_REG_RT_DETECT_TRH__A */
417
418 WRBLOCK(CP_REG_AC_NEXP_OFFS__A, 5),
419 0x32, 0x00, /* CP_REG_AC_NEXP_OFFS__A */
420 0x62, 0x00, /* CP_REG_AC_AVER_POW__A */
421 0x82, 0x00, /* CP_REG_AC_MAX_POW__A */
422 0x26, 0x00, /* CP_REG_AC_WEIGHT_MAN__A */
423 0x0F, 0x00, /* CP_REG_AC_WEIGHT_EXP__A */
424
425 WRBLOCK(CP_REG_AC_AMP_MODE__A, 2),
426 0x02, 0x00, /* CP_REG_AC_AMP_MODE__A */
427 0x01, 0x00, /* CP_REG_AC_AMP_FIX__A */
428
429 WR16(CP_REG_INTERVAL__A, 0x0005),
430 WR16(CP_REG_RT_EXP_MARG__A, 0x0004),
431 WR16(CP_REG_AC_ANG_MODE__A, 0x0003),
432
433 WR16(CP_REG_COMM_EXEC__A, 0x0001),
434 END_OF_TABLE
435};
436
437u8 DRXD_InitCPB1[] = {
438 WR16(B_CP_REG_BR_SPL_OFFSET__A, 0x0008),
439 WR16(B_CP_COMM_EXEC__A, 0x0001),
440 END_OF_TABLE
441};
442
443u8 DRXD_InitCEA2[] = {
444 WRBLOCK(CE_REG_AVG_POW__A, 4),
445 0x62, 0x00, /* CE_REG_AVG_POW__A */
446 0x78, 0x00, /* CE_REG_MAX_POW__A */
447 0x62, 0x00, /* CE_REG_ATT__A */
448 0x17, 0x00, /* CE_REG_NRED__A */
449
450 WRBLOCK(CE_REG_NE_ERR_SELECT__A, 2),
451 0x07, 0x00, /* CE_REG_NE_ERR_SELECT__A */
452 0xEB, 0xFF, /* CE_REG_NE_TD_CAL__A */
453
454 WRBLOCK(CE_REG_NE_MIXAVG__A, 2),
455 0x06, 0x00, /* CE_REG_NE_MIXAVG__A */
456 0x00, 0x00, /* CE_REG_NE_NUPD_OFS__A */
457
458 WRBLOCK(CE_REG_PE_NEXP_OFFS__A, 2),
459 0x00, 0x00, /* CE_REG_PE_NEXP_OFFS__A */
460 0x00, 0x00, /* CE_REG_PE_TIMESHIFT__A */
461
462 WRBLOCK(CE_REG_TP_A0_TAP_NEW__A, 3),
463 0x00, 0x01, /* CE_REG_TP_A0_TAP_NEW__A */
464 0x01, 0x00, /* CE_REG_TP_A0_TAP_NEW_VALID__A */
465 0x0E, 0x00, /* CE_REG_TP_A0_MU_LMS_STEP__A */
466
467 WRBLOCK(CE_REG_TP_A1_TAP_NEW__A, 3),
468 0x00, 0x00, /* CE_REG_TP_A1_TAP_NEW__A */
469 0x01, 0x00, /* CE_REG_TP_A1_TAP_NEW_VALID__A */
470 0x0A, 0x00, /* CE_REG_TP_A1_MU_LMS_STEP__A */
471
472 WRBLOCK(CE_REG_FI_SHT_INCR__A, 2),
473 0x12, 0x00, /* CE_REG_FI_SHT_INCR__A */
474 0x0C, 0x00, /* CE_REG_FI_EXP_NORM__A */
475
476 WRBLOCK(CE_REG_IR_INPUTSEL__A, 3),
477 0x00, 0x00, /* CE_REG_IR_INPUTSEL__A */
478 0x00, 0x00, /* CE_REG_IR_STARTPOS__A */
479 0xFF, 0x00, /* CE_REG_IR_NEXP_THRES__A */
480
481 WR16(CE_REG_TI_NEXP_OFFS__A, 0x0000),
482
483 END_OF_TABLE
484};
485
486u8 DRXD_InitCEB1[] = {
487 WR16(B_CE_REG_TI_PHN_ENABLE__A, 0x0001),
488 WR16(B_CE_REG_FR_PM_SET__A, 0x000D),
489
490 END_OF_TABLE
491};
492
493u8 DRXD_InitEQA2[] = {
494 WRBLOCK(EQ_REG_OT_QNT_THRES0__A, 4),
495 0x1E, 0x00, /* EQ_REG_OT_QNT_THRES0__A */
496 0x1F, 0x00, /* EQ_REG_OT_QNT_THRES1__A */
497 0x06, 0x00, /* EQ_REG_OT_CSI_STEP__A */
498 0x02, 0x00, /* EQ_REG_OT_CSI_OFFSET__A */
499
500 WR16(EQ_REG_TD_REQ_SMB_CNT__A, 0x0200),
501 WR16(EQ_REG_IS_CLIP_EXP__A, 0x001F),
502 WR16(EQ_REG_SN_OFFSET__A, (u16) (-7)),
503 WR16(EQ_REG_RC_SEL_CAR__A, 0x0002),
504 WR16(EQ_REG_COMM_EXEC__A, 0x0001),
505 END_OF_TABLE
506};
507
508u8 DRXD_InitEQB1[] = {
509 WR16(B_EQ_REG_COMM_EXEC__A, 0x0001),
510 END_OF_TABLE
511};
512
513u8 DRXD_ResetECRAM[] = {
514 /* Reset packet sync bytes in EC_VD ram */
515 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
516 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
517 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
518 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
519 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
520 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
521 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
522 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
523 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
524 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
525 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
526
527 /* Reset packet sync bytes in EC_RS ram */
528 WR16(EC_RS_EC_RAM__A, 0x0000),
529 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
530 END_OF_TABLE
531};
532
533u8 DRXD_InitECA2[] = {
534 WRBLOCK(EC_SB_REG_CSI_HI__A, 6),
535 0x1F, 0x00, /* EC_SB_REG_CSI_HI__A */
536 0x1E, 0x00, /* EC_SB_REG_CSI_LO__A */
537 0x01, 0x00, /* EC_SB_REG_SMB_TGL__A */
538 0x7F, 0x00, /* EC_SB_REG_SNR_HI__A */
539 0x7F, 0x00, /* EC_SB_REG_SNR_MID__A */
540 0x7F, 0x00, /* EC_SB_REG_SNR_LO__A */
541
542 WRBLOCK(EC_RS_REG_REQ_PCK_CNT__A, 2),
543 0x00, 0x10, /* EC_RS_REG_REQ_PCK_CNT__A */
544 DATA16(EC_RS_REG_VAL_PCK), /* EC_RS_REG_VAL__A */
545
546 WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
547 0x03, 0x00, /* EC_OC_REG_TMD_TOP_MODE__A */
548 0xF4, 0x01, /* EC_OC_REG_TMD_TOP_CNT__A */
549 0xC0, 0x03, /* EC_OC_REG_TMD_HIL_MAR__A */
550 0x40, 0x00, /* EC_OC_REG_TMD_LOL_MAR__A */
551 0x03, 0x00, /* EC_OC_REG_TMD_CUR_CNT__A */
552
553 WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
554 0x06, 0x00, /* EC_OC_REG_AVR_ASH_CNT__A */
555 0x02, 0x00, /* EC_OC_REG_AVR_BSH_CNT__A */
556
557 WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
558 0x07, 0x00, /* EC_OC_REG_RCN_MODE__A */
559 0x00, 0x00, /* EC_OC_REG_RCN_CRA_LOP__A */
560 0xc0, 0x00, /* EC_OC_REG_RCN_CRA_HIP__A */
561 0x00, 0x10, /* EC_OC_REG_RCN_CST_LOP__A */
562 0x00, 0x00, /* EC_OC_REG_RCN_CST_HIP__A */
563 0xFF, 0x01, /* EC_OC_REG_RCN_SET_LVL__A */
564 0x0D, 0x00, /* EC_OC_REG_RCN_GAI_LVL__A */
565
566 WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
567 0x00, 0x00, /* EC_OC_REG_RCN_CLP_LOP__A */
568 0xC0, 0x00, /* EC_OC_REG_RCN_CLP_HIP__A */
569
570 WR16(EC_SB_REG_CSI_OFS__A, 0x0001),
571 WR16(EC_VD_REG_FORCE__A, 0x0002),
572 WR16(EC_VD_REG_REQ_SMB_CNT__A, 0x0001),
573 WR16(EC_VD_REG_RLK_ENA__A, 0x0001),
574 WR16(EC_OD_REG_SYNC__A, 0x0664),
575 WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
576 WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
577 /* Output zero on monitorbus pads, power saving */
578 WR16(EC_OC_REG_OCR_MON_UOS__A,
579 (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
580 EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
581 EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
582 EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
583 EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
584 EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
585 EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
586 EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
587 EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
588 EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
589 EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
590 EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
591 WR16(EC_OC_REG_OCR_MON_WRI__A,
592 EC_OC_REG_OCR_MON_WRI_INIT),
593
594/* CHK_ERROR(ResetECRAM(demod)); */
595 /* Reset packet sync bytes in EC_VD ram */
596 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
597 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
598 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
599 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
600 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
601 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
602 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
603 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
604 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
605 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
606 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
607
608 /* Reset packet sync bytes in EC_RS ram */
609 WR16(EC_RS_EC_RAM__A, 0x0000),
610 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
611
612 WR16(EC_SB_REG_COMM_EXEC__A, 0x0001),
613 WR16(EC_VD_REG_COMM_EXEC__A, 0x0001),
614 WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
615 WR16(EC_RS_REG_COMM_EXEC__A, 0x0001),
616 END_OF_TABLE
617};
618
619u8 DRXD_InitECB1[] = {
620 WR16(B_EC_SB_REG_CSI_OFS0__A, 0x0001),
621 WR16(B_EC_SB_REG_CSI_OFS1__A, 0x0001),
622 WR16(B_EC_SB_REG_CSI_OFS2__A, 0x0001),
623 WR16(B_EC_SB_REG_CSI_LO__A, 0x000c),
624 WR16(B_EC_SB_REG_CSI_HI__A, 0x0018),
625 WR16(B_EC_SB_REG_SNR_HI__A, 0x007f),
626 WR16(B_EC_SB_REG_SNR_MID__A, 0x007f),
627 WR16(B_EC_SB_REG_SNR_LO__A, 0x007f),
628
629 WR16(B_EC_OC_REG_DTO_CLKMODE__A, 0x0002),
630 WR16(B_EC_OC_REG_DTO_PER__A, 0x0006),
631 WR16(B_EC_OC_REG_DTO_BUR__A, 0x0001),
632 WR16(B_EC_OC_REG_RCR_CLKMODE__A, 0x0000),
633 WR16(B_EC_OC_REG_RCN_GAI_LVL__A, 0x000D),
634 WR16(B_EC_OC_REG_OC_MPG_SIO__A, 0x0000),
635
636 /* Needed because shadow registers do not have correct default value */
637 WR16(B_EC_OC_REG_RCN_CST_LOP__A, 0x1000),
638 WR16(B_EC_OC_REG_RCN_CST_HIP__A, 0x0000),
639 WR16(B_EC_OC_REG_RCN_CRA_LOP__A, 0x0000),
640 WR16(B_EC_OC_REG_RCN_CRA_HIP__A, 0x00C0),
641 WR16(B_EC_OC_REG_RCN_CLP_LOP__A, 0x0000),
642 WR16(B_EC_OC_REG_RCN_CLP_HIP__A, 0x00C0),
643 WR16(B_EC_OC_REG_DTO_INC_LOP__A, 0x0000),
644 WR16(B_EC_OC_REG_DTO_INC_HIP__A, 0x00C0),
645
646 WR16(B_EC_OD_REG_SYNC__A, 0x0664),
647 WR16(B_EC_RS_REG_REQ_PCK_CNT__A, 0x1000),
648
649/* CHK_ERROR(ResetECRAM(demod)); */
650 /* Reset packet sync bytes in EC_VD ram */
651 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
652 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
653 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
654 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
655 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
656 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
657 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
658 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
659 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
660 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
661 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
662
663 /* Reset packet sync bytes in EC_RS ram */
664 WR16(EC_RS_EC_RAM__A, 0x0000),
665 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
666
667 WR16(B_EC_SB_REG_COMM_EXEC__A, 0x0001),
668 WR16(B_EC_VD_REG_COMM_EXEC__A, 0x0001),
669 WR16(B_EC_OD_REG_COMM_EXEC__A, 0x0001),
670 WR16(B_EC_RS_REG_COMM_EXEC__A, 0x0001),
671 END_OF_TABLE
672};
673
674u8 DRXD_ResetECA2[] = {
675
676 WR16(EC_OC_REG_COMM_EXEC__A, 0x0000),
677 WR16(EC_OD_REG_COMM_EXEC__A, 0x0000),
678
679 WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
680 0x03, 0x00, /* EC_OC_REG_TMD_TOP_MODE__A */
681 0xF4, 0x01, /* EC_OC_REG_TMD_TOP_CNT__A */
682 0xC0, 0x03, /* EC_OC_REG_TMD_HIL_MAR__A */
683 0x40, 0x00, /* EC_OC_REG_TMD_LOL_MAR__A */
684 0x03, 0x00, /* EC_OC_REG_TMD_CUR_CNT__A */
685
686 WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
687 0x06, 0x00, /* EC_OC_REG_AVR_ASH_CNT__A */
688 0x02, 0x00, /* EC_OC_REG_AVR_BSH_CNT__A */
689
690 WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
691 0x07, 0x00, /* EC_OC_REG_RCN_MODE__A */
692 0x00, 0x00, /* EC_OC_REG_RCN_CRA_LOP__A */
693 0xc0, 0x00, /* EC_OC_REG_RCN_CRA_HIP__A */
694 0x00, 0x10, /* EC_OC_REG_RCN_CST_LOP__A */
695 0x00, 0x00, /* EC_OC_REG_RCN_CST_HIP__A */
696 0xFF, 0x01, /* EC_OC_REG_RCN_SET_LVL__A */
697 0x0D, 0x00, /* EC_OC_REG_RCN_GAI_LVL__A */
698
699 WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
700 0x00, 0x00, /* EC_OC_REG_RCN_CLP_LOP__A */
701 0xC0, 0x00, /* EC_OC_REG_RCN_CLP_HIP__A */
702
703 WR16(EC_OD_REG_SYNC__A, 0x0664),
704 WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
705 WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
706 /* Output zero on monitorbus pads, power saving */
707 WR16(EC_OC_REG_OCR_MON_UOS__A,
708 (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
709 EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
710 EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
711 EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
712 EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
713 EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
714 EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
715 EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
716 EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
717 EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
718 EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
719 EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
720 WR16(EC_OC_REG_OCR_MON_WRI__A,
721 EC_OC_REG_OCR_MON_WRI_INIT),
722
723/* CHK_ERROR(ResetECRAM(demod)); */
724 /* Reset packet sync bytes in EC_VD ram */
725 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
726 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
727 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
728 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
729 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
730 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
731 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
732 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
733 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
734 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
735 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
736
737 /* Reset packet sync bytes in EC_RS ram */
738 WR16(EC_RS_EC_RAM__A, 0x0000),
739 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
740
741 WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
742 END_OF_TABLE
743};
744
745u8 DRXD_InitSC[] = {
746 WR16(SC_COMM_EXEC__A, 0),
747 WR16(SC_COMM_STATE__A, 0),
748
749#ifdef COMPILE_FOR_QT
750 WR16(SC_RA_RAM_BE_OPT_DELAY__A, 0x100),
751#endif
752
753 /* SC is not started, this is done in SetChannels() */
754 END_OF_TABLE
755};
756
757/* Diversity settings */
758
759u8 DRXD_InitDiversityFront[] = {
760 /* Start demod ********* RF in , diversity out **************************** */
761 WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
762 B_SC_RA_RAM_CONFIG_FREQSCAN__M),
763
764 WR16(B_SC_RA_RAM_LC_ABS_2K__A, 0x7),
765 WR16(B_SC_RA_RAM_LC_ABS_8K__A, 0x7),
766 WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
767 WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
768 WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
769 WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
770 WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
771 WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
772
773 WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
774 WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
775 WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
776 WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
777 WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
778 WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
779
780 WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
781 WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
782 WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
783 WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
784 WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
785
786 WR16(B_CC_REG_DIVERSITY__A, 0x0001),
787 WR16(B_EC_OC_REG_OC_MODE_HIP__A, 0x0010),
788 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |
789 B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
790
791 /* 0x2a ), *//* CE to PASS mux */
792
793 END_OF_TABLE
794};
795
796u8 DRXD_InitDiversityEnd[] = {
797 /* End demod *********** combining RF in and diversity in, MPEG TS out **** */
798 /* disable near/far; switch on timing slave mode */
799 WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
800 B_SC_RA_RAM_CONFIG_FREQSCAN__M |
801 B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M |
802 B_SC_RA_RAM_CONFIG_SLAVE__M |
803 B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M
804/* MV from CtrlDiversity */
805 ),
806#ifdef DRXDDIV_SRMM_SLAVING
807 WR16(SC_RA_RAM_LC_ABS_2K__A, 0x3c7),
808 WR16(SC_RA_RAM_LC_ABS_8K__A, 0x3c7),
809#else
810 WR16(SC_RA_RAM_LC_ABS_2K__A, 0x7),
811 WR16(SC_RA_RAM_LC_ABS_8K__A, 0x7),
812#endif
813
814 WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
815 WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
816 WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
817 WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
818 WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
819 WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
820
821 WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
822 WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
823 WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
824 WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
825 WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
826 WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
827
828 WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
829 WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
830 WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
831 WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
832 WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
833
834 WR16(B_CC_REG_DIVERSITY__A, 0x0001),
835 END_OF_TABLE
836};
837
838u8 DRXD_DisableDiversity[] = {
839 WR16(B_SC_RA_RAM_LC_ABS_2K__A, B_SC_RA_RAM_LC_ABS_2K__PRE),
840 WR16(B_SC_RA_RAM_LC_ABS_8K__A, B_SC_RA_RAM_LC_ABS_8K__PRE),
841 WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A,
842 B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE),
843 WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A,
844 B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE),
845 WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A,
846 B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE),
847 WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A,
848 B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE),
849 WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A,
850 B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE),
851 WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A,
852 B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE),
853
854 WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A,
855 B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE),
856 WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A,
857 B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE),
858 WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A,
859 B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE),
860 WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A,
861 B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE),
862 WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A,
863 B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE),
864 WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A,
865 B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE),
866
867 WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, B_LC_RA_RAM_FILTER_CRMM_A__PRE),
868 WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, B_LC_RA_RAM_FILTER_CRMM_B__PRE),
869 WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, B_LC_RA_RAM_FILTER_SRMM_A__PRE),
870 WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, B_LC_RA_RAM_FILTER_SRMM_B__PRE),
871 WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, B_LC_RA_RAM_FILTER_SYM_SET__PRE),
872
873 WR16(B_CC_REG_DIVERSITY__A, 0x0000),
874 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_INIT), /* combining disabled */
875
876 END_OF_TABLE
877};
878
879u8 DRXD_StartDiversityFront[] = {
880 /* Start demod, RF in and diversity out, no combining */
881 WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),
882 WR16(B_FE_AD_REG_FDB_IN__A, 0x0),
883 WR16(B_FE_AD_REG_INVEXT__A, 0x0),
884 WR16(B_EQ_REG_COMM_MB__A, 0x12), /* EQ to MB out */
885 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE | /* CE to PASS mux */
886 B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
887
888 WR16(SC_RA_RAM_ECHO_SHIFT_LIM__A, 2),
889
890 END_OF_TABLE
891};
892
893u8 DRXD_StartDiversityEnd[] = {
894 /* End demod, combining RF in and diversity in, MPEG TS out */
895 WR16(B_FE_CF_REG_IMP_VAL__A, 0x0), /* disable impulse noise cruncher */
896 WR16(B_FE_AD_REG_INVEXT__A, 0x0), /* clock inversion (for sohard board) */
897 WR16(B_CP_REG_BR_STR_DEL__A, 10), /* apperently no mb delay matching is best */
898
899 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_DIV_ON | /* org = 0x81 combining enabled */
900 B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
901 B_EQ_REG_RC_SEL_CAR_PASS_A_CC | B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC),
902
903 END_OF_TABLE
904};
905
906u8 DRXD_DiversityDelay8MHZ[] = {
907 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1150 - 50),
908 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1100 - 50),
909 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 1000 - 50),
910 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 800 - 50),
911 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5420 - 50),
912 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5200 - 50),
913 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4800 - 50),
914 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 4000 - 50),
915 END_OF_TABLE
916};
917
918u8 DRXD_DiversityDelay6MHZ[] = /* also used ok for 7 MHz */
919{
920 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1100 - 50),
921 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1000 - 50),
922 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 900 - 50),
923 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 600 - 50),
924 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5300 - 50),
925 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5000 - 50),
926 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4500 - 50),
927 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 3500 - 50),
928 END_OF_TABLE
929};
diff --git a/drivers/media/dvb/frontends/drxd_firm.h b/drivers/media/dvb/frontends/drxd_firm.h
new file mode 100644
index 000000000000..41597e89941c
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_firm.h
@@ -0,0 +1,115 @@
1/*
2 * drxd_firm.h
3 *
4 * Copyright (C) 2006-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef _DRXD_FIRM_H_
25#define _DRXD_FIRM_H_
26
27#include <linux/types.h>
28#include "drxd_map_firm.h"
29
30#define VERSION_MAJOR 1
31#define VERSION_MINOR 4
32#define VERSION_PATCH 23
33
34#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
35
36#define DRXD_MAX_RETRIES (1000)
37#define HI_I2C_DELAY 84
38#define HI_I2C_BRIDGE_DELAY 750
39
40#define EQ_TD_TPS_PWR_UNKNOWN 0x00C0 /* Unknown configurations */
41#define EQ_TD_TPS_PWR_QPSK 0x016a
42#define EQ_TD_TPS_PWR_QAM16_ALPHAN 0x0195
43#define EQ_TD_TPS_PWR_QAM16_ALPHA1 0x0195
44#define EQ_TD_TPS_PWR_QAM16_ALPHA2 0x011E
45#define EQ_TD_TPS_PWR_QAM16_ALPHA4 0x01CE
46#define EQ_TD_TPS_PWR_QAM64_ALPHAN 0x019F
47#define EQ_TD_TPS_PWR_QAM64_ALPHA1 0x019F
48#define EQ_TD_TPS_PWR_QAM64_ALPHA2 0x00F8
49#define EQ_TD_TPS_PWR_QAM64_ALPHA4 0x014D
50
51#define DRXD_DEF_AG_PWD_CONSUMER 0x000E
52#define DRXD_DEF_AG_PWD_PRO 0x0000
53#define DRXD_DEF_AG_AGC_SIO 0x0000
54
55#define DRXD_FE_CTRL_MAX 1023
56
57#define DRXD_OSCDEV_DO_SCAN (16)
58
59#define DRXD_OSCDEV_DONT_SCAN (0)
60
61#define DRXD_OSCDEV_STEP (275)
62
63#define DRXD_SCAN_TIMEOUT (650)
64
65#define DRXD_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
66#define DRXD_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
67#define DRXD_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
68
69#define IRLEN_COARSE_8K (10)
70#define IRLEN_FINE_8K (10)
71#define IRLEN_COARSE_2K (7)
72#define IRLEN_FINE_2K (9)
73#define DIFF_INVALID (511)
74#define DIFF_TARGET (4)
75#define DIFF_MARGIN (1)
76
77extern u8 DRXD_InitAtomicRead[];
78extern u8 DRXD_HiI2cPatch_1[];
79extern u8 DRXD_HiI2cPatch_3[];
80
81extern u8 DRXD_InitSC[];
82
83extern u8 DRXD_ResetCEFR[];
84extern u8 DRXD_InitFEA2_1[];
85extern u8 DRXD_InitFEA2_2[];
86extern u8 DRXD_InitCPA2[];
87extern u8 DRXD_InitCEA2[];
88extern u8 DRXD_InitEQA2[];
89extern u8 DRXD_InitECA2[];
90extern u8 DRXD_ResetECA2[];
91extern u8 DRXD_ResetECRAM[];
92
93extern u8 DRXD_A2_microcode[];
94extern u32 DRXD_A2_microcode_length;
95
96extern u8 DRXD_InitFEB1_1[];
97extern u8 DRXD_InitFEB1_2[];
98extern u8 DRXD_InitCPB1[];
99extern u8 DRXD_InitCEB1[];
100extern u8 DRXD_InitEQB1[];
101extern u8 DRXD_InitECB1[];
102
103extern u8 DRXD_InitDiversityFront[];
104extern u8 DRXD_InitDiversityEnd[];
105extern u8 DRXD_DisableDiversity[];
106extern u8 DRXD_StartDiversityFront[];
107extern u8 DRXD_StartDiversityEnd[];
108
109extern u8 DRXD_DiversityDelay8MHZ[];
110extern u8 DRXD_DiversityDelay6MHZ[];
111
112extern u8 DRXD_B1_microcode[];
113extern u32 DRXD_B1_microcode_length;
114
115#endif
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c
new file mode 100644
index 000000000000..ea4c1c361d2b
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_hard.c
@@ -0,0 +1,3001 @@
1/*
2 * drxd_hard.c: DVB-T Demodulator Micronas DRX3975D-A2,DRX397xD-B1
3 *
4 * Copyright (C) 2003-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxd.h"
36#include "drxd_firm.h"
37
38#define DRX_FW_FILENAME_A2 "drxd-a2-1.1.fw"
39#define DRX_FW_FILENAME_B1 "drxd-b1-1.1.fw"
40
41#define CHUNK_SIZE 48
42
43#define DRX_I2C_RMW 0x10
44#define DRX_I2C_BROADCAST 0x20
45#define DRX_I2C_CLEARCRC 0x80
46#define DRX_I2C_SINGLE_MASTER 0xC0
47#define DRX_I2C_MODEFLAGS 0xC0
48#define DRX_I2C_FLAGS 0xF0
49
50#ifndef SIZEOF_ARRAY
51#define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
52#endif
53
54#define DEFAULT_LOCK_TIMEOUT 1100
55
56#define DRX_CHANNEL_AUTO 0
57#define DRX_CHANNEL_HIGH 1
58#define DRX_CHANNEL_LOW 2
59
60#define DRX_LOCK_MPEG 1
61#define DRX_LOCK_FEC 2
62#define DRX_LOCK_DEMOD 4
63
64/****************************************************************************/
65
66enum CSCDState {
67 CSCD_INIT = 0,
68 CSCD_SET,
69 CSCD_SAVED
70};
71
72enum CDrxdState {
73 DRXD_UNINITIALIZED = 0,
74 DRXD_STOPPED,
75 DRXD_STARTED
76};
77
78enum AGC_CTRL_MODE {
79 AGC_CTRL_AUTO = 0,
80 AGC_CTRL_USER,
81 AGC_CTRL_OFF
82};
83
84enum OperationMode {
85 OM_Default,
86 OM_DVBT_Diversity_Front,
87 OM_DVBT_Diversity_End
88};
89
90struct SCfgAgc {
91 enum AGC_CTRL_MODE ctrlMode;
92 u16 outputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
93 u16 settleLevel; /* range [0, ... , 1023], 1/n of fullscale range */
94 u16 minOutputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
95 u16 maxOutputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
96 u16 speed; /* range [0, ... , 1023], 1/n of fullscale range */
97
98 u16 R1;
99 u16 R2;
100 u16 R3;
101};
102
103struct SNoiseCal {
104 int cpOpt;
105 u16 cpNexpOfs;
106 u16 tdCal2k;
107 u16 tdCal8k;
108};
109
110enum app_env {
111 APPENV_STATIC = 0,
112 APPENV_PORTABLE = 1,
113 APPENV_MOBILE = 2
114};
115
116enum EIFFilter {
117 IFFILTER_SAW = 0,
118 IFFILTER_DISCRETE = 1
119};
120
121struct drxd_state {
122 struct dvb_frontend frontend;
123 struct dvb_frontend_ops ops;
124 struct dvb_frontend_parameters param;
125
126 const struct firmware *fw;
127 struct device *dev;
128
129 struct i2c_adapter *i2c;
130 void *priv;
131 struct drxd_config config;
132
133 int i2c_access;
134 int init_done;
135 struct mutex mutex;
136
137 u8 chip_adr;
138 u16 hi_cfg_timing_div;
139 u16 hi_cfg_bridge_delay;
140 u16 hi_cfg_wakeup_key;
141 u16 hi_cfg_ctrl;
142
143 u16 intermediate_freq;
144 u16 osc_clock_freq;
145
146 enum CSCDState cscd_state;
147 enum CDrxdState drxd_state;
148
149 u16 sys_clock_freq;
150 s16 osc_clock_deviation;
151 u16 expected_sys_clock_freq;
152
153 u16 insert_rs_byte;
154 u16 enable_parallel;
155
156 int operation_mode;
157
158 struct SCfgAgc if_agc_cfg;
159 struct SCfgAgc rf_agc_cfg;
160
161 struct SNoiseCal noise_cal;
162
163 u32 fe_fs_add_incr;
164 u32 org_fe_fs_add_incr;
165 u16 current_fe_if_incr;
166
167 u16 m_FeAgRegAgPwd;
168 u16 m_FeAgRegAgAgcSio;
169
170 u16 m_EcOcRegOcModeLop;
171 u16 m_EcOcRegSncSncLvl;
172 u8 *m_InitAtomicRead;
173 u8 *m_HiI2cPatch;
174
175 u8 *m_ResetCEFR;
176 u8 *m_InitFE_1;
177 u8 *m_InitFE_2;
178 u8 *m_InitCP;
179 u8 *m_InitCE;
180 u8 *m_InitEQ;
181 u8 *m_InitSC;
182 u8 *m_InitEC;
183 u8 *m_ResetECRAM;
184 u8 *m_InitDiversityFront;
185 u8 *m_InitDiversityEnd;
186 u8 *m_DisableDiversity;
187 u8 *m_StartDiversityFront;
188 u8 *m_StartDiversityEnd;
189
190 u8 *m_DiversityDelay8MHZ;
191 u8 *m_DiversityDelay6MHZ;
192
193 u8 *microcode;
194 u32 microcode_length;
195
196 int type_A;
197 int PGA;
198 int diversity;
199 int tuner_mirrors;
200
201 enum app_env app_env_default;
202 enum app_env app_env_diversity;
203
204};
205
206/****************************************************************************/
207/* I2C **********************************************************************/
208/****************************************************************************/
209
210static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 * data, int len)
211{
212 struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len };
213
214 if (i2c_transfer(adap, &msg, 1) != 1)
215 return -1;
216 return 0;
217}
218
219static int i2c_read(struct i2c_adapter *adap,
220 u8 adr, u8 *msg, int len, u8 *answ, int alen)
221{
222 struct i2c_msg msgs[2] = {
223 {
224 .addr = adr, .flags = 0,
225 .buf = msg, .len = len
226 }, {
227 .addr = adr, .flags = I2C_M_RD,
228 .buf = answ, .len = alen
229 }
230 };
231 if (i2c_transfer(adap, msgs, 2) != 2)
232 return -1;
233 return 0;
234}
235
236inline u32 MulDiv32(u32 a, u32 b, u32 c)
237{
238 u64 tmp64;
239
240 tmp64 = (u64)a * (u64)b;
241 do_div(tmp64, c);
242
243 return (u32) tmp64;
244}
245
246static int Read16(struct drxd_state *state, u32 reg, u16 *data, u8 flags)
247{
248 u8 adr = state->config.demod_address;
249 u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
250 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
251 };
252 u8 mm2[2];
253 if (i2c_read(state->i2c, adr, mm1, 4, mm2, 2) < 0)
254 return -1;
255 if (data)
256 *data = mm2[0] | (mm2[1] << 8);
257 return mm2[0] | (mm2[1] << 8);
258}
259
260static int Read32(struct drxd_state *state, u32 reg, u32 *data, u8 flags)
261{
262 u8 adr = state->config.demod_address;
263 u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
264 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
265 };
266 u8 mm2[4];
267
268 if (i2c_read(state->i2c, adr, mm1, 4, mm2, 4) < 0)
269 return -1;
270 if (data)
271 *data =
272 mm2[0] | (mm2[1] << 8) | (mm2[2] << 16) | (mm2[3] << 24);
273 return 0;
274}
275
276static int Write16(struct drxd_state *state, u32 reg, u16 data, u8 flags)
277{
278 u8 adr = state->config.demod_address;
279 u8 mm[6] = { reg & 0xff, (reg >> 16) & 0xff,
280 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
281 data & 0xff, (data >> 8) & 0xff
282 };
283
284 if (i2c_write(state->i2c, adr, mm, 6) < 0)
285 return -1;
286 return 0;
287}
288
289static int Write32(struct drxd_state *state, u32 reg, u32 data, u8 flags)
290{
291 u8 adr = state->config.demod_address;
292 u8 mm[8] = { reg & 0xff, (reg >> 16) & 0xff,
293 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
294 data & 0xff, (data >> 8) & 0xff,
295 (data >> 16) & 0xff, (data >> 24) & 0xff
296 };
297
298 if (i2c_write(state->i2c, adr, mm, 8) < 0)
299 return -1;
300 return 0;
301}
302
303static int write_chunk(struct drxd_state *state,
304 u32 reg, u8 *data, u32 len, u8 flags)
305{
306 u8 adr = state->config.demod_address;
307 u8 mm[CHUNK_SIZE + 4] = { reg & 0xff, (reg >> 16) & 0xff,
308 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
309 };
310 int i;
311
312 for (i = 0; i < len; i++)
313 mm[4 + i] = data[i];
314 if (i2c_write(state->i2c, adr, mm, 4 + len) < 0) {
315 printk(KERN_ERR "error in write_chunk\n");
316 return -1;
317 }
318 return 0;
319}
320
321static int WriteBlock(struct drxd_state *state,
322 u32 Address, u16 BlockSize, u8 *pBlock, u8 Flags)
323{
324 while (BlockSize > 0) {
325 u16 Chunk = BlockSize > CHUNK_SIZE ? CHUNK_SIZE : BlockSize;
326
327 if (write_chunk(state, Address, pBlock, Chunk, Flags) < 0)
328 return -1;
329 pBlock += Chunk;
330 Address += (Chunk >> 1);
331 BlockSize -= Chunk;
332 }
333 return 0;
334}
335
336static int WriteTable(struct drxd_state *state, u8 * pTable)
337{
338 int status = 0;
339
340 if (pTable == NULL)
341 return 0;
342
343 while (!status) {
344 u16 Length;
345 u32 Address = pTable[0] | (pTable[1] << 8) |
346 (pTable[2] << 16) | (pTable[3] << 24);
347
348 if (Address == 0xFFFFFFFF)
349 break;
350 pTable += sizeof(u32);
351
352 Length = pTable[0] | (pTable[1] << 8);
353 pTable += sizeof(u16);
354 if (!Length)
355 break;
356 status = WriteBlock(state, Address, Length * 2, pTable, 0);
357 pTable += (Length * 2);
358 }
359 return status;
360}
361
362/****************************************************************************/
363/****************************************************************************/
364/****************************************************************************/
365
366static int ResetCEFR(struct drxd_state *state)
367{
368 return WriteTable(state, state->m_ResetCEFR);
369}
370
371static int InitCP(struct drxd_state *state)
372{
373 return WriteTable(state, state->m_InitCP);
374}
375
376static int InitCE(struct drxd_state *state)
377{
378 int status;
379 enum app_env AppEnv = state->app_env_default;
380
381 do {
382 status = WriteTable(state, state->m_InitCE);
383 if (status < 0)
384 break;
385
386 if (state->operation_mode == OM_DVBT_Diversity_Front ||
387 state->operation_mode == OM_DVBT_Diversity_End) {
388 AppEnv = state->app_env_diversity;
389 }
390 if (AppEnv == APPENV_STATIC) {
391 status = Write16(state, CE_REG_TAPSET__A, 0x0000, 0);
392 if (status < 0)
393 break;
394 } else if (AppEnv == APPENV_PORTABLE) {
395 status = Write16(state, CE_REG_TAPSET__A, 0x0001, 0);
396 if (status < 0)
397 break;
398 } else if (AppEnv == APPENV_MOBILE && state->type_A) {
399 status = Write16(state, CE_REG_TAPSET__A, 0x0002, 0);
400 if (status < 0)
401 break;
402 } else if (AppEnv == APPENV_MOBILE && !state->type_A) {
403 status = Write16(state, CE_REG_TAPSET__A, 0x0006, 0);
404 if (status < 0)
405 break;
406 }
407
408 /* start ce */
409 status = Write16(state, B_CE_REG_COMM_EXEC__A, 0x0001, 0);
410 if (status < 0)
411 break;
412 } while (0);
413 return status;
414}
415
416static int StopOC(struct drxd_state *state)
417{
418 int status = 0;
419 u16 ocSyncLvl = 0;
420 u16 ocModeLop = state->m_EcOcRegOcModeLop;
421 u16 dtoIncLop = 0;
422 u16 dtoIncHip = 0;
423
424 do {
425 /* Store output configuration */
426 status = Read16(state, EC_OC_REG_SNC_ISC_LVL__A, &ocSyncLvl, 0);
427 if (status < 0)
428 break;
429 /* CHK_ERROR(Read16(EC_OC_REG_OC_MODE_LOP__A, &ocModeLop)); */
430 state->m_EcOcRegSncSncLvl = ocSyncLvl;
431 /* m_EcOcRegOcModeLop = ocModeLop; */
432
433 /* Flush FIFO (byte-boundary) at fixed rate */
434 status = Read16(state, EC_OC_REG_RCN_MAP_LOP__A, &dtoIncLop, 0);
435 if (status < 0)
436 break;
437 status = Read16(state, EC_OC_REG_RCN_MAP_HIP__A, &dtoIncHip, 0);
438 if (status < 0)
439 break;
440 status = Write16(state, EC_OC_REG_DTO_INC_LOP__A, dtoIncLop, 0);
441 if (status < 0)
442 break;
443 status = Write16(state, EC_OC_REG_DTO_INC_HIP__A, dtoIncHip, 0);
444 if (status < 0)
445 break;
446 ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M);
447 ocModeLop |= EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC;
448 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
449 if (status < 0)
450 break;
451 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
452 if (status < 0)
453 break;
454
455 msleep(1);
456 /* Output pins to '0' */
457 status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS__M, 0);
458 if (status < 0)
459 break;
460
461 /* Force the OC out of sync */
462 ocSyncLvl &= ~(EC_OC_REG_SNC_ISC_LVL_OSC__M);
463 status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, ocSyncLvl, 0);
464 if (status < 0)
465 break;
466 ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M);
467 ocModeLop |= EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE;
468 ocModeLop |= 0x2; /* Magically-out-of-sync */
469 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
470 if (status < 0)
471 break;
472 status = Write16(state, EC_OC_REG_COMM_INT_STA__A, 0x0, 0);
473 if (status < 0)
474 break;
475 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
476 if (status < 0)
477 break;
478 } while (0);
479
480 return status;
481}
482
483static int StartOC(struct drxd_state *state)
484{
485 int status = 0;
486
487 do {
488 /* Stop OC */
489 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
490 if (status < 0)
491 break;
492
493 /* Restore output configuration */
494 status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, state->m_EcOcRegSncSncLvl, 0);
495 if (status < 0)
496 break;
497 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, state->m_EcOcRegOcModeLop, 0);
498 if (status < 0)
499 break;
500
501 /* Output pins active again */
502 status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS_INIT, 0);
503 if (status < 0)
504 break;
505
506 /* Start OC */
507 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
508 if (status < 0)
509 break;
510 } while (0);
511 return status;
512}
513
514static int InitEQ(struct drxd_state *state)
515{
516 return WriteTable(state, state->m_InitEQ);
517}
518
519static int InitEC(struct drxd_state *state)
520{
521 return WriteTable(state, state->m_InitEC);
522}
523
524static int InitSC(struct drxd_state *state)
525{
526 return WriteTable(state, state->m_InitSC);
527}
528
529static int InitAtomicRead(struct drxd_state *state)
530{
531 return WriteTable(state, state->m_InitAtomicRead);
532}
533
534static int CorrectSysClockDeviation(struct drxd_state *state);
535
536static int DRX_GetLockStatus(struct drxd_state *state, u32 * pLockStatus)
537{
538 u16 ScRaRamLock = 0;
539 const u16 mpeg_lock_mask = (SC_RA_RAM_LOCK_MPEG__M |
540 SC_RA_RAM_LOCK_FEC__M |
541 SC_RA_RAM_LOCK_DEMOD__M);
542 const u16 fec_lock_mask = (SC_RA_RAM_LOCK_FEC__M |
543 SC_RA_RAM_LOCK_DEMOD__M);
544 const u16 demod_lock_mask = SC_RA_RAM_LOCK_DEMOD__M;
545
546 int status;
547
548 *pLockStatus = 0;
549
550 status = Read16(state, SC_RA_RAM_LOCK__A, &ScRaRamLock, 0x0000);
551 if (status < 0) {
552 printk(KERN_ERR "Can't read SC_RA_RAM_LOCK__A status = %08x\n", status);
553 return status;
554 }
555
556 if (state->drxd_state != DRXD_STARTED)
557 return 0;
558
559 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
560 *pLockStatus |= DRX_LOCK_MPEG;
561 CorrectSysClockDeviation(state);
562 }
563
564 if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
565 *pLockStatus |= DRX_LOCK_FEC;
566
567 if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
568 *pLockStatus |= DRX_LOCK_DEMOD;
569 return 0;
570}
571
572/****************************************************************************/
573
574static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
575{
576 int status;
577
578 if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
579 return -1;
580
581 if (cfg->ctrlMode == AGC_CTRL_USER) {
582 do {
583 u16 FeAgRegPm1AgcWri;
584 u16 FeAgRegAgModeLop;
585
586 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
587 if (status < 0)
588 break;
589 FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
590 FeAgRegAgModeLop |= FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC;
591 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
592 if (status < 0)
593 break;
594
595 FeAgRegPm1AgcWri = (u16) (cfg->outputLevel &
596 FE_AG_REG_PM1_AGC_WRI__M);
597 status = Write16(state, FE_AG_REG_PM1_AGC_WRI__A, FeAgRegPm1AgcWri, 0);
598 if (status < 0)
599 break;
600 } while (0);
601 } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
602 if (((cfg->maxOutputLevel) < (cfg->minOutputLevel)) ||
603 ((cfg->maxOutputLevel) > DRXD_FE_CTRL_MAX) ||
604 ((cfg->speed) > DRXD_FE_CTRL_MAX) ||
605 ((cfg->settleLevel) > DRXD_FE_CTRL_MAX)
606 )
607 return -1;
608 do {
609 u16 FeAgRegAgModeLop;
610 u16 FeAgRegEgcSetLvl;
611 u16 slope, offset;
612
613 /* == Mode == */
614
615 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
616 if (status < 0)
617 break;
618 FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
619 FeAgRegAgModeLop |=
620 FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC;
621 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
622 if (status < 0)
623 break;
624
625 /* == Settle level == */
626
627 FeAgRegEgcSetLvl = (u16) ((cfg->settleLevel >> 1) &
628 FE_AG_REG_EGC_SET_LVL__M);
629 status = Write16(state, FE_AG_REG_EGC_SET_LVL__A, FeAgRegEgcSetLvl, 0);
630 if (status < 0)
631 break;
632
633 /* == Min/Max == */
634
635 slope = (u16) ((cfg->maxOutputLevel -
636 cfg->minOutputLevel) / 2);
637 offset = (u16) ((cfg->maxOutputLevel +
638 cfg->minOutputLevel) / 2 - 511);
639
640 status = Write16(state, FE_AG_REG_GC1_AGC_RIC__A, slope, 0);
641 if (status < 0)
642 break;
643 status = Write16(state, FE_AG_REG_GC1_AGC_OFF__A, offset, 0);
644 if (status < 0)
645 break;
646
647 /* == Speed == */
648 {
649 const u16 maxRur = 8;
650 const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 };
651 const u16 fastIncrDecLUT[] = { 14, 15, 15, 16,
652 17, 18, 18, 19,
653 20, 21, 22, 23,
654 24, 26, 27, 28,
655 29, 31
656 };
657
658 u16 fineSteps = (DRXD_FE_CTRL_MAX + 1) /
659 (maxRur + 1);
660 u16 fineSpeed = (u16) (cfg->speed -
661 ((cfg->speed /
662 fineSteps) *
663 fineSteps));
664 u16 invRurCount = (u16) (cfg->speed /
665 fineSteps);
666 u16 rurCount;
667 if (invRurCount > maxRur) {
668 rurCount = 0;
669 fineSpeed += fineSteps;
670 } else {
671 rurCount = maxRur - invRurCount;
672 }
673
674 /*
675 fastInc = default *
676 (2^(fineSpeed/fineSteps))
677 => range[default...2*default>
678 slowInc = default *
679 (2^(fineSpeed/fineSteps))
680 */
681 {
682 u16 fastIncrDec =
683 fastIncrDecLUT[fineSpeed /
684 ((fineSteps /
685 (14 + 1)) + 1)];
686 u16 slowIncrDec =
687 slowIncrDecLUT[fineSpeed /
688 (fineSteps /
689 (3 + 1))];
690
691 status = Write16(state, FE_AG_REG_EGC_RUR_CNT__A, rurCount, 0);
692 if (status < 0)
693 break;
694 status = Write16(state, FE_AG_REG_EGC_FAS_INC__A, fastIncrDec, 0);
695 if (status < 0)
696 break;
697 status = Write16(state, FE_AG_REG_EGC_FAS_DEC__A, fastIncrDec, 0);
698 if (status < 0)
699 break;
700 status = Write16(state, FE_AG_REG_EGC_SLO_INC__A, slowIncrDec, 0);
701 if (status < 0)
702 break;
703 status = Write16(state, FE_AG_REG_EGC_SLO_DEC__A, slowIncrDec, 0);
704 if (status < 0)
705 break;
706 }
707 }
708 } while (0);
709
710 } else {
711 /* No OFF mode for IF control */
712 return -1;
713 }
714 return status;
715}
716
717static int SetCfgRfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
718{
719 int status = 0;
720
721 if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
722 return -1;
723
724 if (cfg->ctrlMode == AGC_CTRL_USER) {
725 do {
726 u16 AgModeLop = 0;
727 u16 level = (cfg->outputLevel);
728
729 if (level == DRXD_FE_CTRL_MAX)
730 level++;
731
732 status = Write16(state, FE_AG_REG_PM2_AGC_WRI__A, level, 0x0000);
733 if (status < 0)
734 break;
735
736 /*==== Mode ====*/
737
738 /* Powerdown PD2, WRI source */
739 state->m_FeAgRegAgPwd &= ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
740 state->m_FeAgRegAgPwd |=
741 FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
742 status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
743 if (status < 0)
744 break;
745
746 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
747 if (status < 0)
748 break;
749 AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
750 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
751 AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
752 FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
753 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
754 if (status < 0)
755 break;
756
757 /* enable AGC2 pin */
758 {
759 u16 FeAgRegAgAgcSio = 0;
760 status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
761 if (status < 0)
762 break;
763 FeAgRegAgAgcSio &=
764 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
765 FeAgRegAgAgcSio |=
766 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
767 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
768 if (status < 0)
769 break;
770 }
771
772 } while (0);
773 } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
774 u16 AgModeLop = 0;
775
776 do {
777 u16 level;
778 /* Automatic control */
779 /* Powerup PD2, AGC2 as output, TGC source */
780 (state->m_FeAgRegAgPwd) &=
781 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
782 (state->m_FeAgRegAgPwd) |=
783 FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
784 status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
785 if (status < 0)
786 break;
787
788 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
789 if (status < 0)
790 break;
791 AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
792 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
793 AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
794 FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC);
795 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
796 if (status < 0)
797 break;
798 /* Settle level */
799 level = (((cfg->settleLevel) >> 4) &
800 FE_AG_REG_TGC_SET_LVL__M);
801 status = Write16(state, FE_AG_REG_TGC_SET_LVL__A, level, 0x0000);
802 if (status < 0)
803 break;
804
805 /* Min/max: don't care */
806
807 /* Speed: TODO */
808
809 /* enable AGC2 pin */
810 {
811 u16 FeAgRegAgAgcSio = 0;
812 status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
813 if (status < 0)
814 break;
815 FeAgRegAgAgcSio &=
816 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
817 FeAgRegAgAgcSio |=
818 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
819 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
820 if (status < 0)
821 break;
822 }
823
824 } while (0);
825 } else {
826 u16 AgModeLop = 0;
827
828 do {
829 /* No RF AGC control */
830 /* Powerdown PD2, AGC2 as output, WRI source */
831 (state->m_FeAgRegAgPwd) &=
832 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
833 (state->m_FeAgRegAgPwd) |=
834 FE_AG_REG_AG_PWD_PWD_PD2_ENABLE;
835 status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
836 if (status < 0)
837 break;
838
839 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
840 if (status < 0)
841 break;
842 AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
843 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
844 AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
845 FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
846 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
847 if (status < 0)
848 break;
849
850 /* set FeAgRegAgAgcSio AGC2 (RF) as input */
851 {
852 u16 FeAgRegAgAgcSio = 0;
853 status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
854 if (status < 0)
855 break;
856 FeAgRegAgAgcSio &=
857 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
858 FeAgRegAgAgcSio |=
859 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT;
860 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
861 if (status < 0)
862 break;
863 }
864 } while (0);
865 }
866 return status;
867}
868
869static int ReadIFAgc(struct drxd_state *state, u32 * pValue)
870{
871 int status = 0;
872
873 *pValue = 0;
874 if (state->if_agc_cfg.ctrlMode != AGC_CTRL_OFF) {
875 u16 Value;
876 status = Read16(state, FE_AG_REG_GC1_AGC_DAT__A, &Value, 0);
877 Value &= FE_AG_REG_GC1_AGC_DAT__M;
878 if (status >= 0) {
879 /* 3.3V
880 |
881 R1
882 |
883 Vin - R3 - * -- Vout
884 |
885 R2
886 |
887 GND
888 */
889 u32 R1 = state->if_agc_cfg.R1;
890 u32 R2 = state->if_agc_cfg.R2;
891 u32 R3 = state->if_agc_cfg.R3;
892
893 u32 Vmax = (3300 * R2) / (R1 + R2);
894 u32 Rpar = (R2 * R3) / (R3 + R2);
895 u32 Vmin = (3300 * Rpar) / (R1 + Rpar);
896 u32 Vout = Vmin + ((Vmax - Vmin) * Value) / 1024;
897
898 *pValue = Vout;
899 }
900 }
901 return status;
902}
903
904static int load_firmware(struct drxd_state *state, const char *fw_name)
905{
906 const struct firmware *fw;
907
908 if (request_firmware(&fw, fw_name, state->dev) < 0) {
909 printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name);
910 return -EIO;
911 }
912
913 state->microcode = kzalloc(fw->size, GFP_KERNEL);
914 if (state->microcode == NULL) {
915 printk(KERN_ERR "drxd: firmware load failure: nomemory\n");
916 return -ENOMEM;
917 }
918
919 memcpy(state->microcode, fw->data, fw->size);
920 state->microcode_length = fw->size;
921 return 0;
922}
923
924static int DownloadMicrocode(struct drxd_state *state,
925 const u8 *pMCImage, u32 Length)
926{
927 u8 *pSrc;
928 u16 Flags;
929 u32 Address;
930 u16 nBlocks;
931 u16 BlockSize;
932 u16 BlockCRC;
933 u32 offset = 0;
934 int i, status = 0;
935
936 pSrc = (u8 *) pMCImage;
937 Flags = (pSrc[0] << 8) | pSrc[1];
938 pSrc += sizeof(u16);
939 offset += sizeof(u16);
940 nBlocks = (pSrc[0] << 8) | pSrc[1];
941 pSrc += sizeof(u16);
942 offset += sizeof(u16);
943
944 for (i = 0; i < nBlocks; i++) {
945 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
946 (pSrc[2] << 8) | pSrc[3];
947 pSrc += sizeof(u32);
948 offset += sizeof(u32);
949
950 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
951 pSrc += sizeof(u16);
952 offset += sizeof(u16);
953
954 Flags = (pSrc[0] << 8) | pSrc[1];
955 pSrc += sizeof(u16);
956 offset += sizeof(u16);
957
958 BlockCRC = (pSrc[0] << 8) | pSrc[1];
959 pSrc += sizeof(u16);
960 offset += sizeof(u16);
961
962 status = WriteBlock(state, Address, BlockSize,
963 pSrc, DRX_I2C_CLEARCRC);
964 if (status < 0)
965 break;
966 pSrc += BlockSize;
967 offset += BlockSize;
968 }
969
970 return status;
971}
972
973static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
974{
975 u32 nrRetries = 0;
976 u16 waitCmd;
977 int status;
978
979 status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
980 if (status < 0)
981 return status;
982
983 do {
984 nrRetries += 1;
985 if (nrRetries > DRXD_MAX_RETRIES) {
986 status = -1;
987 break;
988 };
989 status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
990 } while (waitCmd != 0);
991
992 if (status >= 0)
993 status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
994 return status;
995}
996
997static int HI_CfgCommand(struct drxd_state *state)
998{
999 int status = 0;
1000
1001 mutex_lock(&state->mutex);
1002 Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
1003 Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, state->hi_cfg_timing_div, 0);
1004 Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, state->hi_cfg_bridge_delay, 0);
1005 Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, state->hi_cfg_wakeup_key, 0);
1006 Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, state->hi_cfg_ctrl, 0);
1007
1008 Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
1009
1010 if ((state->hi_cfg_ctrl & HI_RA_RAM_SRV_CFG_ACT_PWD_EXE) ==
1011 HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)
1012 status = Write16(state, HI_RA_RAM_SRV_CMD__A,
1013 HI_RA_RAM_SRV_CMD_CONFIG, 0);
1014 else
1015 status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0);
1016 mutex_unlock(&state->mutex);
1017 return status;
1018}
1019
1020static int InitHI(struct drxd_state *state)
1021{
1022 state->hi_cfg_wakeup_key = (state->chip_adr);
1023 /* port/bridge/power down ctrl */
1024 state->hi_cfg_ctrl = HI_RA_RAM_SRV_CFG_ACT_SLV0_ON;
1025 return HI_CfgCommand(state);
1026}
1027
1028static int HI_ResetCommand(struct drxd_state *state)
1029{
1030 int status;
1031
1032 mutex_lock(&state->mutex);
1033 status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
1034 HI_RA_RAM_SRV_RST_KEY_ACT, 0);
1035 if (status == 0)
1036 status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0);
1037 mutex_unlock(&state->mutex);
1038 msleep(1);
1039 return status;
1040}
1041
1042static int DRX_ConfigureI2CBridge(struct drxd_state *state, int bEnableBridge)
1043{
1044 state->hi_cfg_ctrl &= (~HI_RA_RAM_SRV_CFG_ACT_BRD__M);
1045 if (bEnableBridge)
1046 state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_ON;
1047 else
1048 state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_OFF;
1049
1050 return HI_CfgCommand(state);
1051}
1052
1053#define HI_TR_WRITE 0x9
1054#define HI_TR_READ 0xA
1055#define HI_TR_READ_WRITE 0xB
1056#define HI_TR_BROADCAST 0x4
1057
1058#if 0
1059static int AtomicReadBlock(struct drxd_state *state,
1060 u32 Addr, u16 DataSize, u8 *pData, u8 Flags)
1061{
1062 int status;
1063 int i = 0;
1064
1065 /* Parameter check */
1066 if ((!pData) || ((DataSize & 1) != 0))
1067 return -1;
1068
1069 mutex_lock(&state->mutex);
1070
1071 do {
1072 /* Instruct HI to read n bytes */
1073 /* TODO use proper names forthese egisters */
1074 status = Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, (HI_TR_FUNC_ADDR & 0xFFFF), 0);
1075 if (status < 0)
1076 break;
1077 status = Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, (u16) (Addr >> 16), 0);
1078 if (status < 0)
1079 break;
1080 status = Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, (u16) (Addr & 0xFFFF), 0);
1081 if (status < 0)
1082 break;
1083 status = Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, (u16) ((DataSize / 2) - 1), 0);
1084 if (status < 0)
1085 break;
1086 status = Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, HI_TR_READ, 0);
1087 if (status < 0)
1088 break;
1089
1090 status = HI_Command(state, HI_RA_RAM_SRV_CMD_EXECUTE, 0);
1091 if (status < 0)
1092 break;
1093
1094 } while (0);
1095
1096 if (status >= 0) {
1097 for (i = 0; i < (DataSize / 2); i += 1) {
1098 u16 word;
1099
1100 status = Read16(state, (HI_RA_RAM_USR_BEGIN__A + i),
1101 &word, 0);
1102 if (status < 0)
1103 break;
1104 pData[2 * i] = (u8) (word & 0xFF);
1105 pData[(2 * i) + 1] = (u8) (word >> 8);
1106 }
1107 }
1108 mutex_unlock(&state->mutex);
1109 return status;
1110}
1111
1112static int AtomicReadReg32(struct drxd_state *state,
1113 u32 Addr, u32 *pData, u8 Flags)
1114{
1115 u8 buf[sizeof(u32)];
1116 int status;
1117
1118 if (!pData)
1119 return -1;
1120 status = AtomicReadBlock(state, Addr, sizeof(u32), buf, Flags);
1121 *pData = (((u32) buf[0]) << 0) +
1122 (((u32) buf[1]) << 8) +
1123 (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
1124 return status;
1125}
1126#endif
1127
1128static int StopAllProcessors(struct drxd_state *state)
1129{
1130 return Write16(state, HI_COMM_EXEC__A,
1131 SC_COMM_EXEC_CTL_STOP, DRX_I2C_BROADCAST);
1132}
1133
1134static int EnableAndResetMB(struct drxd_state *state)
1135{
1136 if (state->type_A) {
1137 /* disable? monitor bus observe @ EC_OC */
1138 Write16(state, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
1139 }
1140
1141 /* do inverse broadcast, followed by explicit write to HI */
1142 Write16(state, HI_COMM_MB__A, 0x0000, DRX_I2C_BROADCAST);
1143 Write16(state, HI_COMM_MB__A, 0x0000, 0x0000);
1144 return 0;
1145}
1146
1147static int InitCC(struct drxd_state *state)
1148{
1149 if (state->osc_clock_freq == 0 ||
1150 state->osc_clock_freq > 20000 ||
1151 (state->osc_clock_freq % 4000) != 0) {
1152 printk(KERN_ERR "invalid osc frequency %d\n", state->osc_clock_freq);
1153 return -1;
1154 }
1155
1156 Write16(state, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0);
1157 Write16(state, CC_REG_PLL_MODE__A, CC_REG_PLL_MODE_BYPASS_PLL |
1158 CC_REG_PLL_MODE_PUMP_CUR_12, 0);
1159 Write16(state, CC_REG_REF_DIVIDE__A, state->osc_clock_freq / 4000, 0);
1160 Write16(state, CC_REG_PWD_MODE__A, CC_REG_PWD_MODE_DOWN_PLL, 0);
1161 Write16(state, CC_REG_UPDATE__A, CC_REG_UPDATE_KEY, 0);
1162
1163 return 0;
1164}
1165
1166static int ResetECOD(struct drxd_state *state)
1167{
1168 int status = 0;
1169
1170 if (state->type_A)
1171 status = Write16(state, EC_OD_REG_SYNC__A, 0x0664, 0);
1172 else
1173 status = Write16(state, B_EC_OD_REG_SYNC__A, 0x0664, 0);
1174
1175 if (!(status < 0))
1176 status = WriteTable(state, state->m_ResetECRAM);
1177 if (!(status < 0))
1178 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0001, 0);
1179 return status;
1180}
1181
1182/* Configure PGA switch */
1183
1184static int SetCfgPga(struct drxd_state *state, int pgaSwitch)
1185{
1186 int status;
1187 u16 AgModeLop = 0;
1188 u16 AgModeHip = 0;
1189 do {
1190 if (pgaSwitch) {
1191 /* PGA on */
1192 /* fine gain */
1193 status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
1194 if (status < 0)
1195 break;
1196 AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
1197 AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC;
1198 status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
1199 if (status < 0)
1200 break;
1201
1202 /* coarse gain */
1203 status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
1204 if (status < 0)
1205 break;
1206 AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
1207 AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC;
1208 status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
1209 if (status < 0)
1210 break;
1211
1212 /* enable fine and coarse gain, enable AAF,
1213 no ext resistor */
1214 status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN, 0x0000);
1215 if (status < 0)
1216 break;
1217 } else {
1218 /* PGA off, bypass */
1219
1220 /* fine gain */
1221 status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
1222 if (status < 0)
1223 break;
1224 AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
1225 AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC;
1226 status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
1227 if (status < 0)
1228 break;
1229
1230 /* coarse gain */
1231 status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
1232 if (status < 0)
1233 break;
1234 AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
1235 AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC;
1236 status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
1237 if (status < 0)
1238 break;
1239
1240 /* disable fine and coarse gain, enable AAF,
1241 no ext resistor */
1242 status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);
1243 if (status < 0)
1244 break;
1245 }
1246 } while (0);
1247 return status;
1248}
1249
1250static int InitFE(struct drxd_state *state)
1251{
1252 int status;
1253
1254 do {
1255 status = WriteTable(state, state->m_InitFE_1);
1256 if (status < 0)
1257 break;
1258
1259 if (state->type_A) {
1260 status = Write16(state, FE_AG_REG_AG_PGA_MODE__A,
1261 FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
1262 0);
1263 } else {
1264 if (state->PGA)
1265 status = SetCfgPga(state, 0);
1266 else
1267 status =
1268 Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
1269 B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
1270 0);
1271 }
1272
1273 if (status < 0)
1274 break;
1275 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, state->m_FeAgRegAgAgcSio, 0x0000);
1276 if (status < 0)
1277 break;
1278 status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
1279 if (status < 0)
1280 break;
1281
1282 status = WriteTable(state, state->m_InitFE_2);
1283 if (status < 0)
1284 break;
1285
1286 } while (0);
1287
1288 return status;
1289}
1290
1291static int InitFT(struct drxd_state *state)
1292{
1293 /*
1294 norm OFFSET, MB says =2 voor 8K en =3 voor 2K waarschijnlijk
1295 SC stuff
1296 */
1297 return Write16(state, FT_REG_COMM_EXEC__A, 0x0001, 0x0000);
1298}
1299
1300static int SC_WaitForReady(struct drxd_state *state)
1301{
1302 u16 curCmd;
1303 int i;
1304
1305 for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
1306 int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
1307 if (status == 0 || curCmd == 0)
1308 return status;
1309 }
1310 return -1;
1311}
1312
1313static int SC_SendCommand(struct drxd_state *state, u16 cmd)
1314{
1315 int status = 0;
1316 u16 errCode;
1317
1318 Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
1319 SC_WaitForReady(state);
1320
1321 Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
1322
1323 if (errCode == 0xFFFF) {
1324 printk(KERN_ERR "Command Error\n");
1325 status = -1;
1326 }
1327
1328 return status;
1329}
1330
1331static int SC_ProcStartCommand(struct drxd_state *state,
1332 u16 subCmd, u16 param0, u16 param1)
1333{
1334 int status = 0;
1335 u16 scExec;
1336
1337 mutex_lock(&state->mutex);
1338 do {
1339 Read16(state, SC_COMM_EXEC__A, &scExec, 0);
1340 if (scExec != 1) {
1341 status = -1;
1342 break;
1343 }
1344 SC_WaitForReady(state);
1345 Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
1346 Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
1347 Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
1348
1349 SC_SendCommand(state, SC_RA_RAM_CMD_PROC_START);
1350 } while (0);
1351 mutex_unlock(&state->mutex);
1352 return status;
1353}
1354
1355static int SC_SetPrefParamCommand(struct drxd_state *state,
1356 u16 subCmd, u16 param0, u16 param1)
1357{
1358 int status;
1359
1360 mutex_lock(&state->mutex);
1361 do {
1362 status = SC_WaitForReady(state);
1363 if (status < 0)
1364 break;
1365 status = Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
1366 if (status < 0)
1367 break;
1368 status = Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
1369 if (status < 0)
1370 break;
1371 status = Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
1372 if (status < 0)
1373 break;
1374
1375 status = SC_SendCommand(state, SC_RA_RAM_CMD_SET_PREF_PARAM);
1376 if (status < 0)
1377 break;
1378 } while (0);
1379 mutex_unlock(&state->mutex);
1380 return status;
1381}
1382
1383#if 0
1384static int SC_GetOpParamCommand(struct drxd_state *state, u16 * result)
1385{
1386 int status = 0;
1387
1388 mutex_lock(&state->mutex);
1389 do {
1390 status = SC_WaitForReady(state);
1391 if (status < 0)
1392 break;
1393 status = SC_SendCommand(state, SC_RA_RAM_CMD_GET_OP_PARAM);
1394 if (status < 0)
1395 break;
1396 status = Read16(state, SC_RA_RAM_PARAM0__A, result, 0);
1397 if (status < 0)
1398 break;
1399 } while (0);
1400 mutex_unlock(&state->mutex);
1401 return status;
1402}
1403#endif
1404
1405static int ConfigureMPEGOutput(struct drxd_state *state, int bEnableOutput)
1406{
1407 int status;
1408
1409 do {
1410 u16 EcOcRegIprInvMpg = 0;
1411 u16 EcOcRegOcModeLop = 0;
1412 u16 EcOcRegOcModeHip = 0;
1413 u16 EcOcRegOcMpgSio = 0;
1414
1415 /*CHK_ERROR(Read16(state, EC_OC_REG_OC_MODE_LOP__A, &EcOcRegOcModeLop, 0)); */
1416
1417 if (state->operation_mode == OM_DVBT_Diversity_Front) {
1418 if (bEnableOutput) {
1419 EcOcRegOcModeHip |=
1420 B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR;
1421 } else
1422 EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
1423 EcOcRegOcModeLop |=
1424 EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
1425 } else {
1426 EcOcRegOcModeLop = state->m_EcOcRegOcModeLop;
1427
1428 if (bEnableOutput)
1429 EcOcRegOcMpgSio &= (~(EC_OC_REG_OC_MPG_SIO__M));
1430 else
1431 EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
1432
1433 /* Don't Insert RS Byte */
1434 if (state->insert_rs_byte) {
1435 EcOcRegOcModeLop &=
1436 (~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M));
1437 EcOcRegOcModeHip &=
1438 (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
1439 EcOcRegOcModeHip |=
1440 EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE;
1441 } else {
1442 EcOcRegOcModeLop |=
1443 EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
1444 EcOcRegOcModeHip &=
1445 (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
1446 EcOcRegOcModeHip |=
1447 EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE;
1448 }
1449
1450 /* Mode = Parallel */
1451 if (state->enable_parallel)
1452 EcOcRegOcModeLop &=
1453 (~(EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M));
1454 else
1455 EcOcRegOcModeLop |=
1456 EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL;
1457 }
1458 /* Invert Data */
1459 /* EcOcRegIprInvMpg |= 0x00FF; */
1460 EcOcRegIprInvMpg &= (~(0x00FF));
1461
1462 /* Invert Error ( we don't use the pin ) */
1463 /* EcOcRegIprInvMpg |= 0x0100; */
1464 EcOcRegIprInvMpg &= (~(0x0100));
1465
1466 /* Invert Start ( we don't use the pin ) */
1467 /* EcOcRegIprInvMpg |= 0x0200; */
1468 EcOcRegIprInvMpg &= (~(0x0200));
1469
1470 /* Invert Valid ( we don't use the pin ) */
1471 /* EcOcRegIprInvMpg |= 0x0400; */
1472 EcOcRegIprInvMpg &= (~(0x0400));
1473
1474 /* Invert Clock */
1475 /* EcOcRegIprInvMpg |= 0x0800; */
1476 EcOcRegIprInvMpg &= (~(0x0800));
1477
1478 /* EcOcRegOcModeLop =0x05; */
1479 status = Write16(state, EC_OC_REG_IPR_INV_MPG__A, EcOcRegIprInvMpg, 0);
1480 if (status < 0)
1481 break;
1482 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, EcOcRegOcModeLop, 0);
1483 if (status < 0)
1484 break;
1485 status = Write16(state, EC_OC_REG_OC_MODE_HIP__A, EcOcRegOcModeHip, 0x0000);
1486 if (status < 0)
1487 break;
1488 status = Write16(state, EC_OC_REG_OC_MPG_SIO__A, EcOcRegOcMpgSio, 0);
1489 if (status < 0)
1490 break;
1491 } while (0);
1492 return status;
1493}
1494
1495static int SetDeviceTypeId(struct drxd_state *state)
1496{
1497 int status = 0;
1498 u16 deviceId = 0;
1499
1500 do {
1501 status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
1502 if (status < 0)
1503 break;
1504 /* TODO: why twice? */
1505 status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
1506 if (status < 0)
1507 break;
1508 printk(KERN_INFO "drxd: deviceId = %04x\n", deviceId);
1509
1510 state->type_A = 0;
1511 state->PGA = 0;
1512 state->diversity = 0;
1513 if (deviceId == 0) { /* on A2 only 3975 available */
1514 state->type_A = 1;
1515 printk(KERN_INFO "DRX3975D-A2\n");
1516 } else {
1517 deviceId >>= 12;
1518 printk(KERN_INFO "DRX397%dD-B1\n", deviceId);
1519 switch (deviceId) {
1520 case 4:
1521 state->diversity = 1;
1522 case 3:
1523 case 7:
1524 state->PGA = 1;
1525 break;
1526 case 6:
1527 state->diversity = 1;
1528 case 5:
1529 case 8:
1530 break;
1531 default:
1532 status = -1;
1533 break;
1534 }
1535 }
1536 } while (0);
1537
1538 if (status < 0)
1539 return status;
1540
1541 /* Init Table selection */
1542 state->m_InitAtomicRead = DRXD_InitAtomicRead;
1543 state->m_InitSC = DRXD_InitSC;
1544 state->m_ResetECRAM = DRXD_ResetECRAM;
1545 if (state->type_A) {
1546 state->m_ResetCEFR = DRXD_ResetCEFR;
1547 state->m_InitFE_1 = DRXD_InitFEA2_1;
1548 state->m_InitFE_2 = DRXD_InitFEA2_2;
1549 state->m_InitCP = DRXD_InitCPA2;
1550 state->m_InitCE = DRXD_InitCEA2;
1551 state->m_InitEQ = DRXD_InitEQA2;
1552 state->m_InitEC = DRXD_InitECA2;
1553 if (load_firmware(state, DRX_FW_FILENAME_A2))
1554 return -EIO;
1555 } else {
1556 state->m_ResetCEFR = NULL;
1557 state->m_InitFE_1 = DRXD_InitFEB1_1;
1558 state->m_InitFE_2 = DRXD_InitFEB1_2;
1559 state->m_InitCP = DRXD_InitCPB1;
1560 state->m_InitCE = DRXD_InitCEB1;
1561 state->m_InitEQ = DRXD_InitEQB1;
1562 state->m_InitEC = DRXD_InitECB1;
1563 if (load_firmware(state, DRX_FW_FILENAME_B1))
1564 return -EIO;
1565 }
1566 if (state->diversity) {
1567 state->m_InitDiversityFront = DRXD_InitDiversityFront;
1568 state->m_InitDiversityEnd = DRXD_InitDiversityEnd;
1569 state->m_DisableDiversity = DRXD_DisableDiversity;
1570 state->m_StartDiversityFront = DRXD_StartDiversityFront;
1571 state->m_StartDiversityEnd = DRXD_StartDiversityEnd;
1572 state->m_DiversityDelay8MHZ = DRXD_DiversityDelay8MHZ;
1573 state->m_DiversityDelay6MHZ = DRXD_DiversityDelay6MHZ;
1574 } else {
1575 state->m_InitDiversityFront = NULL;
1576 state->m_InitDiversityEnd = NULL;
1577 state->m_DisableDiversity = NULL;
1578 state->m_StartDiversityFront = NULL;
1579 state->m_StartDiversityEnd = NULL;
1580 state->m_DiversityDelay8MHZ = NULL;
1581 state->m_DiversityDelay6MHZ = NULL;
1582 }
1583
1584 return status;
1585}
1586
1587static int CorrectSysClockDeviation(struct drxd_state *state)
1588{
1589 int status;
1590 s32 incr = 0;
1591 s32 nomincr = 0;
1592 u32 bandwidth = 0;
1593 u32 sysClockInHz = 0;
1594 u32 sysClockFreq = 0; /* in kHz */
1595 s16 oscClockDeviation;
1596 s16 Diff;
1597
1598 do {
1599 /* Retrieve bandwidth and incr, sanity check */
1600
1601 /* These accesses should be AtomicReadReg32, but that
1602 causes trouble (at least for diversity */
1603 status = Read32(state, LC_RA_RAM_IFINCR_NOM_L__A, ((u32 *) &nomincr), 0);
1604 if (status < 0)
1605 break;
1606 status = Read32(state, FE_IF_REG_INCR0__A, (u32 *) &incr, 0);
1607 if (status < 0)
1608 break;
1609
1610 if (state->type_A) {
1611 if ((nomincr - incr < -500) || (nomincr - incr > 500))
1612 break;
1613 } else {
1614 if ((nomincr - incr < -2000) || (nomincr - incr > 2000))
1615 break;
1616 }
1617
1618 switch (state->param.u.ofdm.bandwidth) {
1619 case BANDWIDTH_8_MHZ:
1620 bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
1621 break;
1622 case BANDWIDTH_7_MHZ:
1623 bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
1624 break;
1625 case BANDWIDTH_6_MHZ:
1626 bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
1627 break;
1628 default:
1629 return -1;
1630 break;
1631 }
1632
1633 /* Compute new sysclock value
1634 sysClockFreq = (((incr + 2^23)*bandwidth)/2^21)/1000 */
1635 incr += (1 << 23);
1636 sysClockInHz = MulDiv32(incr, bandwidth, 1 << 21);
1637 sysClockFreq = (u32) (sysClockInHz / 1000);
1638 /* rounding */
1639 if ((sysClockInHz % 1000) > 500)
1640 sysClockFreq++;
1641
1642 /* Compute clock deviation in ppm */
1643 oscClockDeviation = (u16) ((((s32) (sysClockFreq) -
1644 (s32)
1645 (state->expected_sys_clock_freq)) *
1646 1000000L) /
1647 (s32)
1648 (state->expected_sys_clock_freq));
1649
1650 Diff = oscClockDeviation - state->osc_clock_deviation;
1651 /*printk(KERN_INFO "sysclockdiff=%d\n", Diff); */
1652 if (Diff >= -200 && Diff <= 200) {
1653 state->sys_clock_freq = (u16) sysClockFreq;
1654 if (oscClockDeviation != state->osc_clock_deviation) {
1655 if (state->config.osc_deviation) {
1656 state->config.osc_deviation(state->priv,
1657 oscClockDeviation,
1658 1);
1659 state->osc_clock_deviation =
1660 oscClockDeviation;
1661 }
1662 }
1663 /* switch OFF SRMM scan in SC */
1664 status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DONT_SCAN, 0);
1665 if (status < 0)
1666 break;
1667 /* overrule FE_IF internal value for
1668 proper re-locking */
1669 status = Write16(state, SC_RA_RAM_IF_SAVE__AX, state->current_fe_if_incr, 0);
1670 if (status < 0)
1671 break;
1672 state->cscd_state = CSCD_SAVED;
1673 }
1674 } while (0);
1675
1676 return status;
1677}
1678
1679static int DRX_Stop(struct drxd_state *state)
1680{
1681 int status;
1682
1683 if (state->drxd_state != DRXD_STARTED)
1684 return 0;
1685
1686 do {
1687 if (state->cscd_state != CSCD_SAVED) {
1688 u32 lock;
1689 status = DRX_GetLockStatus(state, &lock);
1690 if (status < 0)
1691 break;
1692 }
1693
1694 status = StopOC(state);
1695 if (status < 0)
1696 break;
1697
1698 state->drxd_state = DRXD_STOPPED;
1699
1700 status = ConfigureMPEGOutput(state, 0);
1701 if (status < 0)
1702 break;
1703
1704 if (state->type_A) {
1705 /* Stop relevant processors off the device */
1706 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0x0000);
1707 if (status < 0)
1708 break;
1709
1710 status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1711 if (status < 0)
1712 break;
1713 status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1714 if (status < 0)
1715 break;
1716 } else {
1717 /* Stop all processors except HI & CC & FE */
1718 status = Write16(state, B_SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1719 if (status < 0)
1720 break;
1721 status = Write16(state, B_LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1722 if (status < 0)
1723 break;
1724 status = Write16(state, B_FT_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1725 if (status < 0)
1726 break;
1727 status = Write16(state, B_CP_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1728 if (status < 0)
1729 break;
1730 status = Write16(state, B_CE_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1731 if (status < 0)
1732 break;
1733 status = Write16(state, B_EQ_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1734 if (status < 0)
1735 break;
1736 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0);
1737 if (status < 0)
1738 break;
1739 }
1740
1741 } while (0);
1742 return status;
1743}
1744
1745int SetOperationMode(struct drxd_state *state, int oMode)
1746{
1747 int status;
1748
1749 do {
1750 if (state->drxd_state != DRXD_STOPPED) {
1751 status = -1;
1752 break;
1753 }
1754
1755 if (oMode == state->operation_mode) {
1756 status = 0;
1757 break;
1758 }
1759
1760 if (oMode != OM_Default && !state->diversity) {
1761 status = -1;
1762 break;
1763 }
1764
1765 switch (oMode) {
1766 case OM_DVBT_Diversity_Front:
1767 status = WriteTable(state, state->m_InitDiversityFront);
1768 break;
1769 case OM_DVBT_Diversity_End:
1770 status = WriteTable(state, state->m_InitDiversityEnd);
1771 break;
1772 case OM_Default:
1773 /* We need to check how to
1774 get DRXD out of diversity */
1775 default:
1776 status = WriteTable(state, state->m_DisableDiversity);
1777 break;
1778 }
1779 } while (0);
1780
1781 if (!status)
1782 state->operation_mode = oMode;
1783 return status;
1784}
1785
1786static int StartDiversity(struct drxd_state *state)
1787{
1788 int status = 0;
1789 u16 rcControl;
1790
1791 do {
1792 if (state->operation_mode == OM_DVBT_Diversity_Front) {
1793 status = WriteTable(state, state->m_StartDiversityFront);
1794 if (status < 0)
1795 break;
1796 } else if (state->operation_mode == OM_DVBT_Diversity_End) {
1797 status = WriteTable(state, state->m_StartDiversityEnd);
1798 if (status < 0)
1799 break;
1800 if (state->param.u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
1801 status = WriteTable(state, state->m_DiversityDelay8MHZ);
1802 if (status < 0)
1803 break;
1804 } else {
1805 status = WriteTable(state, state->m_DiversityDelay6MHZ);
1806 if (status < 0)
1807 break;
1808 }
1809
1810 status = Read16(state, B_EQ_REG_RC_SEL_CAR__A, &rcControl, 0);
1811 if (status < 0)
1812 break;
1813 rcControl &= ~(B_EQ_REG_RC_SEL_CAR_FFTMODE__M);
1814 rcControl |= B_EQ_REG_RC_SEL_CAR_DIV_ON |
1815 /* combining enabled */
1816 B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
1817 B_EQ_REG_RC_SEL_CAR_PASS_A_CC |
1818 B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC;
1819 status = Write16(state, B_EQ_REG_RC_SEL_CAR__A, rcControl, 0);
1820 if (status < 0)
1821 break;
1822 }
1823 } while (0);
1824 return status;
1825}
1826
1827static int SetFrequencyShift(struct drxd_state *state,
1828 u32 offsetFreq, int channelMirrored)
1829{
1830 int negativeShift = (state->tuner_mirrors == channelMirrored);
1831
1832 /* Handle all mirroring
1833 *
1834 * Note: ADC mirroring (aliasing) is implictly handled by limiting
1835 * feFsRegAddInc to 28 bits below
1836 * (if the result before masking is more than 28 bits, this means
1837 * that the ADC is mirroring.
1838 * The masking is in fact the aliasing of the ADC)
1839 *
1840 */
1841
1842 /* Compute register value, unsigned computation */
1843 state->fe_fs_add_incr = MulDiv32(state->intermediate_freq +
1844 offsetFreq,
1845 1 << 28, state->sys_clock_freq);
1846 /* Remove integer part */
1847 state->fe_fs_add_incr &= 0x0FFFFFFFL;
1848 if (negativeShift)
1849 state->fe_fs_add_incr = ((1 << 28) - state->fe_fs_add_incr);
1850
1851 /* Save the frequency shift without tunerOffset compensation
1852 for CtrlGetChannel. */
1853 state->org_fe_fs_add_incr = MulDiv32(state->intermediate_freq,
1854 1 << 28, state->sys_clock_freq);
1855 /* Remove integer part */
1856 state->org_fe_fs_add_incr &= 0x0FFFFFFFL;
1857 if (negativeShift)
1858 state->org_fe_fs_add_incr = ((1L << 28) -
1859 state->org_fe_fs_add_incr);
1860
1861 return Write32(state, FE_FS_REG_ADD_INC_LOP__A,
1862 state->fe_fs_add_incr, 0);
1863}
1864
1865static int SetCfgNoiseCalibration(struct drxd_state *state,
1866 struct SNoiseCal *noiseCal)
1867{
1868 u16 beOptEna;
1869 int status = 0;
1870
1871 do {
1872 status = Read16(state, SC_RA_RAM_BE_OPT_ENA__A, &beOptEna, 0);
1873 if (status < 0)
1874 break;
1875 if (noiseCal->cpOpt) {
1876 beOptEna |= (1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
1877 } else {
1878 beOptEna &= ~(1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
1879 status = Write16(state, CP_REG_AC_NEXP_OFFS__A, noiseCal->cpNexpOfs, 0);
1880 if (status < 0)
1881 break;
1882 }
1883 status = Write16(state, SC_RA_RAM_BE_OPT_ENA__A, beOptEna, 0);
1884 if (status < 0)
1885 break;
1886
1887 if (!state->type_A) {
1888 status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_2K__A, noiseCal->tdCal2k, 0);
1889 if (status < 0)
1890 break;
1891 status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_8K__A, noiseCal->tdCal8k, 0);
1892 if (status < 0)
1893 break;
1894 }
1895 } while (0);
1896
1897 return status;
1898}
1899
1900static int DRX_Start(struct drxd_state *state, s32 off)
1901{
1902 struct dvb_ofdm_parameters *p = &state->param.u.ofdm;
1903 int status;
1904
1905 u16 transmissionParams = 0;
1906 u16 operationMode = 0;
1907 u16 qpskTdTpsPwr = 0;
1908 u16 qam16TdTpsPwr = 0;
1909 u16 qam64TdTpsPwr = 0;
1910 u32 feIfIncr = 0;
1911 u32 bandwidth = 0;
1912 int mirrorFreqSpect;
1913
1914 u16 qpskSnCeGain = 0;
1915 u16 qam16SnCeGain = 0;
1916 u16 qam64SnCeGain = 0;
1917 u16 qpskIsGainMan = 0;
1918 u16 qam16IsGainMan = 0;
1919 u16 qam64IsGainMan = 0;
1920 u16 qpskIsGainExp = 0;
1921 u16 qam16IsGainExp = 0;
1922 u16 qam64IsGainExp = 0;
1923 u16 bandwidthParam = 0;
1924
1925 if (off < 0)
1926 off = (off - 500) / 1000;
1927 else
1928 off = (off + 500) / 1000;
1929
1930 do {
1931 if (state->drxd_state != DRXD_STOPPED)
1932 return -1;
1933 status = ResetECOD(state);
1934 if (status < 0)
1935 break;
1936 if (state->type_A) {
1937 status = InitSC(state);
1938 if (status < 0)
1939 break;
1940 } else {
1941 status = InitFT(state);
1942 if (status < 0)
1943 break;
1944 status = InitCP(state);
1945 if (status < 0)
1946 break;
1947 status = InitCE(state);
1948 if (status < 0)
1949 break;
1950 status = InitEQ(state);
1951 if (status < 0)
1952 break;
1953 status = InitSC(state);
1954 if (status < 0)
1955 break;
1956 }
1957
1958 /* Restore current IF & RF AGC settings */
1959
1960 status = SetCfgIfAgc(state, &state->if_agc_cfg);
1961 if (status < 0)
1962 break;
1963 status = SetCfgRfAgc(state, &state->rf_agc_cfg);
1964 if (status < 0)
1965 break;
1966
1967 mirrorFreqSpect = (state->param.inversion == INVERSION_ON);
1968
1969 switch (p->transmission_mode) {
1970 default: /* Not set, detect it automatically */
1971 operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
1972 /* fall through , try first guess DRX_FFTMODE_8K */
1973 case TRANSMISSION_MODE_8K:
1974 transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
1975 if (state->type_A) {
1976 status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_8K, 0x0000);
1977 if (status < 0)
1978 break;
1979 qpskSnCeGain = 99;
1980 qam16SnCeGain = 83;
1981 qam64SnCeGain = 67;
1982 }
1983 break;
1984 case TRANSMISSION_MODE_2K:
1985 transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_2K;
1986 if (state->type_A) {
1987 status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_2K, 0x0000);
1988 if (status < 0)
1989 break;
1990 qpskSnCeGain = 97;
1991 qam16SnCeGain = 71;
1992 qam64SnCeGain = 65;
1993 }
1994 break;
1995 }
1996
1997 switch (p->guard_interval) {
1998 case GUARD_INTERVAL_1_4:
1999 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
2000 break;
2001 case GUARD_INTERVAL_1_8:
2002 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_8;
2003 break;
2004 case GUARD_INTERVAL_1_16:
2005 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_16;
2006 break;
2007 case GUARD_INTERVAL_1_32:
2008 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_32;
2009 break;
2010 default: /* Not set, detect it automatically */
2011 operationMode |= SC_RA_RAM_OP_AUTO_GUARD__M;
2012 /* try first guess 1/4 */
2013 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
2014 break;
2015 }
2016
2017 switch (p->hierarchy_information) {
2018 case HIERARCHY_1:
2019 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1;
2020 if (state->type_A) {
2021 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0001, 0x0000);
2022 if (status < 0)
2023 break;
2024 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0001, 0x0000);
2025 if (status < 0)
2026 break;
2027
2028 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
2029 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA1;
2030 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA1;
2031
2032 qpskIsGainMan =
2033 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
2034 qam16IsGainMan =
2035 SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
2036 qam64IsGainMan =
2037 SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
2038
2039 qpskIsGainExp =
2040 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
2041 qam16IsGainExp =
2042 SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
2043 qam64IsGainExp =
2044 SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
2045 }
2046 break;
2047
2048 case HIERARCHY_2:
2049 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A2;
2050 if (state->type_A) {
2051 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0002, 0x0000);
2052 if (status < 0)
2053 break;
2054 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0002, 0x0000);
2055 if (status < 0)
2056 break;
2057
2058 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
2059 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA2;
2060 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA2;
2061
2062 qpskIsGainMan =
2063 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
2064 qam16IsGainMan =
2065 SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE;
2066 qam64IsGainMan =
2067 SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE;
2068
2069 qpskIsGainExp =
2070 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
2071 qam16IsGainExp =
2072 SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE;
2073 qam64IsGainExp =
2074 SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE;
2075 }
2076 break;
2077 case HIERARCHY_4:
2078 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A4;
2079 if (state->type_A) {
2080 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0003, 0x0000);
2081 if (status < 0)
2082 break;
2083 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0003, 0x0000);
2084 if (status < 0)
2085 break;
2086
2087 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
2088 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA4;
2089 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA4;
2090
2091 qpskIsGainMan =
2092 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
2093 qam16IsGainMan =
2094 SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE;
2095 qam64IsGainMan =
2096 SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE;
2097
2098 qpskIsGainExp =
2099 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
2100 qam16IsGainExp =
2101 SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE;
2102 qam64IsGainExp =
2103 SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE;
2104 }
2105 break;
2106 case HIERARCHY_AUTO:
2107 default:
2108 /* Not set, detect it automatically, start with none */
2109 operationMode |= SC_RA_RAM_OP_AUTO_HIER__M;
2110 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_NO;
2111 if (state->type_A) {
2112 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0000, 0x0000);
2113 if (status < 0)
2114 break;
2115 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0000, 0x0000);
2116 if (status < 0)
2117 break;
2118
2119 qpskTdTpsPwr = EQ_TD_TPS_PWR_QPSK;
2120 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHAN;
2121 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHAN;
2122
2123 qpskIsGainMan =
2124 SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE;
2125 qam16IsGainMan =
2126 SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
2127 qam64IsGainMan =
2128 SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
2129
2130 qpskIsGainExp =
2131 SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE;
2132 qam16IsGainExp =
2133 SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
2134 qam64IsGainExp =
2135 SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
2136 }
2137 break;
2138 }
2139 status = status;
2140 if (status < 0)
2141 break;
2142
2143 switch (p->constellation) {
2144 default:
2145 operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
2146 /* fall through , try first guess
2147 DRX_CONSTELLATION_QAM64 */
2148 case QAM_64:
2149 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
2150 if (state->type_A) {
2151 status = Write16(state, EQ_REG_OT_CONST__A, 0x0002, 0x0000);
2152 if (status < 0)
2153 break;
2154 status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_64QAM, 0x0000);
2155 if (status < 0)
2156 break;
2157 status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0020, 0x0000);
2158 if (status < 0)
2159 break;
2160 status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0008, 0x0000);
2161 if (status < 0)
2162 break;
2163 status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0002, 0x0000);
2164 if (status < 0)
2165 break;
2166
2167 status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam64TdTpsPwr, 0x0000);
2168 if (status < 0)
2169 break;
2170 status = Write16(state, EQ_REG_SN_CEGAIN__A, qam64SnCeGain, 0x0000);
2171 if (status < 0)
2172 break;
2173 status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam64IsGainMan, 0x0000);
2174 if (status < 0)
2175 break;
2176 status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam64IsGainExp, 0x0000);
2177 if (status < 0)
2178 break;
2179 }
2180 break;
2181 case QPSK:
2182 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QPSK;
2183 if (state->type_A) {
2184 status = Write16(state, EQ_REG_OT_CONST__A, 0x0000, 0x0000);
2185 if (status < 0)
2186 break;
2187 status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_QPSK, 0x0000);
2188 if (status < 0)
2189 break;
2190 status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
2191 if (status < 0)
2192 break;
2193 status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0000, 0x0000);
2194 if (status < 0)
2195 break;
2196 status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
2197 if (status < 0)
2198 break;
2199
2200 status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qpskTdTpsPwr, 0x0000);
2201 if (status < 0)
2202 break;
2203 status = Write16(state, EQ_REG_SN_CEGAIN__A, qpskSnCeGain, 0x0000);
2204 if (status < 0)
2205 break;
2206 status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qpskIsGainMan, 0x0000);
2207 if (status < 0)
2208 break;
2209 status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qpskIsGainExp, 0x0000);
2210 if (status < 0)
2211 break;
2212 }
2213 break;
2214
2215 case QAM_16:
2216 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM16;
2217 if (state->type_A) {
2218 status = Write16(state, EQ_REG_OT_CONST__A, 0x0001, 0x0000);
2219 if (status < 0)
2220 break;
2221 status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_16QAM, 0x0000);
2222 if (status < 0)
2223 break;
2224 status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
2225 if (status < 0)
2226 break;
2227 status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0004, 0x0000);
2228 if (status < 0)
2229 break;
2230 status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
2231 if (status < 0)
2232 break;
2233
2234 status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam16TdTpsPwr, 0x0000);
2235 if (status < 0)
2236 break;
2237 status = Write16(state, EQ_REG_SN_CEGAIN__A, qam16SnCeGain, 0x0000);
2238 if (status < 0)
2239 break;
2240 status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam16IsGainMan, 0x0000);
2241 if (status < 0)
2242 break;
2243 status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam16IsGainExp, 0x0000);
2244 if (status < 0)
2245 break;
2246 }
2247 break;
2248
2249 }
2250 status = status;
2251 if (status < 0)
2252 break;
2253
2254 switch (DRX_CHANNEL_HIGH) {
2255 default:
2256 case DRX_CHANNEL_AUTO:
2257 case DRX_CHANNEL_LOW:
2258 transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO;
2259 status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000);
2260 if (status < 0)
2261 break;
2262 break;
2263 case DRX_CHANNEL_HIGH:
2264 transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI;
2265 status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000);
2266 if (status < 0)
2267 break;
2268 break;
2269
2270 }
2271
2272 switch (p->code_rate_HP) {
2273 case FEC_1_2:
2274 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2;
2275 if (state->type_A) {
2276 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000);
2277 if (status < 0)
2278 break;
2279 }
2280 break;
2281 default:
2282 operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
2283 case FEC_2_3:
2284 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
2285 if (state->type_A) {
2286 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000);
2287 if (status < 0)
2288 break;
2289 }
2290 break;
2291 case FEC_3_4:
2292 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4;
2293 if (state->type_A) {
2294 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000);
2295 if (status < 0)
2296 break;
2297 }
2298 break;
2299 case FEC_5_6:
2300 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6;
2301 if (state->type_A) {
2302 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000);
2303 if (status < 0)
2304 break;
2305 }
2306 break;
2307 case FEC_7_8:
2308 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8;
2309 if (state->type_A) {
2310 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000);
2311 if (status < 0)
2312 break;
2313 }
2314 break;
2315 }
2316 status = status;
2317 if (status < 0)
2318 break;
2319
2320 /* First determine real bandwidth (Hz) */
2321 /* Also set delay for impulse noise cruncher (only A2) */
2322 /* Also set parameters for EC_OC fix, note
2323 EC_OC_REG_TMD_HIL_MAR is changed
2324 by SC for fix for some 8K,1/8 guard but is restored by
2325 InitEC and ResetEC
2326 functions */
2327 switch (p->bandwidth) {
2328 case BANDWIDTH_AUTO:
2329 case BANDWIDTH_8_MHZ:
2330 /* (64/7)*(8/8)*1000000 */
2331 bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
2332
2333 bandwidthParam = 0;
2334 status = Write16(state,
2335 FE_AG_REG_IND_DEL__A, 50, 0x0000);
2336 break;
2337 case BANDWIDTH_7_MHZ:
2338 /* (64/7)*(7/8)*1000000 */
2339 bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
2340 bandwidthParam = 0x4807; /*binary:0100 1000 0000 0111 */
2341 status = Write16(state,
2342 FE_AG_REG_IND_DEL__A, 59, 0x0000);
2343 break;
2344 case BANDWIDTH_6_MHZ:
2345 /* (64/7)*(6/8)*1000000 */
2346 bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
2347 bandwidthParam = 0x0F07; /*binary: 0000 1111 0000 0111 */
2348 status = Write16(state,
2349 FE_AG_REG_IND_DEL__A, 71, 0x0000);
2350 break;
2351 default:
2352 status = -EINVAL;
2353 }
2354 if (status < 0)
2355 break;
2356
2357 status = Write16(state, SC_RA_RAM_BAND__A, bandwidthParam, 0x0000);
2358 if (status < 0)
2359 break;
2360
2361 {
2362 u16 sc_config;
2363 status = Read16(state, SC_RA_RAM_CONFIG__A, &sc_config, 0);
2364 if (status < 0)
2365 break;
2366
2367 /* enable SLAVE mode in 2k 1/32 to
2368 prevent timing change glitches */
2369 if ((p->transmission_mode == TRANSMISSION_MODE_2K) &&
2370 (p->guard_interval == GUARD_INTERVAL_1_32)) {
2371 /* enable slave */
2372 sc_config |= SC_RA_RAM_CONFIG_SLAVE__M;
2373 } else {
2374 /* disable slave */
2375 sc_config &= ~SC_RA_RAM_CONFIG_SLAVE__M;
2376 }
2377 status = Write16(state, SC_RA_RAM_CONFIG__A, sc_config, 0);
2378 if (status < 0)
2379 break;
2380 }
2381
2382 status = SetCfgNoiseCalibration(state, &state->noise_cal);
2383 if (status < 0)
2384 break;
2385
2386 if (state->cscd_state == CSCD_INIT) {
2387 /* switch on SRMM scan in SC */
2388 status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DO_SCAN, 0x0000);
2389 if (status < 0)
2390 break;
2391/* CHK_ERROR(Write16(SC_RA_RAM_SAMPLE_RATE_STEP__A, DRXD_OSCDEV_STEP, 0x0000));*/
2392 state->cscd_state = CSCD_SET;
2393 }
2394
2395 /* Now compute FE_IF_REG_INCR */
2396 /*((( SysFreq/BandWidth)/2)/2) -1) * 2^23) =>
2397 ((SysFreq / BandWidth) * (2^21) ) - (2^23) */
2398 feIfIncr = MulDiv32(state->sys_clock_freq * 1000,
2399 (1ULL << 21), bandwidth) - (1 << 23);
2400 status = Write16(state, FE_IF_REG_INCR0__A, (u16) (feIfIncr & FE_IF_REG_INCR0__M), 0x0000);
2401 if (status < 0)
2402 break;
2403 status = Write16(state, FE_IF_REG_INCR1__A, (u16) ((feIfIncr >> FE_IF_REG_INCR0__W) & FE_IF_REG_INCR1__M), 0x0000);
2404 if (status < 0)
2405 break;
2406 /* Bandwidth setting done */
2407
2408 /* Mirror & frequency offset */
2409 SetFrequencyShift(state, off, mirrorFreqSpect);
2410
2411 /* Start SC, write channel settings to SC */
2412
2413 /* Enable SC after setting all other parameters */
2414 status = Write16(state, SC_COMM_STATE__A, 0, 0x0000);
2415 if (status < 0)
2416 break;
2417 status = Write16(state, SC_COMM_EXEC__A, 1, 0x0000);
2418 if (status < 0)
2419 break;
2420
2421 /* Write SC parameter registers, operation mode */
2422#if 1
2423 operationMode = (SC_RA_RAM_OP_AUTO_MODE__M |
2424 SC_RA_RAM_OP_AUTO_GUARD__M |
2425 SC_RA_RAM_OP_AUTO_CONST__M |
2426 SC_RA_RAM_OP_AUTO_HIER__M |
2427 SC_RA_RAM_OP_AUTO_RATE__M);
2428#endif
2429 status = SC_SetPrefParamCommand(state, 0x0000, transmissionParams, operationMode);
2430 if (status < 0)
2431 break;
2432
2433 /* Start correct processes to get in lock */
2434 status = SC_ProcStartCommand(state, SC_RA_RAM_PROC_LOCKTRACK, SC_RA_RAM_SW_EVENT_RUN_NMASK__M, SC_RA_RAM_LOCKTRACK_MIN);
2435 if (status < 0)
2436 break;
2437
2438 status = StartOC(state);
2439 if (status < 0)
2440 break;
2441
2442 if (state->operation_mode != OM_Default) {
2443 status = StartDiversity(state);
2444 if (status < 0)
2445 break;
2446 }
2447
2448 state->drxd_state = DRXD_STARTED;
2449 } while (0);
2450
2451 return status;
2452}
2453
2454static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
2455{
2456 u32 ulRfAgcOutputLevel = 0xffffffff;
2457 u32 ulRfAgcSettleLevel = 528; /* Optimum value for MT2060 */
2458 u32 ulRfAgcMinLevel = 0; /* Currently unused */
2459 u32 ulRfAgcMaxLevel = DRXD_FE_CTRL_MAX; /* Currently unused */
2460 u32 ulRfAgcSpeed = 0; /* Currently unused */
2461 u32 ulRfAgcMode = 0; /*2; Off */
2462 u32 ulRfAgcR1 = 820;
2463 u32 ulRfAgcR2 = 2200;
2464 u32 ulRfAgcR3 = 150;
2465 u32 ulIfAgcMode = 0; /* Auto */
2466 u32 ulIfAgcOutputLevel = 0xffffffff;
2467 u32 ulIfAgcSettleLevel = 0xffffffff;
2468 u32 ulIfAgcMinLevel = 0xffffffff;
2469 u32 ulIfAgcMaxLevel = 0xffffffff;
2470 u32 ulIfAgcSpeed = 0xffffffff;
2471 u32 ulIfAgcR1 = 820;
2472 u32 ulIfAgcR2 = 2200;
2473 u32 ulIfAgcR3 = 150;
2474 u32 ulClock = state->config.clock;
2475 u32 ulSerialMode = 0;
2476 u32 ulEcOcRegOcModeLop = 4; /* Dynamic DTO source */
2477 u32 ulHiI2cDelay = HI_I2C_DELAY;
2478 u32 ulHiI2cBridgeDelay = HI_I2C_BRIDGE_DELAY;
2479 u32 ulHiI2cPatch = 0;
2480 u32 ulEnvironment = APPENV_PORTABLE;
2481 u32 ulEnvironmentDiversity = APPENV_MOBILE;
2482 u32 ulIFFilter = IFFILTER_SAW;
2483
2484 state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2485 state->if_agc_cfg.outputLevel = 0;
2486 state->if_agc_cfg.settleLevel = 140;
2487 state->if_agc_cfg.minOutputLevel = 0;
2488 state->if_agc_cfg.maxOutputLevel = 1023;
2489 state->if_agc_cfg.speed = 904;
2490
2491 if (ulIfAgcMode == 1 && ulIfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
2492 state->if_agc_cfg.ctrlMode = AGC_CTRL_USER;
2493 state->if_agc_cfg.outputLevel = (u16) (ulIfAgcOutputLevel);
2494 }
2495
2496 if (ulIfAgcMode == 0 &&
2497 ulIfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
2498 ulIfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
2499 ulIfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
2500 ulIfAgcSpeed <= DRXD_FE_CTRL_MAX) {
2501 state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2502 state->if_agc_cfg.settleLevel = (u16) (ulIfAgcSettleLevel);
2503 state->if_agc_cfg.minOutputLevel = (u16) (ulIfAgcMinLevel);
2504 state->if_agc_cfg.maxOutputLevel = (u16) (ulIfAgcMaxLevel);
2505 state->if_agc_cfg.speed = (u16) (ulIfAgcSpeed);
2506 }
2507
2508 state->if_agc_cfg.R1 = (u16) (ulIfAgcR1);
2509 state->if_agc_cfg.R2 = (u16) (ulIfAgcR2);
2510 state->if_agc_cfg.R3 = (u16) (ulIfAgcR3);
2511
2512 state->rf_agc_cfg.R1 = (u16) (ulRfAgcR1);
2513 state->rf_agc_cfg.R2 = (u16) (ulRfAgcR2);
2514 state->rf_agc_cfg.R3 = (u16) (ulRfAgcR3);
2515
2516 state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2517 /* rest of the RFAgcCfg structure currently unused */
2518 if (ulRfAgcMode == 1 && ulRfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
2519 state->rf_agc_cfg.ctrlMode = AGC_CTRL_USER;
2520 state->rf_agc_cfg.outputLevel = (u16) (ulRfAgcOutputLevel);
2521 }
2522
2523 if (ulRfAgcMode == 0 &&
2524 ulRfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
2525 ulRfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
2526 ulRfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
2527 ulRfAgcSpeed <= DRXD_FE_CTRL_MAX) {
2528 state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2529 state->rf_agc_cfg.settleLevel = (u16) (ulRfAgcSettleLevel);
2530 state->rf_agc_cfg.minOutputLevel = (u16) (ulRfAgcMinLevel);
2531 state->rf_agc_cfg.maxOutputLevel = (u16) (ulRfAgcMaxLevel);
2532 state->rf_agc_cfg.speed = (u16) (ulRfAgcSpeed);
2533 }
2534
2535 if (ulRfAgcMode == 2)
2536 state->rf_agc_cfg.ctrlMode = AGC_CTRL_OFF;
2537
2538 if (ulEnvironment <= 2)
2539 state->app_env_default = (enum app_env)
2540 (ulEnvironment);
2541 if (ulEnvironmentDiversity <= 2)
2542 state->app_env_diversity = (enum app_env)
2543 (ulEnvironmentDiversity);
2544
2545 if (ulIFFilter == IFFILTER_DISCRETE) {
2546 /* discrete filter */
2547 state->noise_cal.cpOpt = 0;
2548 state->noise_cal.cpNexpOfs = 40;
2549 state->noise_cal.tdCal2k = -40;
2550 state->noise_cal.tdCal8k = -24;
2551 } else {
2552 /* SAW filter */
2553 state->noise_cal.cpOpt = 1;
2554 state->noise_cal.cpNexpOfs = 0;
2555 state->noise_cal.tdCal2k = -21;
2556 state->noise_cal.tdCal8k = -24;
2557 }
2558 state->m_EcOcRegOcModeLop = (u16) (ulEcOcRegOcModeLop);
2559
2560 state->chip_adr = (state->config.demod_address << 1) | 1;
2561 switch (ulHiI2cPatch) {
2562 case 1:
2563 state->m_HiI2cPatch = DRXD_HiI2cPatch_1;
2564 break;
2565 case 3:
2566 state->m_HiI2cPatch = DRXD_HiI2cPatch_3;
2567 break;
2568 default:
2569 state->m_HiI2cPatch = NULL;
2570 }
2571
2572 /* modify tuner and clock attributes */
2573 state->intermediate_freq = (u16) (IntermediateFrequency / 1000);
2574 /* expected system clock frequency in kHz */
2575 state->expected_sys_clock_freq = 48000;
2576 /* real system clock frequency in kHz */
2577 state->sys_clock_freq = 48000;
2578 state->osc_clock_freq = (u16) ulClock;
2579 state->osc_clock_deviation = 0;
2580 state->cscd_state = CSCD_INIT;
2581 state->drxd_state = DRXD_UNINITIALIZED;
2582
2583 state->PGA = 0;
2584 state->type_A = 0;
2585 state->tuner_mirrors = 0;
2586
2587 /* modify MPEG output attributes */
2588 state->insert_rs_byte = state->config.insert_rs_byte;
2589 state->enable_parallel = (ulSerialMode != 1);
2590
2591 /* Timing div, 250ns/Psys */
2592 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2593
2594 state->hi_cfg_timing_div = (u16) ((state->sys_clock_freq / 1000) *
2595 ulHiI2cDelay) / 1000;
2596 /* Bridge delay, uses oscilator clock */
2597 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2598 state->hi_cfg_bridge_delay = (u16) ((state->osc_clock_freq / 1000) *
2599 ulHiI2cBridgeDelay) / 1000;
2600
2601 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
2602 /* state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO; */
2603 state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
2604 return 0;
2605}
2606
2607int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
2608{
2609 int status = 0;
2610 u32 driverVersion;
2611
2612 if (state->init_done)
2613 return 0;
2614
2615 CDRXD(state, state->config.IF ? state->config.IF : 36000000);
2616
2617 do {
2618 state->operation_mode = OM_Default;
2619
2620 status = SetDeviceTypeId(state);
2621 if (status < 0)
2622 break;
2623
2624 /* Apply I2c address patch to B1 */
2625 if (!state->type_A && state->m_HiI2cPatch != NULL)
2626 status = WriteTable(state, state->m_HiI2cPatch);
2627 if (status < 0)
2628 break;
2629
2630 if (state->type_A) {
2631 /* HI firmware patch for UIO readout,
2632 avoid clearing of result register */
2633 status = Write16(state, 0x43012D, 0x047f, 0);
2634 if (status < 0)
2635 break;
2636 }
2637
2638 status = HI_ResetCommand(state);
2639 if (status < 0)
2640 break;
2641
2642 status = StopAllProcessors(state);
2643 if (status < 0)
2644 break;
2645 status = InitCC(state);
2646 if (status < 0)
2647 break;
2648
2649 state->osc_clock_deviation = 0;
2650
2651 if (state->config.osc_deviation)
2652 state->osc_clock_deviation =
2653 state->config.osc_deviation(state->priv, 0, 0);
2654 {
2655 /* Handle clock deviation */
2656 s32 devB;
2657 s32 devA = (s32) (state->osc_clock_deviation) *
2658 (s32) (state->expected_sys_clock_freq);
2659 /* deviation in kHz */
2660 s32 deviation = (devA / (1000000L));
2661 /* rounding, signed */
2662 if (devA > 0)
2663 devB = (2);
2664 else
2665 devB = (-2);
2666 if ((devB * (devA % 1000000L) > 1000000L)) {
2667 /* add +1 or -1 */
2668 deviation += (devB / 2);
2669 }
2670
2671 state->sys_clock_freq =
2672 (u16) ((state->expected_sys_clock_freq) +
2673 deviation);
2674 }
2675 status = InitHI(state);
2676 if (status < 0)
2677 break;
2678 status = InitAtomicRead(state);
2679 if (status < 0)
2680 break;
2681
2682 status = EnableAndResetMB(state);
2683 if (status < 0)
2684 break;
2685 if (state->type_A)
2686 status = ResetCEFR(state);
2687 if (status < 0)
2688 break;
2689
2690 if (fw) {
2691 status = DownloadMicrocode(state, fw, fw_size);
2692 if (status < 0)
2693 break;
2694 } else {
2695 status = DownloadMicrocode(state, state->microcode, state->microcode_length);
2696 if (status < 0)
2697 break;
2698 }
2699
2700 if (state->PGA) {
2701 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO;
2702 SetCfgPga(state, 0); /* PGA = 0 dB */
2703 } else {
2704 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
2705 }
2706
2707 state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
2708
2709 status = InitFE(state);
2710 if (status < 0)
2711 break;
2712 status = InitFT(state);
2713 if (status < 0)
2714 break;
2715 status = InitCP(state);
2716 if (status < 0)
2717 break;
2718 status = InitCE(state);
2719 if (status < 0)
2720 break;
2721 status = InitEQ(state);
2722 if (status < 0)
2723 break;
2724 status = InitEC(state);
2725 if (status < 0)
2726 break;
2727 status = InitSC(state);
2728 if (status < 0)
2729 break;
2730
2731 status = SetCfgIfAgc(state, &state->if_agc_cfg);
2732 if (status < 0)
2733 break;
2734 status = SetCfgRfAgc(state, &state->rf_agc_cfg);
2735 if (status < 0)
2736 break;
2737
2738 state->cscd_state = CSCD_INIT;
2739 status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
2740 if (status < 0)
2741 break;
2742 status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
2743 if (status < 0)
2744 break;
2745
2746 driverVersion = (((VERSION_MAJOR / 10) << 4) +
2747 (VERSION_MAJOR % 10)) << 24;
2748 driverVersion += (((VERSION_MINOR / 10) << 4) +
2749 (VERSION_MINOR % 10)) << 16;
2750 driverVersion += ((VERSION_PATCH / 1000) << 12) +
2751 ((VERSION_PATCH / 100) << 8) +
2752 ((VERSION_PATCH / 10) << 4) + (VERSION_PATCH % 10);
2753
2754 status = Write32(state, SC_RA_RAM_DRIVER_VERSION__AX, driverVersion, 0);
2755 if (status < 0)
2756 break;
2757
2758 status = StopOC(state);
2759 if (status < 0)
2760 break;
2761
2762 state->drxd_state = DRXD_STOPPED;
2763 state->init_done = 1;
2764 status = 0;
2765 } while (0);
2766 return status;
2767}
2768
2769int DRXD_status(struct drxd_state *state, u32 * pLockStatus)
2770{
2771 DRX_GetLockStatus(state, pLockStatus);
2772
2773 /*if (*pLockStatus&DRX_LOCK_MPEG) */
2774 if (*pLockStatus & DRX_LOCK_FEC) {
2775 ConfigureMPEGOutput(state, 1);
2776 /* Get status again, in case we have MPEG lock now */
2777 /*DRX_GetLockStatus(state, pLockStatus); */
2778 }
2779
2780 return 0;
2781}
2782
2783/****************************************************************************/
2784/****************************************************************************/
2785/****************************************************************************/
2786
2787static int drxd_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2788{
2789 struct drxd_state *state = fe->demodulator_priv;
2790 u32 value;
2791 int res;
2792
2793 res = ReadIFAgc(state, &value);
2794 if (res < 0)
2795 *strength = 0;
2796 else
2797 *strength = 0xffff - (value << 4);
2798 return 0;
2799}
2800
2801static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
2802{
2803 struct drxd_state *state = fe->demodulator_priv;
2804 u32 lock;
2805
2806 DRXD_status(state, &lock);
2807 *status = 0;
2808 /* No MPEG lock in V255 firmware, bug ? */
2809#if 1
2810 if (lock & DRX_LOCK_MPEG)
2811 *status |= FE_HAS_LOCK;
2812#else
2813 if (lock & DRX_LOCK_FEC)
2814 *status |= FE_HAS_LOCK;
2815#endif
2816 if (lock & DRX_LOCK_FEC)
2817 *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
2818 if (lock & DRX_LOCK_DEMOD)
2819 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
2820
2821 return 0;
2822}
2823
2824static int drxd_init(struct dvb_frontend *fe)
2825{
2826 struct drxd_state *state = fe->demodulator_priv;
2827 int err = 0;
2828
2829/* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
2830 return DRXD_init(state, 0, 0);
2831
2832 err = DRXD_init(state, state->fw->data, state->fw->size);
2833 release_firmware(state->fw);
2834 return err;
2835}
2836
2837int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
2838{
2839 struct drxd_state *state = fe->demodulator_priv;
2840
2841 if (state->config.disable_i2c_gate_ctrl == 1)
2842 return 0;
2843
2844 return DRX_ConfigureI2CBridge(state, onoff);
2845}
2846EXPORT_SYMBOL(drxd_config_i2c);
2847
2848static int drxd_get_tune_settings(struct dvb_frontend *fe,
2849 struct dvb_frontend_tune_settings *sets)
2850{
2851 sets->min_delay_ms = 10000;
2852 sets->max_drift = 0;
2853 sets->step_size = 0;
2854 return 0;
2855}
2856
2857static int drxd_read_ber(struct dvb_frontend *fe, u32 * ber)
2858{
2859 *ber = 0;
2860 return 0;
2861}
2862
2863static int drxd_read_snr(struct dvb_frontend *fe, u16 * snr)
2864{
2865 *snr = 0;
2866 return 0;
2867}
2868
2869static int drxd_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
2870{
2871 *ucblocks = 0;
2872 return 0;
2873}
2874
2875static int drxd_sleep(struct dvb_frontend *fe)
2876{
2877 struct drxd_state *state = fe->demodulator_priv;
2878
2879 ConfigureMPEGOutput(state, 0);
2880 return 0;
2881}
2882
2883static int drxd_get_frontend(struct dvb_frontend *fe,
2884 struct dvb_frontend_parameters *param)
2885{
2886 return 0;
2887}
2888
2889static int drxd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
2890{
2891 return drxd_config_i2c(fe, enable);
2892}
2893
2894static int drxd_set_frontend(struct dvb_frontend *fe,
2895 struct dvb_frontend_parameters *param)
2896{
2897 struct drxd_state *state = fe->demodulator_priv;
2898 s32 off = 0;
2899
2900 state->param = *param;
2901 DRX_Stop(state);
2902
2903 if (fe->ops.tuner_ops.set_params) {
2904 fe->ops.tuner_ops.set_params(fe, param);
2905 if (fe->ops.i2c_gate_ctrl)
2906 fe->ops.i2c_gate_ctrl(fe, 0);
2907 }
2908
2909 /* FIXME: move PLL drivers */
2910 if (state->config.pll_set &&
2911 state->config.pll_set(state->priv, param,
2912 state->config.pll_address,
2913 state->config.demoda_address, &off) < 0) {
2914 printk(KERN_ERR "Error in pll_set\n");
2915 return -1;
2916 }
2917
2918 msleep(200);
2919
2920 return DRX_Start(state, off);
2921}
2922
2923static void drxd_release(struct dvb_frontend *fe)
2924{
2925 struct drxd_state *state = fe->demodulator_priv;
2926
2927 kfree(state);
2928}
2929
2930static struct dvb_frontend_ops drxd_ops = {
2931
2932 .info = {
2933 .name = "Micronas DRXD DVB-T",
2934 .type = FE_OFDM,
2935 .frequency_min = 47125000,
2936 .frequency_max = 855250000,
2937 .frequency_stepsize = 166667,
2938 .frequency_tolerance = 0,
2939 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2940 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2941 FE_CAN_FEC_AUTO |
2942 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2943 FE_CAN_QAM_AUTO |
2944 FE_CAN_TRANSMISSION_MODE_AUTO |
2945 FE_CAN_GUARD_INTERVAL_AUTO |
2946 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
2947
2948 .release = drxd_release,
2949 .init = drxd_init,
2950 .sleep = drxd_sleep,
2951 .i2c_gate_ctrl = drxd_i2c_gate_ctrl,
2952
2953 .set_frontend = drxd_set_frontend,
2954 .get_frontend = drxd_get_frontend,
2955 .get_tune_settings = drxd_get_tune_settings,
2956
2957 .read_status = drxd_read_status,
2958 .read_ber = drxd_read_ber,
2959 .read_signal_strength = drxd_read_signal_strength,
2960 .read_snr = drxd_read_snr,
2961 .read_ucblocks = drxd_read_ucblocks,
2962};
2963
2964struct dvb_frontend *drxd_attach(const struct drxd_config *config,
2965 void *priv, struct i2c_adapter *i2c,
2966 struct device *dev)
2967{
2968 struct drxd_state *state = NULL;
2969
2970 state = kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
2971 if (!state)
2972 return NULL;
2973 memset(state, 0, sizeof(*state));
2974
2975 memcpy(&state->ops, &drxd_ops, sizeof(struct dvb_frontend_ops));
2976 state->dev = dev;
2977 state->config = *config;
2978 state->i2c = i2c;
2979 state->priv = priv;
2980
2981 mutex_init(&state->mutex);
2982
2983 if (Read16(state, 0, 0, 0) < 0)
2984 goto error;
2985
2986 memcpy(&state->frontend.ops, &drxd_ops,
2987 sizeof(struct dvb_frontend_ops));
2988 state->frontend.demodulator_priv = state;
2989 ConfigureMPEGOutput(state, 0);
2990 return &state->frontend;
2991
2992error:
2993 printk(KERN_ERR "drxd: not found\n");
2994 kfree(state);
2995 return NULL;
2996}
2997EXPORT_SYMBOL(drxd_attach);
2998
2999MODULE_DESCRIPTION("DRXD driver");
3000MODULE_AUTHOR("Micronas");
3001MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxd_map_firm.h b/drivers/media/dvb/frontends/drxd_map_firm.h
new file mode 100644
index 000000000000..6bc553abf215
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_map_firm.h
@@ -0,0 +1,1013 @@
1/*
2 * drx3973d_map_firm.h
3 *
4 * Copyright (C) 2006-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef __DRX3973D_MAP__H__
25#define __DRX3973D_MAP__H__
26
27/*
28 * Note: originally, this file contained 12000+ lines of data
29 * Probably a few lines for every firwmare assembler instruction. However,
30 * only a few defines were actually used. So, removed all uneeded lines.
31 * If ever needed, the other lines can be easily obtained via git history.
32 */
33
34#define HI_COMM_EXEC__A 0x400000
35#define HI_COMM_MB__A 0x400002
36#define HI_CT_REG_COMM_STATE__A 0x410001
37#define HI_RA_RAM_SRV_RES__A 0x420031
38#define HI_RA_RAM_SRV_CMD__A 0x420032
39#define HI_RA_RAM_SRV_CMD_RESET 0x2
40#define HI_RA_RAM_SRV_CMD_CONFIG 0x3
41#define HI_RA_RAM_SRV_CMD_EXECUTE 0x6
42#define HI_RA_RAM_SRV_RST_KEY__A 0x420033
43#define HI_RA_RAM_SRV_RST_KEY_ACT 0x3973
44#define HI_RA_RAM_SRV_CFG_KEY__A 0x420033
45#define HI_RA_RAM_SRV_CFG_DIV__A 0x420034
46#define HI_RA_RAM_SRV_CFG_BDL__A 0x420035
47#define HI_RA_RAM_SRV_CFG_WUP__A 0x420036
48#define HI_RA_RAM_SRV_CFG_ACT__A 0x420037
49#define HI_RA_RAM_SRV_CFG_ACT_SLV0_ON 0x1
50#define HI_RA_RAM_SRV_CFG_ACT_BRD__M 0x4
51#define HI_RA_RAM_SRV_CFG_ACT_BRD_OFF 0x0
52#define HI_RA_RAM_SRV_CFG_ACT_BRD_ON 0x4
53#define HI_RA_RAM_SRV_CFG_ACT_PWD_EXE 0x8
54#define HI_RA_RAM_USR_BEGIN__A 0x420040
55#define HI_IF_RAM_TRP_BPT0__AX 0x430000
56#define HI_IF_RAM_USR_BEGIN__A 0x430200
57#define SC_COMM_EXEC__A 0x800000
58#define SC_COMM_EXEC_CTL_STOP 0x0
59#define SC_COMM_STATE__A 0x800001
60#define SC_RA_RAM_PARAM0__A 0x820040
61#define SC_RA_RAM_PARAM1__A 0x820041
62#define SC_RA_RAM_CMD_ADDR__A 0x820042
63#define SC_RA_RAM_CMD__A 0x820043
64#define SC_RA_RAM_CMD_PROC_START 0x1
65#define SC_RA_RAM_CMD_SET_PREF_PARAM 0x3
66#define SC_RA_RAM_CMD_GET_OP_PARAM 0x5
67#define SC_RA_RAM_SW_EVENT_RUN_NMASK__M 0x1
68#define SC_RA_RAM_LOCKTRACK_MIN 0x1
69#define SC_RA_RAM_OP_PARAM_MODE_2K 0x0
70#define SC_RA_RAM_OP_PARAM_MODE_8K 0x1
71#define SC_RA_RAM_OP_PARAM_GUARD_32 0x0
72#define SC_RA_RAM_OP_PARAM_GUARD_16 0x4
73#define SC_RA_RAM_OP_PARAM_GUARD_8 0x8
74#define SC_RA_RAM_OP_PARAM_GUARD_4 0xC
75#define SC_RA_RAM_OP_PARAM_CONST_QPSK 0x0
76#define SC_RA_RAM_OP_PARAM_CONST_QAM16 0x10
77#define SC_RA_RAM_OP_PARAM_CONST_QAM64 0x20
78#define SC_RA_RAM_OP_PARAM_HIER_NO 0x0
79#define SC_RA_RAM_OP_PARAM_HIER_A1 0x40
80#define SC_RA_RAM_OP_PARAM_HIER_A2 0x80
81#define SC_RA_RAM_OP_PARAM_HIER_A4 0xC0
82#define SC_RA_RAM_OP_PARAM_RATE_1_2 0x0
83#define SC_RA_RAM_OP_PARAM_RATE_2_3 0x200
84#define SC_RA_RAM_OP_PARAM_RATE_3_4 0x400
85#define SC_RA_RAM_OP_PARAM_RATE_5_6 0x600
86#define SC_RA_RAM_OP_PARAM_RATE_7_8 0x800
87#define SC_RA_RAM_OP_PARAM_PRIO_HI 0x0
88#define SC_RA_RAM_OP_PARAM_PRIO_LO 0x1000
89#define SC_RA_RAM_OP_AUTO_MODE__M 0x1
90#define SC_RA_RAM_OP_AUTO_GUARD__M 0x2
91#define SC_RA_RAM_OP_AUTO_CONST__M 0x4
92#define SC_RA_RAM_OP_AUTO_HIER__M 0x8
93#define SC_RA_RAM_OP_AUTO_RATE__M 0x10
94#define SC_RA_RAM_LOCK__A 0x82004B
95#define SC_RA_RAM_LOCK_DEMOD__M 0x1
96#define SC_RA_RAM_LOCK_FEC__M 0x2
97#define SC_RA_RAM_LOCK_MPEG__M 0x4
98#define SC_RA_RAM_BE_OPT_ENA__A 0x82004C
99#define SC_RA_RAM_BE_OPT_ENA_CP_OPT 0x1
100#define SC_RA_RAM_BE_OPT_DELAY__A 0x82004D
101#define SC_RA_RAM_CONFIG__A 0x820050
102#define SC_RA_RAM_CONFIG_FR_ENABLE__M 0x4
103#define SC_RA_RAM_CONFIG_FREQSCAN__M 0x10
104#define SC_RA_RAM_CONFIG_SLAVE__M 0x20
105#define SC_RA_RAM_IF_SAVE__AX 0x82008E
106#define SC_RA_RAM_IR_COARSE_2K_LENGTH__A 0x8200D1
107#define SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE 0x9
108#define SC_RA_RAM_IR_COARSE_2K_FREQINC__A 0x8200D2
109#define SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE 0x4
110#define SC_RA_RAM_IR_COARSE_2K_KAISINC__A 0x8200D3
111#define SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE 0x100
112#define SC_RA_RAM_IR_COARSE_8K_LENGTH__A 0x8200D4
113#define SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE 0x8
114#define SC_RA_RAM_IR_COARSE_8K_FREQINC__A 0x8200D5
115#define SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE 0x8
116#define SC_RA_RAM_IR_COARSE_8K_KAISINC__A 0x8200D6
117#define SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE 0x200
118#define SC_RA_RAM_IR_FINE_2K_LENGTH__A 0x8200D7
119#define SC_RA_RAM_IR_FINE_2K_LENGTH__PRE 0x9
120#define SC_RA_RAM_IR_FINE_2K_FREQINC__A 0x8200D8
121#define SC_RA_RAM_IR_FINE_2K_FREQINC__PRE 0x4
122#define SC_RA_RAM_IR_FINE_2K_KAISINC__A 0x8200D9
123#define SC_RA_RAM_IR_FINE_2K_KAISINC__PRE 0x100
124#define SC_RA_RAM_IR_FINE_8K_LENGTH__A 0x8200DA
125#define SC_RA_RAM_IR_FINE_8K_LENGTH__PRE 0xB
126#define SC_RA_RAM_IR_FINE_8K_FREQINC__A 0x8200DB
127#define SC_RA_RAM_IR_FINE_8K_FREQINC__PRE 0x1
128#define SC_RA_RAM_IR_FINE_8K_KAISINC__A 0x8200DC
129#define SC_RA_RAM_IR_FINE_8K_KAISINC__PRE 0x40
130#define SC_RA_RAM_ECHO_SHIFT_LIM__A 0x8200DD
131#define SC_RA_RAM_SAMPLE_RATE_COUNT__A 0x8200E8
132#define SC_RA_RAM_SAMPLE_RATE_STEP__A 0x8200E9
133#define SC_RA_RAM_BAND__A 0x8200EC
134#define SC_RA_RAM_LC_ABS_2K__A 0x8200F4
135#define SC_RA_RAM_LC_ABS_2K__PRE 0x1F
136#define SC_RA_RAM_LC_ABS_8K__A 0x8200F5
137#define SC_RA_RAM_LC_ABS_8K__PRE 0x1F
138#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE 0x1D6
139#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE 0x4
140#define SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE 0x1BB
141#define SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE 0x5
142#define SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE 0x1EF
143#define SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE 0x5
144#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE 0x15E
145#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE 0x5
146#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE 0x11A
147#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE 0x6
148#define SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE 0x1FB
149#define SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE 0x5
150#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE 0x12F
151#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE 0x5
152#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE 0x197
153#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE 0x5
154#define SC_RA_RAM_DRIVER_VERSION__AX 0x8201FE
155#define SC_RA_RAM_PROC_LOCKTRACK 0x0
156#define FE_COMM_EXEC__A 0xC00000
157#define FE_AD_REG_COMM_EXEC__A 0xC10000
158#define FE_AD_REG_FDB_IN__A 0xC10012
159#define FE_AD_REG_PD__A 0xC10013
160#define FE_AD_REG_INVEXT__A 0xC10014
161#define FE_AD_REG_CLKNEG__A 0xC10015
162#define FE_AG_REG_COMM_EXEC__A 0xC20000
163#define FE_AG_REG_AG_MODE_LOP__A 0xC20010
164#define FE_AG_REG_AG_MODE_LOP_MODE_4__M 0x10
165#define FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC 0x0
166#define FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC 0x10
167#define FE_AG_REG_AG_MODE_LOP_MODE_5__M 0x20
168#define FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC 0x0
169#define FE_AG_REG_AG_MODE_LOP_MODE_C__M 0x1000
170#define FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC 0x0
171#define FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC 0x1000
172#define FE_AG_REG_AG_MODE_LOP_MODE_E__M 0x4000
173#define FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC 0x0
174#define FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC 0x4000
175#define FE_AG_REG_AG_MODE_HIP__A 0xC20011
176#define FE_AG_REG_AG_PGA_MODE__A 0xC20012
177#define FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN 0x0
178#define FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN 0x1
179#define FE_AG_REG_AG_AGC_SIO__A 0xC20013
180#define FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M 0x2
181#define FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT 0x0
182#define FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT 0x2
183#define FE_AG_REG_AG_PWD__A 0xC20015
184#define FE_AG_REG_AG_PWD_PWD_PD2__M 0x2
185#define FE_AG_REG_AG_PWD_PWD_PD2_DISABLE 0x0
186#define FE_AG_REG_AG_PWD_PWD_PD2_ENABLE 0x2
187#define FE_AG_REG_DCE_AUR_CNT__A 0xC20016
188#define FE_AG_REG_DCE_RUR_CNT__A 0xC20017
189#define FE_AG_REG_ACE_AUR_CNT__A 0xC2001A
190#define FE_AG_REG_ACE_RUR_CNT__A 0xC2001B
191#define FE_AG_REG_CDR_RUR_CNT__A 0xC20020
192#define FE_AG_REG_EGC_RUR_CNT__A 0xC20024
193#define FE_AG_REG_EGC_SET_LVL__A 0xC20025
194#define FE_AG_REG_EGC_SET_LVL__M 0x1FF
195#define FE_AG_REG_EGC_FLA_RGN__A 0xC20026
196#define FE_AG_REG_EGC_SLO_RGN__A 0xC20027
197#define FE_AG_REG_EGC_JMP_PSN__A 0xC20028
198#define FE_AG_REG_EGC_FLA_INC__A 0xC20029
199#define FE_AG_REG_EGC_FLA_DEC__A 0xC2002A
200#define FE_AG_REG_EGC_SLO_INC__A 0xC2002B
201#define FE_AG_REG_EGC_SLO_DEC__A 0xC2002C
202#define FE_AG_REG_EGC_FAS_INC__A 0xC2002D
203#define FE_AG_REG_EGC_FAS_DEC__A 0xC2002E
204#define FE_AG_REG_PM1_AGC_WRI__A 0xC20030
205#define FE_AG_REG_PM1_AGC_WRI__M 0x7FF
206#define FE_AG_REG_GC1_AGC_RIC__A 0xC20031
207#define FE_AG_REG_GC1_AGC_OFF__A 0xC20032
208#define FE_AG_REG_GC1_AGC_MAX__A 0xC20033
209#define FE_AG_REG_GC1_AGC_MIN__A 0xC20034
210#define FE_AG_REG_GC1_AGC_DAT__A 0xC20035
211#define FE_AG_REG_GC1_AGC_DAT__M 0x3FF
212#define FE_AG_REG_PM2_AGC_WRI__A 0xC20036
213#define FE_AG_REG_IND_WIN__A 0xC2003C
214#define FE_AG_REG_IND_THD_LOL__A 0xC2003D
215#define FE_AG_REG_IND_THD_HIL__A 0xC2003E
216#define FE_AG_REG_IND_DEL__A 0xC2003F
217#define FE_AG_REG_IND_PD1_WRI__A 0xC20040
218#define FE_AG_REG_PDA_AUR_CNT__A 0xC20041
219#define FE_AG_REG_PDA_RUR_CNT__A 0xC20042
220#define FE_AG_REG_PDA_AVE_DAT__A 0xC20043
221#define FE_AG_REG_PDC_RUR_CNT__A 0xC20044
222#define FE_AG_REG_PDC_SET_LVL__A 0xC20045
223#define FE_AG_REG_PDC_FLA_RGN__A 0xC20046
224#define FE_AG_REG_PDC_JMP_PSN__A 0xC20047
225#define FE_AG_REG_PDC_FLA_STP__A 0xC20048
226#define FE_AG_REG_PDC_SLO_STP__A 0xC20049
227#define FE_AG_REG_PDC_PD2_WRI__A 0xC2004A
228#define FE_AG_REG_PDC_MAP_DAT__A 0xC2004B
229#define FE_AG_REG_PDC_MAX__A 0xC2004C
230#define FE_AG_REG_TGA_AUR_CNT__A 0xC2004D
231#define FE_AG_REG_TGA_RUR_CNT__A 0xC2004E
232#define FE_AG_REG_TGA_AVE_DAT__A 0xC2004F
233#define FE_AG_REG_TGC_RUR_CNT__A 0xC20050
234#define FE_AG_REG_TGC_SET_LVL__A 0xC20051
235#define FE_AG_REG_TGC_SET_LVL__M 0x3F
236#define FE_AG_REG_TGC_FLA_RGN__A 0xC20052
237#define FE_AG_REG_TGC_JMP_PSN__A 0xC20053
238#define FE_AG_REG_TGC_FLA_STP__A 0xC20054
239#define FE_AG_REG_TGC_SLO_STP__A 0xC20055
240#define FE_AG_REG_TGC_MAP_DAT__A 0xC20056
241#define FE_AG_REG_FGA_AUR_CNT__A 0xC20057
242#define FE_AG_REG_FGA_RUR_CNT__A 0xC20058
243#define FE_AG_REG_FGM_WRI__A 0xC20061
244#define FE_AG_REG_BGC_FGC_WRI__A 0xC20068
245#define FE_AG_REG_BGC_CGC_WRI__A 0xC20069
246#define FE_FS_REG_COMM_EXEC__A 0xC30000
247#define FE_FS_REG_ADD_INC_LOP__A 0xC30010
248#define FE_FD_REG_COMM_EXEC__A 0xC40000
249#define FE_FD_REG_SCL__A 0xC40010
250#define FE_FD_REG_MAX_LEV__A 0xC40011
251#define FE_FD_REG_NR__A 0xC40012
252#define FE_FD_REG_MEAS_VAL__A 0xC40014
253#define FE_IF_REG_COMM_EXEC__A 0xC50000
254#define FE_IF_REG_INCR0__A 0xC50010
255#define FE_IF_REG_INCR0__W 16
256#define FE_IF_REG_INCR0__M 0xFFFF
257#define FE_IF_REG_INCR1__A 0xC50011
258#define FE_IF_REG_INCR1__M 0xFF
259#define FE_CF_REG_COMM_EXEC__A 0xC60000
260#define FE_CF_REG_SCL__A 0xC60010
261#define FE_CF_REG_MAX_LEV__A 0xC60011
262#define FE_CF_REG_NR__A 0xC60012
263#define FE_CF_REG_IMP_VAL__A 0xC60013
264#define FE_CF_REG_MEAS_VAL__A 0xC60014
265#define FE_CU_REG_COMM_EXEC__A 0xC70000
266#define FE_CU_REG_FRM_CNT_RST__A 0xC70011
267#define FE_CU_REG_FRM_CNT_STR__A 0xC70012
268#define FT_COMM_EXEC__A 0x1000000
269#define FT_REG_COMM_EXEC__A 0x1010000
270#define CP_COMM_EXEC__A 0x1400000
271#define CP_REG_COMM_EXEC__A 0x1410000
272#define CP_REG_INTERVAL__A 0x1410011
273#define CP_REG_BR_SPL_OFFSET__A 0x1410023
274#define CP_REG_BR_STR_DEL__A 0x1410024
275#define CP_REG_RT_ANG_INC0__A 0x1410030
276#define CP_REG_RT_ANG_INC1__A 0x1410031
277#define CP_REG_RT_DETECT_ENA__A 0x1410032
278#define CP_REG_RT_DETECT_TRH__A 0x1410033
279#define CP_REG_RT_EXP_MARG__A 0x141003E
280#define CP_REG_AC_NEXP_OFFS__A 0x1410040
281#define CP_REG_AC_AVER_POW__A 0x1410041
282#define CP_REG_AC_MAX_POW__A 0x1410042
283#define CP_REG_AC_WEIGHT_MAN__A 0x1410043
284#define CP_REG_AC_WEIGHT_EXP__A 0x1410044
285#define CP_REG_AC_AMP_MODE__A 0x1410047
286#define CP_REG_AC_AMP_FIX__A 0x1410048
287#define CP_REG_AC_ANG_MODE__A 0x141004A
288#define CE_COMM_EXEC__A 0x1800000
289#define CE_REG_COMM_EXEC__A 0x1810000
290#define CE_REG_TAPSET__A 0x1810011
291#define CE_REG_AVG_POW__A 0x1810012
292#define CE_REG_MAX_POW__A 0x1810013
293#define CE_REG_ATT__A 0x1810014
294#define CE_REG_NRED__A 0x1810015
295#define CE_REG_NE_ERR_SELECT__A 0x1810043
296#define CE_REG_NE_TD_CAL__A 0x1810044
297#define CE_REG_NE_MIXAVG__A 0x1810046
298#define CE_REG_NE_NUPD_OFS__A 0x1810047
299#define CE_REG_PE_NEXP_OFFS__A 0x1810050
300#define CE_REG_PE_TIMESHIFT__A 0x1810051
301#define CE_REG_TP_A0_TAP_NEW__A 0x1810064
302#define CE_REG_TP_A0_TAP_NEW_VALID__A 0x1810065
303#define CE_REG_TP_A0_MU_LMS_STEP__A 0x1810066
304#define CE_REG_TP_A1_TAP_NEW__A 0x1810068
305#define CE_REG_TP_A1_TAP_NEW_VALID__A 0x1810069
306#define CE_REG_TP_A1_MU_LMS_STEP__A 0x181006A
307#define CE_REG_TI_NEXP_OFFS__A 0x1810070
308#define CE_REG_FI_SHT_INCR__A 0x1810090
309#define CE_REG_FI_EXP_NORM__A 0x1810091
310#define CE_REG_IR_INPUTSEL__A 0x18100A0
311#define CE_REG_IR_STARTPOS__A 0x18100A1
312#define CE_REG_IR_NEXP_THRES__A 0x18100A2
313#define CE_REG_FR_TREAL00__A 0x1820010
314#define CE_REG_FR_TIMAG00__A 0x1820011
315#define CE_REG_FR_TREAL01__A 0x1820012
316#define CE_REG_FR_TIMAG01__A 0x1820013
317#define CE_REG_FR_TREAL02__A 0x1820014
318#define CE_REG_FR_TIMAG02__A 0x1820015
319#define CE_REG_FR_TREAL03__A 0x1820016
320#define CE_REG_FR_TIMAG03__A 0x1820017
321#define CE_REG_FR_TREAL04__A 0x1820018
322#define CE_REG_FR_TIMAG04__A 0x1820019
323#define CE_REG_FR_TREAL05__A 0x182001A
324#define CE_REG_FR_TIMAG05__A 0x182001B
325#define CE_REG_FR_TREAL06__A 0x182001C
326#define CE_REG_FR_TIMAG06__A 0x182001D
327#define CE_REG_FR_TREAL07__A 0x182001E
328#define CE_REG_FR_TIMAG07__A 0x182001F
329#define CE_REG_FR_TREAL08__A 0x1820020
330#define CE_REG_FR_TIMAG08__A 0x1820021
331#define CE_REG_FR_TREAL09__A 0x1820022
332#define CE_REG_FR_TIMAG09__A 0x1820023
333#define CE_REG_FR_TREAL10__A 0x1820024
334#define CE_REG_FR_TIMAG10__A 0x1820025
335#define CE_REG_FR_TREAL11__A 0x1820026
336#define CE_REG_FR_TIMAG11__A 0x1820027
337#define CE_REG_FR_MID_TAP__A 0x1820028
338#define CE_REG_FR_SQS_G00__A 0x1820029
339#define CE_REG_FR_SQS_G01__A 0x182002A
340#define CE_REG_FR_SQS_G02__A 0x182002B
341#define CE_REG_FR_SQS_G03__A 0x182002C
342#define CE_REG_FR_SQS_G04__A 0x182002D
343#define CE_REG_FR_SQS_G05__A 0x182002E
344#define CE_REG_FR_SQS_G06__A 0x182002F
345#define CE_REG_FR_SQS_G07__A 0x1820030
346#define CE_REG_FR_SQS_G08__A 0x1820031
347#define CE_REG_FR_SQS_G09__A 0x1820032
348#define CE_REG_FR_SQS_G10__A 0x1820033
349#define CE_REG_FR_SQS_G11__A 0x1820034
350#define CE_REG_FR_SQS_G12__A 0x1820035
351#define CE_REG_FR_RIO_G00__A 0x1820036
352#define CE_REG_FR_RIO_G01__A 0x1820037
353#define CE_REG_FR_RIO_G02__A 0x1820038
354#define CE_REG_FR_RIO_G03__A 0x1820039
355#define CE_REG_FR_RIO_G04__A 0x182003A
356#define CE_REG_FR_RIO_G05__A 0x182003B
357#define CE_REG_FR_RIO_G06__A 0x182003C
358#define CE_REG_FR_RIO_G07__A 0x182003D
359#define CE_REG_FR_RIO_G08__A 0x182003E
360#define CE_REG_FR_RIO_G09__A 0x182003F
361#define CE_REG_FR_RIO_G10__A 0x1820040
362#define CE_REG_FR_MODE__A 0x1820041
363#define CE_REG_FR_SQS_TRH__A 0x1820042
364#define CE_REG_FR_RIO_GAIN__A 0x1820043
365#define CE_REG_FR_BYPASS__A 0x1820044
366#define CE_REG_FR_PM_SET__A 0x1820045
367#define CE_REG_FR_ERR_SH__A 0x1820046
368#define CE_REG_FR_MAN_SH__A 0x1820047
369#define CE_REG_FR_TAP_SH__A 0x1820048
370#define EQ_COMM_EXEC__A 0x1C00000
371#define EQ_REG_COMM_EXEC__A 0x1C10000
372#define EQ_REG_COMM_MB__A 0x1C10002
373#define EQ_REG_IS_GAIN_MAN__A 0x1C10015
374#define EQ_REG_IS_GAIN_EXP__A 0x1C10016
375#define EQ_REG_IS_CLIP_EXP__A 0x1C10017
376#define EQ_REG_SN_CEGAIN__A 0x1C1002A
377#define EQ_REG_SN_OFFSET__A 0x1C1002B
378#define EQ_REG_RC_SEL_CAR__A 0x1C10032
379#define EQ_REG_RC_SEL_CAR_INIT 0x0
380#define EQ_REG_RC_SEL_CAR_DIV_ON 0x1
381#define EQ_REG_RC_SEL_CAR_PASS_A_CC 0x0
382#define EQ_REG_RC_SEL_CAR_PASS_B_CE 0x2
383#define EQ_REG_RC_SEL_CAR_LOCAL_A_CC 0x0
384#define EQ_REG_RC_SEL_CAR_LOCAL_B_CE 0x8
385#define EQ_REG_RC_SEL_CAR_MEAS_A_CC 0x0
386#define EQ_REG_RC_SEL_CAR_MEAS_B_CE 0x20
387#define EQ_REG_OT_CONST__A 0x1C10046
388#define EQ_REG_OT_ALPHA__A 0x1C10047
389#define EQ_REG_OT_QNT_THRES0__A 0x1C10048
390#define EQ_REG_OT_QNT_THRES1__A 0x1C10049
391#define EQ_REG_OT_CSI_STEP__A 0x1C1004A
392#define EQ_REG_OT_CSI_OFFSET__A 0x1C1004B
393#define EQ_REG_TD_REQ_SMB_CNT__A 0x1C10061
394#define EQ_REG_TD_TPS_PWR_OFS__A 0x1C10062
395#define EC_SB_REG_COMM_EXEC__A 0x2010000
396#define EC_SB_REG_TR_MODE__A 0x2010010
397#define EC_SB_REG_TR_MODE_8K 0x0
398#define EC_SB_REG_TR_MODE_2K 0x1
399#define EC_SB_REG_CONST__A 0x2010011
400#define EC_SB_REG_CONST_QPSK 0x0
401#define EC_SB_REG_CONST_16QAM 0x1
402#define EC_SB_REG_CONST_64QAM 0x2
403#define EC_SB_REG_ALPHA__A 0x2010012
404#define EC_SB_REG_PRIOR__A 0x2010013
405#define EC_SB_REG_PRIOR_HI 0x0
406#define EC_SB_REG_PRIOR_LO 0x1
407#define EC_SB_REG_CSI_HI__A 0x2010014
408#define EC_SB_REG_CSI_LO__A 0x2010015
409#define EC_SB_REG_SMB_TGL__A 0x2010016
410#define EC_SB_REG_SNR_HI__A 0x2010017
411#define EC_SB_REG_SNR_MID__A 0x2010018
412#define EC_SB_REG_SNR_LO__A 0x2010019
413#define EC_SB_REG_SCALE_MSB__A 0x201001A
414#define EC_SB_REG_SCALE_BIT2__A 0x201001B
415#define EC_SB_REG_SCALE_LSB__A 0x201001C
416#define EC_SB_REG_CSI_OFS__A 0x201001D
417#define EC_VD_REG_COMM_EXEC__A 0x2090000
418#define EC_VD_REG_FORCE__A 0x2090010
419#define EC_VD_REG_SET_CODERATE__A 0x2090011
420#define EC_VD_REG_SET_CODERATE_C1_2 0x0
421#define EC_VD_REG_SET_CODERATE_C2_3 0x1
422#define EC_VD_REG_SET_CODERATE_C3_4 0x2
423#define EC_VD_REG_SET_CODERATE_C5_6 0x3
424#define EC_VD_REG_SET_CODERATE_C7_8 0x4
425#define EC_VD_REG_REQ_SMB_CNT__A 0x2090012
426#define EC_VD_REG_RLK_ENA__A 0x2090014
427#define EC_OD_REG_COMM_EXEC__A 0x2110000
428#define EC_OD_REG_SYNC__A 0x2110010
429#define EC_OD_DEINT_RAM__A 0x2120000
430#define EC_RS_REG_COMM_EXEC__A 0x2130000
431#define EC_RS_REG_REQ_PCK_CNT__A 0x2130010
432#define EC_RS_REG_VAL__A 0x2130011
433#define EC_RS_REG_VAL_PCK 0x1
434#define EC_RS_EC_RAM__A 0x2140000
435#define EC_OC_REG_COMM_EXEC__A 0x2150000
436#define EC_OC_REG_COMM_EXEC_CTL_ACTIVE 0x1
437#define EC_OC_REG_COMM_EXEC_CTL_HOLD 0x2
438#define EC_OC_REG_COMM_INT_STA__A 0x2150007
439#define EC_OC_REG_OC_MODE_LOP__A 0x2150010
440#define EC_OC_REG_OC_MODE_LOP_PAR_ENA__M 0x1
441#define EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE 0x0
442#define EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE 0x1
443#define EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M 0x4
444#define EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC 0x0
445#define EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M 0x80
446#define EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL 0x80
447#define EC_OC_REG_OC_MODE_HIP__A 0x2150011
448#define EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR 0x10
449#define EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M 0x200
450#define EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE 0x0
451#define EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE 0x200
452#define EC_OC_REG_OC_MPG_SIO__A 0x2150012
453#define EC_OC_REG_OC_MPG_SIO__M 0xFFF
454#define EC_OC_REG_OC_MON_SIO__A 0x2150013
455#define EC_OC_REG_DTO_INC_LOP__A 0x2150014
456#define EC_OC_REG_DTO_INC_HIP__A 0x2150015
457#define EC_OC_REG_SNC_ISC_LVL__A 0x2150016
458#define EC_OC_REG_SNC_ISC_LVL_OSC__M 0xF0
459#define EC_OC_REG_TMD_TOP_MODE__A 0x215001D
460#define EC_OC_REG_TMD_TOP_CNT__A 0x215001E
461#define EC_OC_REG_TMD_HIL_MAR__A 0x215001F
462#define EC_OC_REG_TMD_LOL_MAR__A 0x2150020
463#define EC_OC_REG_TMD_CUR_CNT__A 0x2150021
464#define EC_OC_REG_AVR_ASH_CNT__A 0x2150023
465#define EC_OC_REG_AVR_BSH_CNT__A 0x2150024
466#define EC_OC_REG_RCN_MODE__A 0x2150027
467#define EC_OC_REG_RCN_CRA_LOP__A 0x2150028
468#define EC_OC_REG_RCN_CRA_HIP__A 0x2150029
469#define EC_OC_REG_RCN_CST_LOP__A 0x215002A
470#define EC_OC_REG_RCN_CST_HIP__A 0x215002B
471#define EC_OC_REG_RCN_SET_LVL__A 0x215002C
472#define EC_OC_REG_RCN_GAI_LVL__A 0x215002D
473#define EC_OC_REG_RCN_CLP_LOP__A 0x2150032
474#define EC_OC_REG_RCN_CLP_HIP__A 0x2150033
475#define EC_OC_REG_RCN_MAP_LOP__A 0x2150034
476#define EC_OC_REG_RCN_MAP_HIP__A 0x2150035
477#define EC_OC_REG_OCR_MPG_UOS__A 0x2150036
478#define EC_OC_REG_OCR_MPG_UOS__M 0xFFF
479#define EC_OC_REG_OCR_MPG_UOS_INIT 0x0
480#define EC_OC_REG_OCR_MPG_USR_DAT__A 0x2150038
481#define EC_OC_REG_OCR_MON_UOS__A 0x2150039
482#define EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE 0x1
483#define EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE 0x2
484#define EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE 0x4
485#define EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE 0x8
486#define EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE 0x10
487#define EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE 0x20
488#define EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE 0x40
489#define EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE 0x80
490#define EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE 0x100
491#define EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE 0x200
492#define EC_OC_REG_OCR_MON_UOS_VAL_ENABLE 0x400
493#define EC_OC_REG_OCR_MON_UOS_CLK_ENABLE 0x800
494#define EC_OC_REG_OCR_MON_WRI__A 0x215003A
495#define EC_OC_REG_OCR_MON_WRI_INIT 0x0
496#define EC_OC_REG_IPR_INV_MPG__A 0x2150045
497#define CC_REG_OSC_MODE__A 0x2410010
498#define CC_REG_OSC_MODE_M20 0x1
499#define CC_REG_PLL_MODE__A 0x2410011
500#define CC_REG_PLL_MODE_BYPASS_PLL 0x1
501#define CC_REG_PLL_MODE_PUMP_CUR_12 0x14
502#define CC_REG_REF_DIVIDE__A 0x2410012
503#define CC_REG_PWD_MODE__A 0x2410015
504#define CC_REG_PWD_MODE_DOWN_PLL 0x2
505#define CC_REG_UPDATE__A 0x2410017
506#define CC_REG_UPDATE_KEY 0x3973
507#define CC_REG_JTAGID_L__A 0x2410019
508#define LC_COMM_EXEC__A 0x2800000
509#define LC_RA_RAM_IFINCR_NOM_L__A 0x282000C
510#define LC_RA_RAM_FILTER_SYM_SET__A 0x282001A
511#define LC_RA_RAM_FILTER_SYM_SET__PRE 0x3E8
512#define LC_RA_RAM_FILTER_CRMM_A__A 0x2820060
513#define LC_RA_RAM_FILTER_CRMM_A__PRE 0x4
514#define LC_RA_RAM_FILTER_CRMM_B__A 0x2820061
515#define LC_RA_RAM_FILTER_CRMM_B__PRE 0x1
516#define LC_RA_RAM_FILTER_SRMM_A__A 0x2820068
517#define LC_RA_RAM_FILTER_SRMM_A__PRE 0x4
518#define LC_RA_RAM_FILTER_SRMM_B__A 0x2820069
519#define LC_RA_RAM_FILTER_SRMM_B__PRE 0x1
520#define B_HI_COMM_EXEC__A 0x400000
521#define B_HI_COMM_MB__A 0x400002
522#define B_HI_CT_REG_COMM_STATE__A 0x410001
523#define B_HI_RA_RAM_SRV_RES__A 0x420031
524#define B_HI_RA_RAM_SRV_CMD__A 0x420032
525#define B_HI_RA_RAM_SRV_CMD_RESET 0x2
526#define B_HI_RA_RAM_SRV_CMD_CONFIG 0x3
527#define B_HI_RA_RAM_SRV_CMD_EXECUTE 0x6
528#define B_HI_RA_RAM_SRV_RST_KEY__A 0x420033
529#define B_HI_RA_RAM_SRV_RST_KEY_ACT 0x3973
530#define B_HI_RA_RAM_SRV_CFG_KEY__A 0x420033
531#define B_HI_RA_RAM_SRV_CFG_DIV__A 0x420034
532#define B_HI_RA_RAM_SRV_CFG_BDL__A 0x420035
533#define B_HI_RA_RAM_SRV_CFG_WUP__A 0x420036
534#define B_HI_RA_RAM_SRV_CFG_ACT__A 0x420037
535#define B_HI_RA_RAM_SRV_CFG_ACT_SLV0_ON 0x1
536#define B_HI_RA_RAM_SRV_CFG_ACT_BRD__M 0x4
537#define B_HI_RA_RAM_SRV_CFG_ACT_BRD_OFF 0x0
538#define B_HI_RA_RAM_SRV_CFG_ACT_BRD_ON 0x4
539#define B_HI_RA_RAM_SRV_CFG_ACT_PWD_EXE 0x8
540#define B_HI_RA_RAM_USR_BEGIN__A 0x420040
541#define B_HI_IF_RAM_TRP_BPT0__AX 0x430000
542#define B_HI_IF_RAM_USR_BEGIN__A 0x430200
543#define B_SC_COMM_EXEC__A 0x800000
544#define B_SC_COMM_EXEC_CTL_STOP 0x0
545#define B_SC_COMM_STATE__A 0x800001
546#define B_SC_RA_RAM_PARAM0__A 0x820040
547#define B_SC_RA_RAM_PARAM1__A 0x820041
548#define B_SC_RA_RAM_CMD_ADDR__A 0x820042
549#define B_SC_RA_RAM_CMD__A 0x820043
550#define B_SC_RA_RAM_CMD_PROC_START 0x1
551#define B_SC_RA_RAM_CMD_SET_PREF_PARAM 0x3
552#define B_SC_RA_RAM_CMD_GET_OP_PARAM 0x5
553#define B_SC_RA_RAM_SW_EVENT_RUN_NMASK__M 0x1
554#define B_SC_RA_RAM_LOCKTRACK_MIN 0x1
555#define B_SC_RA_RAM_OP_PARAM_MODE_2K 0x0
556#define B_SC_RA_RAM_OP_PARAM_MODE_8K 0x1
557#define B_SC_RA_RAM_OP_PARAM_GUARD_32 0x0
558#define B_SC_RA_RAM_OP_PARAM_GUARD_16 0x4
559#define B_SC_RA_RAM_OP_PARAM_GUARD_8 0x8
560#define B_SC_RA_RAM_OP_PARAM_GUARD_4 0xC
561#define B_SC_RA_RAM_OP_PARAM_CONST_QPSK 0x0
562#define B_SC_RA_RAM_OP_PARAM_CONST_QAM16 0x10
563#define B_SC_RA_RAM_OP_PARAM_CONST_QAM64 0x20
564#define B_SC_RA_RAM_OP_PARAM_HIER_NO 0x0
565#define B_SC_RA_RAM_OP_PARAM_HIER_A1 0x40
566#define B_SC_RA_RAM_OP_PARAM_HIER_A2 0x80
567#define B_SC_RA_RAM_OP_PARAM_HIER_A4 0xC0
568#define B_SC_RA_RAM_OP_PARAM_RATE_1_2 0x0
569#define B_SC_RA_RAM_OP_PARAM_RATE_2_3 0x200
570#define B_SC_RA_RAM_OP_PARAM_RATE_3_4 0x400
571#define B_SC_RA_RAM_OP_PARAM_RATE_5_6 0x600
572#define B_SC_RA_RAM_OP_PARAM_RATE_7_8 0x800
573#define B_SC_RA_RAM_OP_PARAM_PRIO_HI 0x0
574#define B_SC_RA_RAM_OP_PARAM_PRIO_LO 0x1000
575#define B_SC_RA_RAM_OP_AUTO_MODE__M 0x1
576#define B_SC_RA_RAM_OP_AUTO_GUARD__M 0x2
577#define B_SC_RA_RAM_OP_AUTO_CONST__M 0x4
578#define B_SC_RA_RAM_OP_AUTO_HIER__M 0x8
579#define B_SC_RA_RAM_OP_AUTO_RATE__M 0x10
580#define B_SC_RA_RAM_LOCK__A 0x82004B
581#define B_SC_RA_RAM_LOCK_DEMOD__M 0x1
582#define B_SC_RA_RAM_LOCK_FEC__M 0x2
583#define B_SC_RA_RAM_LOCK_MPEG__M 0x4
584#define B_SC_RA_RAM_BE_OPT_ENA__A 0x82004C
585#define B_SC_RA_RAM_BE_OPT_ENA_CP_OPT 0x1
586#define B_SC_RA_RAM_BE_OPT_DELAY__A 0x82004D
587#define B_SC_RA_RAM_CONFIG__A 0x820050
588#define B_SC_RA_RAM_CONFIG_FR_ENABLE__M 0x4
589#define B_SC_RA_RAM_CONFIG_FREQSCAN__M 0x10
590#define B_SC_RA_RAM_CONFIG_SLAVE__M 0x20
591#define B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M 0x200
592#define B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M 0x400
593#define B_SC_RA_RAM_CO_TD_CAL_2K__A 0x82005D
594#define B_SC_RA_RAM_CO_TD_CAL_8K__A 0x82005E
595#define B_SC_RA_RAM_IF_SAVE__AX 0x82008E
596#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A 0x820098
597#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A 0x820099
598#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A 0x82009A
599#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A 0x82009B
600#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A 0x82009C
601#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A 0x82009D
602#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A 0x82009E
603#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A 0x82009F
604#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A 0x8200D1
605#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE 0x9
606#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A 0x8200D2
607#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE 0x4
608#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A 0x8200D3
609#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE 0x100
610#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A 0x8200D4
611#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE 0x8
612#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A 0x8200D5
613#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE 0x8
614#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A 0x8200D6
615#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE 0x200
616#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__A 0x8200D7
617#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE 0x9
618#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__A 0x8200D8
619#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE 0x4
620#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__A 0x8200D9
621#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE 0x100
622#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__A 0x8200DA
623#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE 0xB
624#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__A 0x8200DB
625#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE 0x1
626#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__A 0x8200DC
627#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE 0x40
628#define B_SC_RA_RAM_ECHO_SHIFT_LIM__A 0x8200DD
629#define B_SC_RA_RAM_SAMPLE_RATE_COUNT__A 0x8200E8
630#define B_SC_RA_RAM_SAMPLE_RATE_STEP__A 0x8200E9
631#define B_SC_RA_RAM_BAND__A 0x8200EC
632#define B_SC_RA_RAM_LC_ABS_2K__A 0x8200F4
633#define B_SC_RA_RAM_LC_ABS_2K__PRE 0x1F
634#define B_SC_RA_RAM_LC_ABS_8K__A 0x8200F5
635#define B_SC_RA_RAM_LC_ABS_8K__PRE 0x1F
636#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE 0x100
637#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE 0x4
638#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE 0x1E2
639#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE 0x4
640#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE 0x10D
641#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE 0x5
642#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE 0x17D
643#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE 0x4
644#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE 0x133
645#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE 0x5
646#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE 0x114
647#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE 0x5
648#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE 0x14A
649#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE 0x4
650#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE 0x1BB
651#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE 0x4
652#define B_SC_RA_RAM_DRIVER_VERSION__AX 0x8201FE
653#define B_SC_RA_RAM_PROC_LOCKTRACK 0x0
654#define B_FE_COMM_EXEC__A 0xC00000
655#define B_FE_AD_REG_COMM_EXEC__A 0xC10000
656#define B_FE_AD_REG_FDB_IN__A 0xC10012
657#define B_FE_AD_REG_PD__A 0xC10013
658#define B_FE_AD_REG_INVEXT__A 0xC10014
659#define B_FE_AD_REG_CLKNEG__A 0xC10015
660#define B_FE_AG_REG_COMM_EXEC__A 0xC20000
661#define B_FE_AG_REG_AG_MODE_LOP__A 0xC20010
662#define B_FE_AG_REG_AG_MODE_LOP_MODE_4__M 0x10
663#define B_FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC 0x0
664#define B_FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC 0x10
665#define B_FE_AG_REG_AG_MODE_LOP_MODE_5__M 0x20
666#define B_FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC 0x0
667#define B_FE_AG_REG_AG_MODE_LOP_MODE_C__M 0x1000
668#define B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC 0x0
669#define B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC 0x1000
670#define B_FE_AG_REG_AG_MODE_LOP_MODE_E__M 0x4000
671#define B_FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC 0x0
672#define B_FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC 0x4000
673#define B_FE_AG_REG_AG_MODE_HIP__A 0xC20011
674#define B_FE_AG_REG_AG_MODE_HIP_MODE_J__M 0x8
675#define B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC 0x0
676#define B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC 0x8
677#define B_FE_AG_REG_AG_PGA_MODE__A 0xC20012
678#define B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN 0x0
679#define B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN 0x1
680#define B_FE_AG_REG_AG_AGC_SIO__A 0xC20013
681#define B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M 0x2
682#define B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT 0x0
683#define B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT 0x2
684#define B_FE_AG_REG_AG_PWD__A 0xC20015
685#define B_FE_AG_REG_AG_PWD_PWD_PD2__M 0x2
686#define B_FE_AG_REG_AG_PWD_PWD_PD2_DISABLE 0x0
687#define B_FE_AG_REG_AG_PWD_PWD_PD2_ENABLE 0x2
688#define B_FE_AG_REG_DCE_AUR_CNT__A 0xC20016
689#define B_FE_AG_REG_DCE_RUR_CNT__A 0xC20017
690#define B_FE_AG_REG_ACE_AUR_CNT__A 0xC2001A
691#define B_FE_AG_REG_ACE_RUR_CNT__A 0xC2001B
692#define B_FE_AG_REG_CDR_RUR_CNT__A 0xC20020
693#define B_FE_AG_REG_EGC_RUR_CNT__A 0xC20024
694#define B_FE_AG_REG_EGC_SET_LVL__A 0xC20025
695#define B_FE_AG_REG_EGC_SET_LVL__M 0x1FF
696#define B_FE_AG_REG_EGC_FLA_RGN__A 0xC20026
697#define B_FE_AG_REG_EGC_SLO_RGN__A 0xC20027
698#define B_FE_AG_REG_EGC_JMP_PSN__A 0xC20028
699#define B_FE_AG_REG_EGC_FLA_INC__A 0xC20029
700#define B_FE_AG_REG_EGC_FLA_DEC__A 0xC2002A
701#define B_FE_AG_REG_EGC_SLO_INC__A 0xC2002B
702#define B_FE_AG_REG_EGC_SLO_DEC__A 0xC2002C
703#define B_FE_AG_REG_EGC_FAS_INC__A 0xC2002D
704#define B_FE_AG_REG_EGC_FAS_DEC__A 0xC2002E
705#define B_FE_AG_REG_PM1_AGC_WRI__A 0xC20030
706#define B_FE_AG_REG_PM1_AGC_WRI__M 0x7FF
707#define B_FE_AG_REG_GC1_AGC_RIC__A 0xC20031
708#define B_FE_AG_REG_GC1_AGC_OFF__A 0xC20032
709#define B_FE_AG_REG_GC1_AGC_MAX__A 0xC20033
710#define B_FE_AG_REG_GC1_AGC_MIN__A 0xC20034
711#define B_FE_AG_REG_GC1_AGC_DAT__A 0xC20035
712#define B_FE_AG_REG_GC1_AGC_DAT__M 0x3FF
713#define B_FE_AG_REG_PM2_AGC_WRI__A 0xC20036
714#define B_FE_AG_REG_IND_WIN__A 0xC2003C
715#define B_FE_AG_REG_IND_THD_LOL__A 0xC2003D
716#define B_FE_AG_REG_IND_THD_HIL__A 0xC2003E
717#define B_FE_AG_REG_IND_DEL__A 0xC2003F
718#define B_FE_AG_REG_IND_PD1_WRI__A 0xC20040
719#define B_FE_AG_REG_PDA_AUR_CNT__A 0xC20041
720#define B_FE_AG_REG_PDA_RUR_CNT__A 0xC20042
721#define B_FE_AG_REG_PDA_AVE_DAT__A 0xC20043
722#define B_FE_AG_REG_PDC_RUR_CNT__A 0xC20044
723#define B_FE_AG_REG_PDC_SET_LVL__A 0xC20045
724#define B_FE_AG_REG_PDC_FLA_RGN__A 0xC20046
725#define B_FE_AG_REG_PDC_JMP_PSN__A 0xC20047
726#define B_FE_AG_REG_PDC_FLA_STP__A 0xC20048
727#define B_FE_AG_REG_PDC_SLO_STP__A 0xC20049
728#define B_FE_AG_REG_PDC_PD2_WRI__A 0xC2004A
729#define B_FE_AG_REG_PDC_MAP_DAT__A 0xC2004B
730#define B_FE_AG_REG_PDC_MAX__A 0xC2004C
731#define B_FE_AG_REG_TGA_AUR_CNT__A 0xC2004D
732#define B_FE_AG_REG_TGA_RUR_CNT__A 0xC2004E
733#define B_FE_AG_REG_TGA_AVE_DAT__A 0xC2004F
734#define B_FE_AG_REG_TGC_RUR_CNT__A 0xC20050
735#define B_FE_AG_REG_TGC_SET_LVL__A 0xC20051
736#define B_FE_AG_REG_TGC_SET_LVL__M 0x3F
737#define B_FE_AG_REG_TGC_FLA_RGN__A 0xC20052
738#define B_FE_AG_REG_TGC_JMP_PSN__A 0xC20053
739#define B_FE_AG_REG_TGC_FLA_STP__A 0xC20054
740#define B_FE_AG_REG_TGC_SLO_STP__A 0xC20055
741#define B_FE_AG_REG_TGC_MAP_DAT__A 0xC20056
742#define B_FE_AG_REG_FGM_WRI__A 0xC20061
743#define B_FE_AG_REG_BGC_FGC_WRI__A 0xC20068
744#define B_FE_AG_REG_BGC_CGC_WRI__A 0xC20069
745#define B_FE_FS_REG_COMM_EXEC__A 0xC30000
746#define B_FE_FS_REG_ADD_INC_LOP__A 0xC30010
747#define B_FE_FD_REG_COMM_EXEC__A 0xC40000
748#define B_FE_FD_REG_SCL__A 0xC40010
749#define B_FE_FD_REG_MAX_LEV__A 0xC40011
750#define B_FE_FD_REG_NR__A 0xC40012
751#define B_FE_FD_REG_MEAS_VAL__A 0xC40014
752#define B_FE_IF_REG_COMM_EXEC__A 0xC50000
753#define B_FE_IF_REG_INCR0__A 0xC50010
754#define B_FE_IF_REG_INCR0__W 16
755#define B_FE_IF_REG_INCR0__M 0xFFFF
756#define B_FE_IF_REG_INCR1__A 0xC50011
757#define B_FE_IF_REG_INCR1__M 0xFF
758#define B_FE_CF_REG_COMM_EXEC__A 0xC60000
759#define B_FE_CF_REG_SCL__A 0xC60010
760#define B_FE_CF_REG_MAX_LEV__A 0xC60011
761#define B_FE_CF_REG_NR__A 0xC60012
762#define B_FE_CF_REG_IMP_VAL__A 0xC60013
763#define B_FE_CF_REG_MEAS_VAL__A 0xC60014
764#define B_FE_CU_REG_COMM_EXEC__A 0xC70000
765#define B_FE_CU_REG_FRM_CNT_RST__A 0xC70011
766#define B_FE_CU_REG_FRM_CNT_STR__A 0xC70012
767#define B_FE_CU_REG_CTR_NFC_ICR__A 0xC70020
768#define B_FE_CU_REG_CTR_NFC_OCR__A 0xC70021
769#define B_FE_CU_REG_DIV_NFC_CLP__A 0xC70027
770#define B_FT_COMM_EXEC__A 0x1000000
771#define B_FT_REG_COMM_EXEC__A 0x1010000
772#define B_CP_COMM_EXEC__A 0x1400000
773#define B_CP_REG_COMM_EXEC__A 0x1410000
774#define B_CP_REG_INTERVAL__A 0x1410011
775#define B_CP_REG_BR_SPL_OFFSET__A 0x1410023
776#define B_CP_REG_BR_STR_DEL__A 0x1410024
777#define B_CP_REG_RT_ANG_INC0__A 0x1410030
778#define B_CP_REG_RT_ANG_INC1__A 0x1410031
779#define B_CP_REG_RT_DETECT_TRH__A 0x1410033
780#define B_CP_REG_AC_NEXP_OFFS__A 0x1410040
781#define B_CP_REG_AC_AVER_POW__A 0x1410041
782#define B_CP_REG_AC_MAX_POW__A 0x1410042
783#define B_CP_REG_AC_WEIGHT_MAN__A 0x1410043
784#define B_CP_REG_AC_WEIGHT_EXP__A 0x1410044
785#define B_CP_REG_AC_AMP_MODE__A 0x1410047
786#define B_CP_REG_AC_AMP_FIX__A 0x1410048
787#define B_CP_REG_AC_ANG_MODE__A 0x141004A
788#define B_CE_COMM_EXEC__A 0x1800000
789#define B_CE_REG_COMM_EXEC__A 0x1810000
790#define B_CE_REG_TAPSET__A 0x1810011
791#define B_CE_REG_AVG_POW__A 0x1810012
792#define B_CE_REG_MAX_POW__A 0x1810013
793#define B_CE_REG_ATT__A 0x1810014
794#define B_CE_REG_NRED__A 0x1810015
795#define B_CE_REG_NE_ERR_SELECT__A 0x1810043
796#define B_CE_REG_NE_TD_CAL__A 0x1810044
797#define B_CE_REG_NE_MIXAVG__A 0x1810046
798#define B_CE_REG_NE_NUPD_OFS__A 0x1810047
799#define B_CE_REG_PE_NEXP_OFFS__A 0x1810050
800#define B_CE_REG_PE_TIMESHIFT__A 0x1810051
801#define B_CE_REG_TP_A0_TAP_NEW__A 0x1810064
802#define B_CE_REG_TP_A0_TAP_NEW_VALID__A 0x1810065
803#define B_CE_REG_TP_A0_MU_LMS_STEP__A 0x1810066
804#define B_CE_REG_TP_A1_TAP_NEW__A 0x1810068
805#define B_CE_REG_TP_A1_TAP_NEW_VALID__A 0x1810069
806#define B_CE_REG_TP_A1_MU_LMS_STEP__A 0x181006A
807#define B_CE_REG_TI_PHN_ENABLE__A 0x1810073
808#define B_CE_REG_FI_SHT_INCR__A 0x1810090
809#define B_CE_REG_FI_EXP_NORM__A 0x1810091
810#define B_CE_REG_IR_INPUTSEL__A 0x18100A0
811#define B_CE_REG_IR_STARTPOS__A 0x18100A1
812#define B_CE_REG_IR_NEXP_THRES__A 0x18100A2
813#define B_CE_REG_FR_TREAL00__A 0x1820010
814#define B_CE_REG_FR_TIMAG00__A 0x1820011
815#define B_CE_REG_FR_TREAL01__A 0x1820012
816#define B_CE_REG_FR_TIMAG01__A 0x1820013
817#define B_CE_REG_FR_TREAL02__A 0x1820014
818#define B_CE_REG_FR_TIMAG02__A 0x1820015
819#define B_CE_REG_FR_TREAL03__A 0x1820016
820#define B_CE_REG_FR_TIMAG03__A 0x1820017
821#define B_CE_REG_FR_TREAL04__A 0x1820018
822#define B_CE_REG_FR_TIMAG04__A 0x1820019
823#define B_CE_REG_FR_TREAL05__A 0x182001A
824#define B_CE_REG_FR_TIMAG05__A 0x182001B
825#define B_CE_REG_FR_TREAL06__A 0x182001C
826#define B_CE_REG_FR_TIMAG06__A 0x182001D
827#define B_CE_REG_FR_TREAL07__A 0x182001E
828#define B_CE_REG_FR_TIMAG07__A 0x182001F
829#define B_CE_REG_FR_TREAL08__A 0x1820020
830#define B_CE_REG_FR_TIMAG08__A 0x1820021
831#define B_CE_REG_FR_TREAL09__A 0x1820022
832#define B_CE_REG_FR_TIMAG09__A 0x1820023
833#define B_CE_REG_FR_TREAL10__A 0x1820024
834#define B_CE_REG_FR_TIMAG10__A 0x1820025
835#define B_CE_REG_FR_TREAL11__A 0x1820026
836#define B_CE_REG_FR_TIMAG11__A 0x1820027
837#define B_CE_REG_FR_MID_TAP__A 0x1820028
838#define B_CE_REG_FR_SQS_G00__A 0x1820029
839#define B_CE_REG_FR_SQS_G01__A 0x182002A
840#define B_CE_REG_FR_SQS_G02__A 0x182002B
841#define B_CE_REG_FR_SQS_G03__A 0x182002C
842#define B_CE_REG_FR_SQS_G04__A 0x182002D
843#define B_CE_REG_FR_SQS_G05__A 0x182002E
844#define B_CE_REG_FR_SQS_G06__A 0x182002F
845#define B_CE_REG_FR_SQS_G07__A 0x1820030
846#define B_CE_REG_FR_SQS_G08__A 0x1820031
847#define B_CE_REG_FR_SQS_G09__A 0x1820032
848#define B_CE_REG_FR_SQS_G10__A 0x1820033
849#define B_CE_REG_FR_SQS_G11__A 0x1820034
850#define B_CE_REG_FR_SQS_G12__A 0x1820035
851#define B_CE_REG_FR_RIO_G00__A 0x1820036
852#define B_CE_REG_FR_RIO_G01__A 0x1820037
853#define B_CE_REG_FR_RIO_G02__A 0x1820038
854#define B_CE_REG_FR_RIO_G03__A 0x1820039
855#define B_CE_REG_FR_RIO_G04__A 0x182003A
856#define B_CE_REG_FR_RIO_G05__A 0x182003B
857#define B_CE_REG_FR_RIO_G06__A 0x182003C
858#define B_CE_REG_FR_RIO_G07__A 0x182003D
859#define B_CE_REG_FR_RIO_G08__A 0x182003E
860#define B_CE_REG_FR_RIO_G09__A 0x182003F
861#define B_CE_REG_FR_RIO_G10__A 0x1820040
862#define B_CE_REG_FR_MODE__A 0x1820041
863#define B_CE_REG_FR_SQS_TRH__A 0x1820042
864#define B_CE_REG_FR_RIO_GAIN__A 0x1820043
865#define B_CE_REG_FR_BYPASS__A 0x1820044
866#define B_CE_REG_FR_PM_SET__A 0x1820045
867#define B_CE_REG_FR_ERR_SH__A 0x1820046
868#define B_CE_REG_FR_MAN_SH__A 0x1820047
869#define B_CE_REG_FR_TAP_SH__A 0x1820048
870#define B_EQ_COMM_EXEC__A 0x1C00000
871#define B_EQ_REG_COMM_EXEC__A 0x1C10000
872#define B_EQ_REG_COMM_MB__A 0x1C10002
873#define B_EQ_REG_IS_GAIN_MAN__A 0x1C10015
874#define B_EQ_REG_IS_GAIN_EXP__A 0x1C10016
875#define B_EQ_REG_IS_CLIP_EXP__A 0x1C10017
876#define B_EQ_REG_SN_CEGAIN__A 0x1C1002A
877#define B_EQ_REG_SN_OFFSET__A 0x1C1002B
878#define B_EQ_REG_RC_SEL_CAR__A 0x1C10032
879#define B_EQ_REG_RC_SEL_CAR_INIT 0x2
880#define B_EQ_REG_RC_SEL_CAR_DIV_ON 0x1
881#define B_EQ_REG_RC_SEL_CAR_PASS_A_CC 0x0
882#define B_EQ_REG_RC_SEL_CAR_PASS_B_CE 0x2
883#define B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC 0x0
884#define B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE 0x8
885#define B_EQ_REG_RC_SEL_CAR_MEAS_A_CC 0x0
886#define B_EQ_REG_RC_SEL_CAR_MEAS_B_CE 0x20
887#define B_EQ_REG_RC_SEL_CAR_FFTMODE__M 0x80
888#define B_EQ_REG_OT_CONST__A 0x1C10046
889#define B_EQ_REG_OT_ALPHA__A 0x1C10047
890#define B_EQ_REG_OT_QNT_THRES0__A 0x1C10048
891#define B_EQ_REG_OT_QNT_THRES1__A 0x1C10049
892#define B_EQ_REG_OT_CSI_STEP__A 0x1C1004A
893#define B_EQ_REG_OT_CSI_OFFSET__A 0x1C1004B
894#define B_EQ_REG_TD_REQ_SMB_CNT__A 0x1C10061
895#define B_EQ_REG_TD_TPS_PWR_OFS__A 0x1C10062
896#define B_EC_SB_REG_COMM_EXEC__A 0x2010000
897#define B_EC_SB_REG_TR_MODE__A 0x2010010
898#define B_EC_SB_REG_TR_MODE_8K 0x0
899#define B_EC_SB_REG_TR_MODE_2K 0x1
900#define B_EC_SB_REG_CONST__A 0x2010011
901#define B_EC_SB_REG_CONST_QPSK 0x0
902#define B_EC_SB_REG_CONST_16QAM 0x1
903#define B_EC_SB_REG_CONST_64QAM 0x2
904#define B_EC_SB_REG_ALPHA__A 0x2010012
905#define B_EC_SB_REG_PRIOR__A 0x2010013
906#define B_EC_SB_REG_PRIOR_HI 0x0
907#define B_EC_SB_REG_PRIOR_LO 0x1
908#define B_EC_SB_REG_CSI_HI__A 0x2010014
909#define B_EC_SB_REG_CSI_LO__A 0x2010015
910#define B_EC_SB_REG_SMB_TGL__A 0x2010016
911#define B_EC_SB_REG_SNR_HI__A 0x2010017
912#define B_EC_SB_REG_SNR_MID__A 0x2010018
913#define B_EC_SB_REG_SNR_LO__A 0x2010019
914#define B_EC_SB_REG_SCALE_MSB__A 0x201001A
915#define B_EC_SB_REG_SCALE_BIT2__A 0x201001B
916#define B_EC_SB_REG_SCALE_LSB__A 0x201001C
917#define B_EC_SB_REG_CSI_OFS0__A 0x201001D
918#define B_EC_SB_REG_CSI_OFS1__A 0x201001E
919#define B_EC_SB_REG_CSI_OFS2__A 0x201001F
920#define B_EC_VD_REG_COMM_EXEC__A 0x2090000
921#define B_EC_VD_REG_FORCE__A 0x2090010
922#define B_EC_VD_REG_SET_CODERATE__A 0x2090011
923#define B_EC_VD_REG_SET_CODERATE_C1_2 0x0
924#define B_EC_VD_REG_SET_CODERATE_C2_3 0x1
925#define B_EC_VD_REG_SET_CODERATE_C3_4 0x2
926#define B_EC_VD_REG_SET_CODERATE_C5_6 0x3
927#define B_EC_VD_REG_SET_CODERATE_C7_8 0x4
928#define B_EC_VD_REG_REQ_SMB_CNT__A 0x2090012
929#define B_EC_VD_REG_RLK_ENA__A 0x2090014
930#define B_EC_OD_REG_COMM_EXEC__A 0x2110000
931#define B_EC_OD_REG_SYNC__A 0x2110664
932#define B_EC_OD_DEINT_RAM__A 0x2120000
933#define B_EC_RS_REG_COMM_EXEC__A 0x2130000
934#define B_EC_RS_REG_REQ_PCK_CNT__A 0x2130010
935#define B_EC_RS_REG_VAL__A 0x2130011
936#define B_EC_RS_REG_VAL_PCK 0x1
937#define B_EC_RS_EC_RAM__A 0x2140000
938#define B_EC_OC_REG_COMM_EXEC__A 0x2150000
939#define B_EC_OC_REG_COMM_EXEC_CTL_ACTIVE 0x1
940#define B_EC_OC_REG_COMM_EXEC_CTL_HOLD 0x2
941#define B_EC_OC_REG_COMM_INT_STA__A 0x2150007
942#define B_EC_OC_REG_OC_MODE_LOP__A 0x2150010
943#define B_EC_OC_REG_OC_MODE_LOP_PAR_ENA__M 0x1
944#define B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE 0x0
945#define B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE 0x1
946#define B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M 0x4
947#define B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC 0x0
948#define B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M 0x80
949#define B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL 0x80
950#define B_EC_OC_REG_OC_MODE_HIP__A 0x2150011
951#define B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR 0x10
952#define B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M 0x200
953#define B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE 0x0
954#define B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE 0x200
955#define B_EC_OC_REG_OC_MPG_SIO__A 0x2150012
956#define B_EC_OC_REG_OC_MPG_SIO__M 0xFFF
957#define B_EC_OC_REG_DTO_INC_LOP__A 0x2150014
958#define B_EC_OC_REG_DTO_INC_HIP__A 0x2150015
959#define B_EC_OC_REG_SNC_ISC_LVL__A 0x2150016
960#define B_EC_OC_REG_SNC_ISC_LVL_OSC__M 0xF0
961#define B_EC_OC_REG_TMD_TOP_MODE__A 0x215001D
962#define B_EC_OC_REG_TMD_TOP_CNT__A 0x215001E
963#define B_EC_OC_REG_TMD_HIL_MAR__A 0x215001F
964#define B_EC_OC_REG_TMD_LOL_MAR__A 0x2150020
965#define B_EC_OC_REG_TMD_CUR_CNT__A 0x2150021
966#define B_EC_OC_REG_AVR_ASH_CNT__A 0x2150023
967#define B_EC_OC_REG_AVR_BSH_CNT__A 0x2150024
968#define B_EC_OC_REG_RCN_MODE__A 0x2150027
969#define B_EC_OC_REG_RCN_CRA_LOP__A 0x2150028
970#define B_EC_OC_REG_RCN_CRA_HIP__A 0x2150029
971#define B_EC_OC_REG_RCN_CST_LOP__A 0x215002A
972#define B_EC_OC_REG_RCN_CST_HIP__A 0x215002B
973#define B_EC_OC_REG_RCN_SET_LVL__A 0x215002C
974#define B_EC_OC_REG_RCN_GAI_LVL__A 0x215002D
975#define B_EC_OC_REG_RCN_CLP_LOP__A 0x2150032
976#define B_EC_OC_REG_RCN_CLP_HIP__A 0x2150033
977#define B_EC_OC_REG_RCN_MAP_LOP__A 0x2150034
978#define B_EC_OC_REG_RCN_MAP_HIP__A 0x2150035
979#define B_EC_OC_REG_OCR_MPG_UOS__A 0x2150036
980#define B_EC_OC_REG_OCR_MPG_UOS__M 0xFFF
981#define B_EC_OC_REG_OCR_MPG_UOS_INIT 0x0
982#define B_EC_OC_REG_OCR_MPG_USR_DAT__A 0x2150038
983#define B_EC_OC_REG_IPR_INV_MPG__A 0x2150045
984#define B_EC_OC_REG_DTO_CLKMODE__A 0x2150047
985#define B_EC_OC_REG_DTO_PER__A 0x2150048
986#define B_EC_OC_REG_DTO_BUR__A 0x2150049
987#define B_EC_OC_REG_RCR_CLKMODE__A 0x215004A
988#define B_CC_REG_OSC_MODE__A 0x2410010
989#define B_CC_REG_OSC_MODE_M20 0x1
990#define B_CC_REG_PLL_MODE__A 0x2410011
991#define B_CC_REG_PLL_MODE_BYPASS_PLL 0x1
992#define B_CC_REG_PLL_MODE_PUMP_CUR_12 0x14
993#define B_CC_REG_REF_DIVIDE__A 0x2410012
994#define B_CC_REG_PWD_MODE__A 0x2410015
995#define B_CC_REG_PWD_MODE_DOWN_PLL 0x2
996#define B_CC_REG_UPDATE__A 0x2410017
997#define B_CC_REG_UPDATE_KEY 0x3973
998#define B_CC_REG_JTAGID_L__A 0x2410019
999#define B_CC_REG_DIVERSITY__A 0x241001B
1000#define B_LC_COMM_EXEC__A 0x2800000
1001#define B_LC_RA_RAM_IFINCR_NOM_L__A 0x282000C
1002#define B_LC_RA_RAM_FILTER_SYM_SET__A 0x282001A
1003#define B_LC_RA_RAM_FILTER_SYM_SET__PRE 0x3E8
1004#define B_LC_RA_RAM_FILTER_CRMM_A__A 0x2820060
1005#define B_LC_RA_RAM_FILTER_CRMM_A__PRE 0x4
1006#define B_LC_RA_RAM_FILTER_CRMM_B__A 0x2820061
1007#define B_LC_RA_RAM_FILTER_CRMM_B__PRE 0x1
1008#define B_LC_RA_RAM_FILTER_SRMM_A__A 0x2820068
1009#define B_LC_RA_RAM_FILTER_SRMM_A__PRE 0x4
1010#define B_LC_RA_RAM_FILTER_SRMM_B__A 0x2820069
1011#define B_LC_RA_RAM_FILTER_SRMM_B__PRE 0x1
1012
1013#endif
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h
index fa79b7c83dd2..c983f2f85802 100644
--- a/drivers/media/dvb/frontends/eds1547.h
+++ b/drivers/media/dvb/frontends/eds1547.h
@@ -61,7 +61,7 @@ static u8 stv0288_earda_inittab[] = {
61 0x3d, 0x30, 61 0x3d, 0x30,
62 0x40, 0x63, 62 0x40, 0x63,
63 0x41, 0x04, 63 0x41, 0x04,
64 0x42, 0x60, 64 0x42, 0x20,
65 0x43, 0x00, 65 0x43, 0x00,
66 0x44, 0x00, 66 0x44, 0x00,
67 0x45, 0x00, 67 0x45, 0x00,
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c
index 6c2e929bd79f..9a517a4bf96d 100644
--- a/drivers/media/dvb/frontends/ix2505v.c
+++ b/drivers/media/dvb/frontends/ix2505v.c
@@ -218,11 +218,13 @@ static int ix2505v_set_params(struct dvb_frontend *fe,
218 fe->ops.i2c_gate_ctrl(fe, 1); 218 fe->ops.i2c_gate_ctrl(fe, 1);
219 219
220 len = sizeof(data); 220 len = sizeof(data);
221
222 ret |= ix2505v_write(state, data, len); 221 ret |= ix2505v_write(state, data, len);
223 222
224 data[2] |= 0x4; /* set TM = 1 other bits same */ 223 data[2] |= 0x4; /* set TM = 1 other bits same */
225 224
225 if (fe->ops.i2c_gate_ctrl)
226 fe->ops.i2c_gate_ctrl(fe, 1);
227
226 len = 1; 228 len = 1;
227 ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */ 229 ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
228 230
@@ -233,12 +235,12 @@ static int ix2505v_set_params(struct dvb_frontend *fe,
233 235
234 deb_info("Data 2=[%x%x]\n", data[2], data[3]); 236 deb_info("Data 2=[%x%x]\n", data[2], data[3]);
235 237
238 if (fe->ops.i2c_gate_ctrl)
239 fe->ops.i2c_gate_ctrl(fe, 1);
240
236 len = 2; 241 len = 2;
237 ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */ 242 ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
238 243
239 if (fe->ops.i2c_gate_ctrl)
240 fe->ops.i2c_gate_ctrl(fe, 0);
241
242 if (state->config->min_delay_ms) 244 if (state->config->min_delay_ms)
243 msleep(state->config->min_delay_ms); 245 msleep(state->config->min_delay_ms);
244 246
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
index e3fe17fd96fb..8e0cfadba688 100644
--- a/drivers/media/dvb/frontends/stv0288.c
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -253,7 +253,7 @@ static u8 stv0288_inittab[] = {
253 0x3d, 0x30, 253 0x3d, 0x30,
254 0x40, 0x63, 254 0x40, 0x63,
255 0x41, 0x04, 255 0x41, 0x04,
256 0x42, 0x60, 256 0x42, 0x20,
257 0x43, 0x00, 257 0x43, 0x00,
258 0x44, 0x00, 258 0x44, 0x00,
259 0x45, 0x00, 259 0x45, 0x00,
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 4e3db3a42e06..42684bec8883 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -64,6 +64,7 @@ struct stv0299_state {
64 fe_code_rate_t fec_inner; 64 fe_code_rate_t fec_inner;
65 int errmode; 65 int errmode;
66 u32 ucblocks; 66 u32 ucblocks;
67 u8 mcr_reg;
67}; 68};
68 69
69#define STATUS_BER 0 70#define STATUS_BER 0
@@ -457,6 +458,9 @@ static int stv0299_init (struct dvb_frontend* fe)
457 458
458 dprintk("stv0299: init chip\n"); 459 dprintk("stv0299: init chip\n");
459 460
461 stv0299_writeregI(state, 0x02, 0x30 | state->mcr_reg);
462 msleep(50);
463
460 for (i = 0; ; i += 2) { 464 for (i = 0; ; i += 2) {
461 reg = state->config->inittab[i]; 465 reg = state->config->inittab[i];
462 val = state->config->inittab[i+1]; 466 val = state->config->inittab[i+1];
@@ -464,6 +468,8 @@ static int stv0299_init (struct dvb_frontend* fe)
464 break; 468 break;
465 if (reg == 0x0c && state->config->op0_off) 469 if (reg == 0x0c && state->config->op0_off)
466 val &= ~0x10; 470 val &= ~0x10;
471 if (reg == 0x2)
472 state->mcr_reg = val & 0xf;
467 stv0299_writeregI(state, reg, val); 473 stv0299_writeregI(state, reg, val);
468 } 474 }
469 475
@@ -618,7 +624,7 @@ static int stv0299_sleep(struct dvb_frontend* fe)
618{ 624{
619 struct stv0299_state* state = fe->demodulator_priv; 625 struct stv0299_state* state = fe->demodulator_priv;
620 626
621 stv0299_writeregI(state, 0x02, 0x80); 627 stv0299_writeregI(state, 0x02, 0xb0 | state->mcr_reg);
622 state->initialised = 0; 628 state->initialised = 0;
623 629
624 return 0; 630 return 0;
@@ -680,7 +686,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
680 state->errmode = STATUS_BER; 686 state->errmode = STATUS_BER;
681 687
682 /* check if the demod is there */ 688 /* check if the demod is there */
683 stv0299_writeregI(state, 0x02, 0x34); /* standby off */ 689 stv0299_writeregI(state, 0x02, 0x30); /* standby off */
684 msleep(200); 690 msleep(200);
685 id = stv0299_readreg(state, 0x00); 691 id = stv0299_readreg(state, 0x00);
686 692
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h
index 07f3fc0998f6..96d86d6eb473 100644
--- a/drivers/media/dvb/frontends/z0194a.h
+++ b/drivers/media/dvb/frontends/z0194a.h
@@ -42,7 +42,7 @@ static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe,
42 42
43static u8 sharp_z0194a_inittab[] = { 43static u8 sharp_z0194a_inittab[] = {
44 0x01, 0x15, 44 0x01, 0x15,
45 0x02, 0x00, 45 0x02, 0x30,
46 0x03, 0x00, 46 0x03, 0x00,
47 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ 47 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
48 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ 48 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 70e73afefb3d..1402062f2c89 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -44,7 +44,7 @@
44 44
45static unsigned int verbose; 45static unsigned int verbose;
46module_param(verbose, int, 0644); 46module_param(verbose, int, 0644);
47MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 47MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
48 48
49#define DRIVER_NAME "Hopper" 49#define DRIVER_NAME "Hopper"
50 50
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index 40da225098cc..05cbb9d95727 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -52,7 +52,7 @@
52 52
53static unsigned int verbose; 53static unsigned int verbose;
54module_param(verbose, int, 0644); 54module_param(verbose, int, 0644);
55MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 55MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
56 56
57static int devs; 57static int devs;
58 58
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c
index 10a432a79d00..371558af2d96 100644
--- a/drivers/media/dvb/mantis/mantis_pci.c
+++ b/drivers/media/dvb/mantis/mantis_pci.c
@@ -48,7 +48,7 @@
48 48
49int __devinit mantis_pci_init(struct mantis_pci *mantis) 49int __devinit mantis_pci_init(struct mantis_pci *mantis)
50{ 50{
51 u8 revision, latency; 51 u8 latency;
52 struct mantis_hwconfig *config = mantis->hwconfig; 52 struct mantis_hwconfig *config = mantis->hwconfig;
53 struct pci_dev *pdev = mantis->pdev; 53 struct pci_dev *pdev = mantis->pdev;
54 int err, ret = 0; 54 int err, ret = 0;
@@ -95,9 +95,8 @@ int __devinit mantis_pci_init(struct mantis_pci *mantis)
95 } 95 }
96 96
97 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); 97 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
98 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
99 mantis->latency = latency; 98 mantis->latency = latency;
100 mantis->revision = revision; 99 mantis->revision = pdev->revision;
101 100
102 dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", 101 dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ",
103 mantis->revision, 102 mantis->revision,
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c
index deec927c7f7a..2ae0afa7756b 100644
--- a/drivers/media/dvb/mantis/mantis_vp1033.c
+++ b/drivers/media/dvb/mantis/mantis_vp1033.c
@@ -37,7 +37,7 @@
37 37
38u8 lgtdqcs001f_inittab[] = { 38u8 lgtdqcs001f_inittab[] = {
39 0x01, 0x15, 39 0x01, 0x15,
40 0x02, 0x00, 40 0x02, 0x30,
41 0x03, 0x00, 41 0x03, 0x00,
42 0x04, 0x2a, 42 0x04, 0x2a,
43 0x05, 0x85, 43 0x05, 0x85,
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 0486919c1d0f..b81df5fafe26 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -1090,6 +1090,7 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1090 i2c_adap->algo = &pt1_i2c_algo; 1090 i2c_adap->algo = &pt1_i2c_algo;
1091 i2c_adap->algo_data = NULL; 1091 i2c_adap->algo_data = NULL;
1092 i2c_adap->dev.parent = &pdev->dev; 1092 i2c_adap->dev.parent = &pdev->dev;
1093 strcpy(i2c_adap->name, DRIVER_NAME);
1093 i2c_set_adapdata(i2c_adap, pt1); 1094 i2c_set_adapdata(i2c_adap, pt1);
1094 ret = i2c_add_adapter(i2c_adap); 1095 ret = i2c_add_adapter(i2c_adap);
1095 if (ret < 0) 1096 if (ret < 0)
@@ -1156,10 +1157,10 @@ err_pt1_disable_ram:
1156 pt1->power = 0; 1157 pt1->power = 0;
1157 pt1->reset = 1; 1158 pt1->reset = 1;
1158 pt1_update_power(pt1); 1159 pt1_update_power(pt1);
1159err_pt1_cleanup_adapters:
1160 pt1_cleanup_adapters(pt1);
1161err_i2c_del_adapter: 1160err_i2c_del_adapter:
1162 i2c_del_adapter(i2c_adap); 1161 i2c_del_adapter(i2c_adap);
1162err_pt1_cleanup_adapters:
1163 pt1_cleanup_adapters(pt1);
1163err_kfree: 1164err_kfree:
1164 pci_set_drvdata(pdev, NULL); 1165 pci_set_drvdata(pdev, NULL);
1165 kfree(pt1); 1166 kfree(pt1);
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 0b8da57cf4c3..0c8164a2cc36 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -297,9 +297,8 @@ static void smsusb_term_device(struct usb_interface *intf)
297 if (dev->coredev) 297 if (dev->coredev)
298 smscore_unregister_device(dev->coredev); 298 smscore_unregister_device(dev->coredev);
299 299
300 kfree(dev);
301
302 sms_info("device %p destroyed", dev); 300 sms_info("device %p destroyed", dev);
301 kfree(dev);
303 } 302 }
304 303
305 usb_set_intfdata(intf, NULL); 304 usb_set_intfdata(intf, NULL);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 44afab2fdc2d..9d83ced69dd6 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -95,6 +95,8 @@ config DVB_BUDGET_CI
95 select DVB_STB0899 if !DVB_FE_CUSTOMISE 95 select DVB_STB0899 if !DVB_FE_CUSTOMISE
96 select DVB_STB6100 if !DVB_FE_CUSTOMISE 96 select DVB_STB6100 if !DVB_FE_CUSTOMISE
97 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 97 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
98 select DVB_STV0288 if !DVB_FE_CUSTOMISE
99 select DVB_STB6000 if !DVB_FE_CUSTOMISE
98 select DVB_TDA10023 if !DVB_FE_CUSTOMISE 100 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
99 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE 101 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
100 depends on RC_CORE 102 depends on RC_CORE
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 1d79ada864d6..926f299b5225 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -52,6 +52,7 @@
52#include "bsru6.h" 52#include "bsru6.h"
53#include "tda1002x.h" 53#include "tda1002x.h"
54#include "tda827x.h" 54#include "tda827x.h"
55#include "bsbe1-d01a.h"
55 56
56#define MODULE_NAME "budget_ci" 57#define MODULE_NAME "budget_ci"
57 58
@@ -224,6 +225,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
224 case 0x1017: 225 case 0x1017:
225 case 0x1019: 226 case 0x1019:
226 case 0x101a: 227 case 0x101a:
228 case 0x101b:
227 /* for the Technotrend 1500 bundled remote */ 229 /* for the Technotrend 1500 bundled remote */
228 dev->map_name = RC_MAP_TT_1500; 230 dev->map_name = RC_MAP_TT_1500;
229 break; 231 break;
@@ -1388,6 +1390,23 @@ static void frontend_init(struct budget_ci *budget_ci)
1388 } 1390 }
1389 break; 1391 break;
1390 1392
1393 case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
1394 budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
1395 if (budget_ci->budget.dvb_frontend) {
1396 if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
1397 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1398 printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
1399 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1400 budget_ci->budget.dvb_frontend = NULL;
1401 }
1402 } else {
1403 printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
1404 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1405 budget_ci->budget.dvb_frontend = NULL;
1406 }
1407 }
1408 break;
1409
1391 case 0x1019: // TT S2-3200 PCI 1410 case 0x1019: // TT S2-3200 PCI
1392 /* 1411 /*
1393 * NOTE! on some STB0899 versions, the internal PLL takes a longer time 1412 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
@@ -1518,6 +1537,7 @@ MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1518MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); 1537MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1519MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); 1538MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1520MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); 1539MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1540MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
1521 1541
1522static struct pci_device_id pci_tbl[] = { 1542static struct pci_device_id pci_tbl[] = {
1523 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), 1543 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1528,6 +1548,7 @@ static struct pci_device_id pci_tbl[] = {
1528 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), 1548 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1529 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), 1549 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1530 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), 1550 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1551 MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
1531 { 1552 {
1532 .vendor = 0, 1553 .vendor = 0,
1533 } 1554 }
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index cbe2f0de1442..420bb42d5233 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -52,7 +52,7 @@
52 my TTUSB, so let it undef'd unless you want to implement another 52 my TTUSB, so let it undef'd unless you want to implement another
53 frontend. never tested. 53 frontend. never tested.
54 54
55 DEBUG: 55 debug:
56 define it to > 3 for really hardcore debugging. you probably don't want 56 define it to > 3 for really hardcore debugging. you probably don't want
57 this unless the device doesn't load at all. > 2 for bandwidth statistics. 57 this unless the device doesn't load at all. > 2 for bandwidth statistics.
58*/ 58*/
@@ -134,20 +134,19 @@ struct ttusb {
134/* ugly workaround ... don't know why it's necessary to read */ 134/* ugly workaround ... don't know why it's necessary to read */
135/* all result codes. */ 135/* all result codes. */
136 136
137#define DEBUG 0
138static int ttusb_cmd(struct ttusb *ttusb, 137static int ttusb_cmd(struct ttusb *ttusb,
139 const u8 * data, int len, int needresult) 138 const u8 * data, int len, int needresult)
140{ 139{
141 int actual_len; 140 int actual_len;
142 int err; 141 int err;
143#if DEBUG >= 3
144 int i; 142 int i;
145 143
146 printk(">"); 144 if (debug >= 3) {
147 for (i = 0; i < len; ++i) 145 printk(KERN_DEBUG ">");
148 printk(" %02x", data[i]); 146 for (i = 0; i < len; ++i)
149 printk("\n"); 147 printk(KERN_CONT " %02x", data[i]);
150#endif 148 printk(KERN_CONT "\n");
149 }
151 150
152 if (mutex_lock_interruptible(&ttusb->semusb) < 0) 151 if (mutex_lock_interruptible(&ttusb->semusb) < 0)
153 return -EAGAIN; 152 return -EAGAIN;
@@ -176,13 +175,15 @@ static int ttusb_cmd(struct ttusb *ttusb,
176 mutex_unlock(&ttusb->semusb); 175 mutex_unlock(&ttusb->semusb);
177 return err; 176 return err;
178 } 177 }
179#if DEBUG >= 3 178
180 actual_len = ttusb->last_result[3] + 4; 179 if (debug >= 3) {
181 printk("<"); 180 actual_len = ttusb->last_result[3] + 4;
182 for (i = 0; i < actual_len; ++i) 181 printk(KERN_DEBUG "<");
183 printk(" %02x", ttusb->last_result[i]); 182 for (i = 0; i < actual_len; ++i)
184 printk("\n"); 183 printk(KERN_CONT " %02x", ttusb->last_result[i]);
185#endif 184 printk(KERN_CONT "\n");
185 }
186
186 if (!needresult) 187 if (!needresult)
187 mutex_unlock(&ttusb->semusb); 188 mutex_unlock(&ttusb->semusb);
188 return 0; 189 return 0;
@@ -636,16 +637,13 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
636 ++ttusb->mux_state; 637 ++ttusb->mux_state;
637 else { 638 else {
638 ttusb->mux_state = 0; 639 ttusb->mux_state = 0;
639#if DEBUG > 3
640 if (ttusb->insync)
641 printk("%02x ", data[-1]);
642#else
643 if (ttusb->insync) { 640 if (ttusb->insync) {
644 printk("%s: lost sync.\n", 641 dprintk("%s: %02x\n",
642 __func__, data[-1]);
643 printk(KERN_INFO "%s: lost sync.\n",
645 __func__); 644 __func__);
646 ttusb->insync = 0; 645 ttusb->insync = 0;
647 } 646 }
648#endif
649 } 647 }
650 break; 648 break;
651 case 3: 649 case 3:
@@ -744,6 +742,9 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
744static void ttusb_iso_irq(struct urb *urb) 742static void ttusb_iso_irq(struct urb *urb)
745{ 743{
746 struct ttusb *ttusb = urb->context; 744 struct ttusb *ttusb = urb->context;
745 struct usb_iso_packet_descriptor *d;
746 u8 *data;
747 int len, i;
747 748
748 if (!ttusb->iso_streaming) 749 if (!ttusb->iso_streaming)
749 return; 750 return;
@@ -755,21 +756,14 @@ static void ttusb_iso_irq(struct urb *urb)
755#endif 756#endif
756 757
757 if (!urb->status) { 758 if (!urb->status) {
758 int i;
759 for (i = 0; i < urb->number_of_packets; ++i) { 759 for (i = 0; i < urb->number_of_packets; ++i) {
760 struct usb_iso_packet_descriptor *d;
761 u8 *data;
762 int len;
763 numpkt++; 760 numpkt++;
764 if (time_after_eq(jiffies, lastj + HZ)) { 761 if (time_after_eq(jiffies, lastj + HZ)) {
765#if DEBUG > 2 762 dprintk("frames/s: %lu (ts: %d, stuff %d, "
766 printk 763 "sec: %d, invalid: %d, all: %d)\n",
767 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n", 764 numpkt * HZ / (jiffies - lastj),
768 numpkt * HZ / (jiffies - lastj), 765 numts, numstuff, numsec, numinvalid,
769 numts, numstuff, numsec, numinvalid, 766 numts + numstuff + numsec + numinvalid);
770 numts + numstuff + numsec +
771 numinvalid);
772#endif
773 numts = numstuff = numsec = numinvalid = 0; 767 numts = numstuff = numsec = numinvalid = 0;
774 lastj = jiffies; 768 lastj = jiffies;
775 numpkt = 0; 769 numpkt = 0;
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 38ae6cd65790..0e740c98786c 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -174,15 +174,27 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
174 if (retval < 0) 174 if (retval < 0)
175 goto done; 175 goto done;
176 176
177 /* wait till tune operation has completed */ 177 /* currently I2C driver only uses interrupt way to tune */
178 timeout = jiffies + msecs_to_jiffies(tune_timeout); 178 if (radio->stci_enabled) {
179 do { 179 INIT_COMPLETION(radio->completion);
180 retval = si470x_get_register(radio, STATUSRSSI); 180
181 if (retval < 0) 181 /* wait till tune operation has completed */
182 goto stop; 182 retval = wait_for_completion_timeout(&radio->completion,
183 timed_out = time_after(jiffies, timeout); 183 msecs_to_jiffies(tune_timeout));
184 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && 184 if (!retval)
185 (!timed_out)); 185 timed_out = true;
186 } else {
187 /* wait till tune operation has completed */
188 timeout = jiffies + msecs_to_jiffies(tune_timeout);
189 do {
190 retval = si470x_get_register(radio, STATUSRSSI);
191 if (retval < 0)
192 goto stop;
193 timed_out = time_after(jiffies, timeout);
194 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
195 && (!timed_out));
196 }
197
186 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 198 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
187 dev_warn(&radio->videodev->dev, "tune does not complete\n"); 199 dev_warn(&radio->videodev->dev, "tune does not complete\n");
188 if (timed_out) 200 if (timed_out)
@@ -310,15 +322,27 @@ static int si470x_set_seek(struct si470x_device *radio,
310 if (retval < 0) 322 if (retval < 0)
311 goto done; 323 goto done;
312 324
313 /* wait till seek operation has completed */ 325 /* currently I2C driver only uses interrupt way to seek */
314 timeout = jiffies + msecs_to_jiffies(seek_timeout); 326 if (radio->stci_enabled) {
315 do { 327 INIT_COMPLETION(radio->completion);
316 retval = si470x_get_register(radio, STATUSRSSI); 328
317 if (retval < 0) 329 /* wait till seek operation has completed */
318 goto stop; 330 retval = wait_for_completion_timeout(&radio->completion,
319 timed_out = time_after(jiffies, timeout); 331 msecs_to_jiffies(seek_timeout));
320 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && 332 if (!retval)
321 (!timed_out)); 333 timed_out = true;
334 } else {
335 /* wait till seek operation has completed */
336 timeout = jiffies + msecs_to_jiffies(seek_timeout);
337 do {
338 retval = si470x_get_register(radio, STATUSRSSI);
339 if (retval < 0)
340 goto stop;
341 timed_out = time_after(jiffies, timeout);
342 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
343 && (!timed_out));
344 }
345
322 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 346 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
323 dev_warn(&radio->videodev->dev, "seek does not complete\n"); 347 dev_warn(&radio->videodev->dev, "seek does not complete\n");
324 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) 348 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 4ce541a5eb47..a2a67772c42c 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -197,8 +197,9 @@ int si470x_fops_open(struct file *file)
197 if (retval < 0) 197 if (retval < 0)
198 goto done; 198 goto done;
199 199
200 /* enable RDS interrupt */ 200 /* enable RDS / STC interrupt */
201 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; 201 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
202 radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
202 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; 203 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
203 radio->registers[SYSCONFIG1] |= 0x1 << 2; 204 radio->registers[SYSCONFIG1] |= 0x1 << 2;
204 retval = si470x_set_register(radio, SYSCONFIG1); 205 retval = si470x_set_register(radio, SYSCONFIG1);
@@ -261,12 +262,11 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
261 **************************************************************************/ 262 **************************************************************************/
262 263
263/* 264/*
264 * si470x_i2c_interrupt_work - rds processing function 265 * si470x_i2c_interrupt - interrupt handler
265 */ 266 */
266static void si470x_i2c_interrupt_work(struct work_struct *work) 267static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
267{ 268{
268 struct si470x_device *radio = container_of(work, 269 struct si470x_device *radio = dev_id;
269 struct si470x_device, radio_work);
270 unsigned char regnr; 270 unsigned char regnr;
271 unsigned char blocknum; 271 unsigned char blocknum;
272 unsigned short bler; /* rds block errors */ 272 unsigned short bler; /* rds block errors */
@@ -274,21 +274,29 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
274 unsigned char tmpbuf[3]; 274 unsigned char tmpbuf[3];
275 int retval = 0; 275 int retval = 0;
276 276
277 /* check Seek/Tune Complete */
278 retval = si470x_get_register(radio, STATUSRSSI);
279 if (retval < 0)
280 goto end;
281
282 if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
283 complete(&radio->completion);
284
277 /* safety checks */ 285 /* safety checks */
278 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 286 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
279 return; 287 goto end;
280 288
281 /* Update RDS registers */ 289 /* Update RDS registers */
282 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { 290 for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
283 retval = si470x_get_register(radio, STATUSRSSI + regnr); 291 retval = si470x_get_register(radio, STATUSRSSI + regnr);
284 if (retval < 0) 292 if (retval < 0)
285 return; 293 goto end;
286 } 294 }
287 295
288 /* get rds blocks */ 296 /* get rds blocks */
289 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) 297 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
290 /* No RDS group ready, better luck next time */ 298 /* No RDS group ready, better luck next time */
291 return; 299 goto end;
292 300
293 for (blocknum = 0; blocknum < 4; blocknum++) { 301 for (blocknum = 0; blocknum < 4; blocknum++) {
294 switch (blocknum) { 302 switch (blocknum) {
@@ -342,19 +350,8 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
342 350
343 if (radio->wr_index != radio->rd_index) 351 if (radio->wr_index != radio->rd_index)
344 wake_up_interruptible(&radio->read_queue); 352 wake_up_interruptible(&radio->read_queue);
345}
346
347
348/*
349 * si470x_i2c_interrupt - interrupt handler
350 */
351static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
352{
353 struct si470x_device *radio = dev_id;
354
355 if (!work_pending(&radio->radio_work))
356 schedule_work(&radio->radio_work);
357 353
354end:
358 return IRQ_HANDLED; 355 return IRQ_HANDLED;
359} 356}
360 357
@@ -376,7 +373,6 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
376 goto err_initial; 373 goto err_initial;
377 } 374 }
378 375
379 INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
380 radio->users = 0; 376 radio->users = 0;
381 radio->client = client; 377 radio->client = client;
382 mutex_init(&radio->lock); 378 mutex_init(&radio->lock);
@@ -441,7 +437,11 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
441 radio->rd_index = 0; 437 radio->rd_index = 0;
442 init_waitqueue_head(&radio->read_queue); 438 init_waitqueue_head(&radio->read_queue);
443 439
444 retval = request_irq(client->irq, si470x_i2c_interrupt, 440 /* mark Seek/Tune Complete Interrupt enabled */
441 radio->stci_enabled = true;
442 init_completion(&radio->completion);
443
444 retval = request_threaded_irq(client->irq, NULL, si470x_i2c_interrupt,
445 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); 445 IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
446 if (retval) { 446 if (retval) {
447 dev_err(&client->dev, "Failed to register interrupt\n"); 447 dev_err(&client->dev, "Failed to register interrupt\n");
@@ -479,7 +479,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
479 struct si470x_device *radio = i2c_get_clientdata(client); 479 struct si470x_device *radio = i2c_get_clientdata(client);
480 480
481 free_irq(client->irq, radio); 481 free_irq(client->irq, radio);
482 cancel_work_sync(&radio->radio_work);
483 video_unregister_device(radio->videodev); 482 video_unregister_device(radio->videodev);
484 kfree(radio); 483 kfree(radio);
485 484
@@ -491,8 +490,9 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
491/* 490/*
492 * si470x_i2c_suspend - suspend the device 491 * si470x_i2c_suspend - suspend the device
493 */ 492 */
494static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg) 493static int si470x_i2c_suspend(struct device *dev)
495{ 494{
495 struct i2c_client *client = to_i2c_client(dev);
496 struct si470x_device *radio = i2c_get_clientdata(client); 496 struct si470x_device *radio = i2c_get_clientdata(client);
497 497
498 /* power down */ 498 /* power down */
@@ -507,8 +507,9 @@ static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
507/* 507/*
508 * si470x_i2c_resume - resume the device 508 * si470x_i2c_resume - resume the device
509 */ 509 */
510static int si470x_i2c_resume(struct i2c_client *client) 510static int si470x_i2c_resume(struct device *dev)
511{ 511{
512 struct i2c_client *client = to_i2c_client(dev);
512 struct si470x_device *radio = i2c_get_clientdata(client); 513 struct si470x_device *radio = i2c_get_clientdata(client);
513 514
514 /* power up : need 110ms */ 515 /* power up : need 110ms */
@@ -519,9 +520,8 @@ static int si470x_i2c_resume(struct i2c_client *client)
519 520
520 return 0; 521 return 0;
521} 522}
522#else 523
523#define si470x_i2c_suspend NULL 524static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
524#define si470x_i2c_resume NULL
525#endif 525#endif
526 526
527 527
@@ -532,11 +532,12 @@ static struct i2c_driver si470x_i2c_driver = {
532 .driver = { 532 .driver = {
533 .name = "si470x", 533 .name = "si470x",
534 .owner = THIS_MODULE, 534 .owner = THIS_MODULE,
535#ifdef CONFIG_PM
536 .pm = &si470x_i2c_pm,
537#endif
535 }, 538 },
536 .probe = si470x_i2c_probe, 539 .probe = si470x_i2c_probe,
537 .remove = __devexit_p(si470x_i2c_remove), 540 .remove = __devexit_p(si470x_i2c_remove),
538 .suspend = si470x_i2c_suspend,
539 .resume = si470x_i2c_resume,
540 .id_table = si470x_i2c_id, 541 .id_table = si470x_i2c_id,
541}; 542};
542 543
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index 4a4e908db04c..68da001b09dc 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -158,6 +158,9 @@ struct si470x_device {
158 unsigned int rd_index; 158 unsigned int rd_index;
159 unsigned int wr_index; 159 unsigned int wr_index;
160 160
161 struct completion completion;
162 bool stci_enabled; /* Seek/Tune Complete Interrupt */
163
161#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) 164#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
162 /* reference to USB and video device */ 165 /* reference to USB and video device */
163 struct usb_device *usbdev; 166 struct usb_device *usbdev;
@@ -179,7 +182,6 @@ struct si470x_device {
179 182
180#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) 183#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
181 struct i2c_client *client; 184 struct i2c_client *client;
182 struct work_struct radio_work;
183#endif 185#endif
184}; 186};
185 187
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h
index 5db6fd14cf3c..1a45a5d847b0 100644
--- a/drivers/media/radio/wl128x/fmdrv.h
+++ b/drivers/media/radio/wl128x/fmdrv.h
@@ -55,8 +55,6 @@
55#define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */ 55#define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */
56#define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */ 56#define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */
57 57
58#define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0]))
59
60#define fmerr(format, ...) \ 58#define fmerr(format, ...) \
61 printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__) 59 printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
62#define fmwarn(format, ...) \ 60#define fmwarn(format, ...) \
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 7f03142a329f..154c337f00fd 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -161,6 +161,17 @@ config IR_NUVOTON
161 To compile this driver as a module, choose M here: the 161 To compile this driver as a module, choose M here: the
162 module will be called nuvoton-cir. 162 module will be called nuvoton-cir.
163 163
164config IR_REDRAT3
165 tristate "RedRat3 IR Transceiver"
166 depends on USB_ARCH_HAS_HCD
167 depends on RC_CORE
168 select USB
169 ---help---
170 Say Y here if you want to use a RedRat3 Infrared Transceiver.
171
172 To compile this driver as a module, choose M here: the
173 module will be called redrat3.
174
164config IR_STREAMZAP 175config IR_STREAMZAP
165 tristate "Streamzap PC Remote IR Receiver" 176 tristate "Streamzap PC Remote IR Receiver"
166 depends on USB_ARCH_HAS_HCD 177 depends on USB_ARCH_HAS_HCD
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index c6cfe70d862f..1f90a219a162 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
18obj-$(CONFIG_IR_MCEUSB) += mceusb.o 18obj-$(CONFIG_IR_MCEUSB) += mceusb.o
19obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o 19obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
20obj-$(CONFIG_IR_ENE) += ene_ir.o 20obj-$(CONFIG_IR_ENE) += ene_ir.o
21obj-$(CONFIG_IR_REDRAT3) += redrat3.o
21obj-$(CONFIG_IR_STREAMZAP) += streamzap.o 22obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
22obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o 23obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
23obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o 24obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 8fc0f081b470..3f3c70716268 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -443,16 +443,6 @@ static int display_close(struct inode *inode, struct file *file)
443 } else { 443 } else {
444 ictx->display_isopen = false; 444 ictx->display_isopen = false;
445 dev_dbg(ictx->dev, "display port closed\n"); 445 dev_dbg(ictx->dev, "display port closed\n");
446 if (!ictx->dev_present_intf0) {
447 /*
448 * Device disconnected before close and IR port is not
449 * open. If IR port is open, context will be deleted by
450 * ir_close.
451 */
452 mutex_unlock(&ictx->lock);
453 free_imon_context(ictx);
454 return retval;
455 }
456 } 446 }
457 447
458 mutex_unlock(&ictx->lock); 448 mutex_unlock(&ictx->lock);
@@ -1492,7 +1482,6 @@ static void imon_incoming_packet(struct imon_context *ictx,
1492 struct device *dev = ictx->dev; 1482 struct device *dev = ictx->dev;
1493 unsigned long flags; 1483 unsigned long flags;
1494 u32 kc; 1484 u32 kc;
1495 bool norelease = false;
1496 int i; 1485 int i;
1497 u64 scancode; 1486 u64 scancode;
1498 int press_type = 0; 1487 int press_type = 0;
@@ -1560,7 +1549,6 @@ static void imon_incoming_packet(struct imon_context *ictx,
1560 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) { 1549 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
1561 len = 8; 1550 len = 8;
1562 imon_pad_to_keys(ictx, buf); 1551 imon_pad_to_keys(ictx, buf);
1563 norelease = true;
1564 } 1552 }
1565 1553
1566 if (debug) { 1554 if (debug) {
@@ -1982,7 +1970,7 @@ static struct input_dev *imon_init_touch(struct imon_context *ictx)
1982 return touch; 1970 return touch;
1983 1971
1984touch_register_failed: 1972touch_register_failed:
1985 input_free_device(ictx->touch); 1973 input_free_device(touch);
1986 1974
1987touch_alloc_failed: 1975touch_alloc_failed:
1988 return NULL; 1976 return NULL;
@@ -2274,14 +2262,12 @@ static int __devinit imon_probe(struct usb_interface *interface,
2274 struct usb_host_interface *iface_desc = NULL; 2262 struct usb_host_interface *iface_desc = NULL;
2275 struct usb_interface *first_if; 2263 struct usb_interface *first_if;
2276 struct device *dev = &interface->dev; 2264 struct device *dev = &interface->dev;
2277 int ifnum, code_length, sysfs_err; 2265 int ifnum, sysfs_err;
2278 int ret = 0; 2266 int ret = 0;
2279 struct imon_context *ictx = NULL; 2267 struct imon_context *ictx = NULL;
2280 struct imon_context *first_if_ctx = NULL; 2268 struct imon_context *first_if_ctx = NULL;
2281 u16 vendor, product; 2269 u16 vendor, product;
2282 2270
2283 code_length = BUF_CHUNK_SIZE * 8;
2284
2285 usbdev = usb_get_dev(interface_to_usbdev(interface)); 2271 usbdev = usb_get_dev(interface_to_usbdev(interface));
2286 iface_desc = interface->cur_altsetting; 2272 iface_desc = interface->cur_altsetting;
2287 ifnum = iface_desc->desc.bInterfaceNumber; 2273 ifnum = iface_desc->desc.bInterfaceNumber;
@@ -2366,8 +2352,6 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
2366 dev = ictx->dev; 2352 dev = ictx->dev;
2367 ifnum = interface->cur_altsetting->desc.bInterfaceNumber; 2353 ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
2368 2354
2369 mutex_lock(&ictx->lock);
2370
2371 /* 2355 /*
2372 * sysfs_remove_group is safe to call even if sysfs_create_group 2356 * sysfs_remove_group is safe to call even if sysfs_create_group
2373 * hasn't been called 2357 * hasn't been called
@@ -2391,24 +2375,20 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
2391 if (ictx->display_supported) { 2375 if (ictx->display_supported) {
2392 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) 2376 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2393 usb_deregister_dev(interface, &imon_lcd_class); 2377 usb_deregister_dev(interface, &imon_lcd_class);
2394 else 2378 else if (ictx->display_type == IMON_DISPLAY_TYPE_VFD)
2395 usb_deregister_dev(interface, &imon_vfd_class); 2379 usb_deregister_dev(interface, &imon_vfd_class);
2396 } 2380 }
2397 } else { 2381 } else {
2398 ictx->dev_present_intf1 = false; 2382 ictx->dev_present_intf1 = false;
2399 usb_kill_urb(ictx->rx_urb_intf1); 2383 usb_kill_urb(ictx->rx_urb_intf1);
2400 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) 2384 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
2401 input_unregister_device(ictx->touch); 2385 input_unregister_device(ictx->touch);
2386 del_timer_sync(&ictx->ttimer);
2387 }
2402 } 2388 }
2403 2389
2404 if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) { 2390 if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1)
2405 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) 2391 free_imon_context(ictx);
2406 del_timer_sync(&ictx->ttimer);
2407 mutex_unlock(&ictx->lock);
2408 if (!ictx->display_isopen)
2409 free_imon_context(ictx);
2410 } else
2411 mutex_unlock(&ictx->lock);
2412 2392
2413 mutex_unlock(&driver_lock); 2393 mutex_unlock(&driver_lock);
2414 2394
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 43908a70bd8b..e716b931cf7e 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1250,11 +1250,9 @@ static void it8709_disable(struct ite_dev *dev)
1250 ite_dbg("%s called", __func__); 1250 ite_dbg("%s called", __func__);
1251 1251
1252 /* clear out all interrupt enable flags */ 1252 /* clear out all interrupt enable flags */
1253 it8709_wr(dev, 1253 it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
1254 it8709_rr(dev, 1254 ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
1255 IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE | 1255 IT85_C0IER);
1256 IT85_RDAIE |
1257 IT85_TLDLIE), IT85_C0IER);
1258 1256
1259 /* disable the receiver */ 1257 /* disable the receiver */
1260 it8709_disable_rx(dev); 1258 it8709_disable_rx(dev);
@@ -1270,11 +1268,9 @@ static void it8709_init_hardware(struct ite_dev *dev)
1270 ite_dbg("%s called", __func__); 1268 ite_dbg("%s called", __func__);
1271 1269
1272 /* disable all the interrupts */ 1270 /* disable all the interrupts */
1273 it8709_wr(dev, 1271 it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
1274 it8709_rr(dev, 1272 ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
1275 IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE | 1273 IT85_C0IER);
1276 IT85_RDAIE |
1277 IT85_TLDLIE), IT85_C0IER);
1278 1274
1279 /* program the baud rate divisor */ 1275 /* program the baud rate divisor */
1280 it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR); 1276 it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
@@ -1282,28 +1278,22 @@ static void it8709_init_hardware(struct ite_dev *dev)
1282 IT85_C0BDHR); 1278 IT85_C0BDHR);
1283 1279
1284 /* program the C0MSTCR register defaults */ 1280 /* program the C0MSTCR register defaults */
1285 it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) & ~(IT85_ILSEL | 1281 it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) &
1286 IT85_ILE 1282 ~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL
1287 | IT85_FIFOTL 1283 | IT85_FIFOCLR | IT85_RESET)) | IT85_FIFOTL_DEFAULT,
1288 | 1284 IT85_C0MSTCR);
1289 IT85_FIFOCLR
1290 |
1291 IT85_RESET))
1292 | IT85_FIFOTL_DEFAULT, IT85_C0MSTCR);
1293 1285
1294 /* program the C0RCR register defaults */ 1286 /* program the C0RCR register defaults */
1295 it8709_wr(dev, 1287 it8709_wr(dev, (it8709_rr(dev, IT85_C0RCR) &
1296 (it8709_rr(dev, IT85_C0RCR) & 1288 ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND | IT85_RXACT
1297 ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND 1289 | IT85_RXDCR)) | ITE_RXDCR_DEFAULT,
1298 | IT85_RXACT | IT85_RXDCR)) | 1290 IT85_C0RCR);
1299 ITE_RXDCR_DEFAULT, IT85_C0RCR);
1300 1291
1301 /* program the C0TCR register defaults */ 1292 /* program the C0TCR register defaults */
1302 it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR) 1293 it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR) & ~(IT85_TXMPM | IT85_TXMPW))
1303 &~(IT85_TXMPM | IT85_TXMPW)) 1294 | IT85_TXRLE | IT85_TXENDF | IT85_TXMPM_DEFAULT
1304 |IT85_TXRLE | IT85_TXENDF | 1295 | IT85_TXMPW_DEFAULT,
1305 IT85_TXMPM_DEFAULT | 1296 IT85_C0TCR);
1306 IT85_TXMPW_DEFAULT, IT85_C0TCR);
1307 1297
1308 /* program the carrier parameters */ 1298 /* program the carrier parameters */
1309 ite_set_carrier_params(dev); 1299 ite_set_carrier_params(dev);
@@ -1660,6 +1650,9 @@ static int ite_suspend(struct pnp_dev *pdev, pm_message_t state)
1660 1650
1661 ite_dbg("%s called", __func__); 1651 ite_dbg("%s called", __func__);
1662 1652
1653 /* wait for any transmission to end */
1654 wait_event_interruptible(dev->tx_ended, !dev->transmitting);
1655
1663 spin_lock_irqsave(&dev->lock, flags); 1656 spin_lock_irqsave(&dev->lock, flags);
1664 1657
1665 /* disable all interrupts */ 1658 /* disable all interrupts */
@@ -1680,13 +1673,10 @@ static int ite_resume(struct pnp_dev *pdev)
1680 1673
1681 spin_lock_irqsave(&dev->lock, flags); 1674 spin_lock_irqsave(&dev->lock, flags);
1682 1675
1683 if (dev->transmitting) { 1676 /* reinitialize hardware config registers */
1684 /* wake up the transmitter */ 1677 dev->params.init_hardware(dev);
1685 wake_up_interruptible(&dev->tx_queue); 1678 /* enable the receiver */
1686 } else { 1679 dev->params.enable_rx(dev);
1687 /* enable the receiver */
1688 dev->params.enable_rx(dev);
1689 }
1690 1680
1691 spin_unlock_irqrestore(&dev->lock, flags); 1681 spin_unlock_irqrestore(&dev->lock, flags);
1692 1682
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 85cac7ddbcec..b57fc83fb4d2 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
77 rc-terratec-slim.o \ 77 rc-terratec-slim.o \
78 rc-terratec-slim-2.o \ 78 rc-terratec-slim-2.o \
79 rc-tevii-nec.o \ 79 rc-tevii-nec.o \
80 rc-tivo.o \
80 rc-total-media-in-hand.o \ 81 rc-total-media-in-hand.o \
81 rc-trekstor.o \ 82 rc-trekstor.o \
82 rc-tt-1500.o \ 83 rc-tt-1500.o \
diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
index bdf97b74cf90..22f54d413a35 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
@@ -52,7 +52,7 @@ static struct rc_map_table avermedia_cardbus[] = {
52 { 0x28, KEY_SELECT }, /* Select */ 52 { 0x28, KEY_SELECT }, /* Select */
53 { 0x29, KEY_BLUE }, /* Blue/Picture */ 53 { 0x29, KEY_BLUE }, /* Blue/Picture */
54 { 0x2a, KEY_BACKSPACE }, /* Back */ 54 { 0x2a, KEY_BACKSPACE }, /* Back */
55 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */ 55 { 0x2b, KEY_VIDEO }, /* PIP (Picture-in-picture) */
56 { 0x2c, KEY_DOWN }, 56 { 0x2c, KEY_DOWN },
57 { 0x2e, KEY_DOT }, 57 { 0x2e, KEY_DOT },
58 { 0x2f, KEY_TV }, /* Live TV */ 58 { 0x2f, KEY_TV }, /* Live TV */
diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c
index 937a81989f00..0ea2aa190d81 100644
--- a/drivers/media/rc/keymaps/rc-imon-mce.c
+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = {
111 { 0x800ff44d, KEY_TITLE }, 111 { 0x800ff44d, KEY_TITLE },
112 112
113 { 0x800ff40c, KEY_POWER }, 113 { 0x800ff40c, KEY_POWER },
114 { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */ 114 { 0x800ff40d, KEY_MEDIA }, /* Windows MCE button */
115 115
116}; 116};
117 117
diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c
index 63d42bd24c9e..75d3843fdc30 100644
--- a/drivers/media/rc/keymaps/rc-imon-pad.c
+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
@@ -87,7 +87,7 @@ static struct rc_map_table imon_pad[] = {
87 87
88 { 0x2b8515b7, KEY_VIDEO }, 88 { 0x2b8515b7, KEY_VIDEO },
89 { 0x299195b7, KEY_AUDIO }, 89 { 0x299195b7, KEY_AUDIO },
90 { 0x2ba115b7, KEY_CAMERA }, 90 { 0x2ba115b7, KEY_IMAGES },
91 { 0x28a515b7, KEY_TV }, 91 { 0x28a515b7, KEY_TV },
92 { 0x29a395b7, KEY_DVD }, 92 { 0x29a395b7, KEY_DVD },
93 { 0x29a295b7, KEY_DVD }, 93 { 0x29a295b7, KEY_DVD },
@@ -97,7 +97,7 @@ static struct rc_map_table imon_pad[] = {
97 { 0x2ba395b7, KEY_MENU }, 97 { 0x2ba395b7, KEY_MENU },
98 98
99 { 0x288515b7, KEY_BOOKMARKS }, 99 { 0x288515b7, KEY_BOOKMARKS },
100 { 0x2ab715b7, KEY_MEDIA }, /* Thumbnail */ 100 { 0x2ab715b7, KEY_CAMERA }, /* Thumbnail */
101 { 0x298595b7, KEY_SUBTITLE }, 101 { 0x298595b7, KEY_SUBTITLE },
102 { 0x2b8595b7, KEY_LANGUAGE }, 102 { 0x2b8595b7, KEY_LANGUAGE },
103 103
@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = {
125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/ 125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */ 126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */
127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */ 127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
128 { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */ 128 { 0x2ab195b7, KEY_MEDIA }, /* Go or MultiMon */
129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ 129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
130}; 130};
131 131
diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index 08d183120e41..7fa17a369f2d 100644
--- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19static struct rc_map_table kworld_plus_tv_analog[] = { 19static struct rc_map_table kworld_plus_tv_analog[] = {
20 { 0x0c, KEY_LEFTMETA }, /* Kworld key */ 20 { 0x0c, KEY_MEDIA }, /* Kworld key */
21 { 0x16, KEY_CLOSECD }, /* -> ) */ 21 { 0x16, KEY_CLOSECD }, /* -> ) */
22 { 0x1d, KEY_POWER2 }, 22 { 0x1d, KEY_POWER2 },
23 23
diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c
index 8dd519ecc58e..01b69bcc8666 100644
--- a/drivers/media/rc/keymaps/rc-rc6-mce.c
+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = {
30 { 0x800f040a, KEY_DELETE }, 30 { 0x800f040a, KEY_DELETE },
31 { 0x800f040b, KEY_ENTER }, 31 { 0x800f040b, KEY_ENTER },
32 { 0x800f040c, KEY_POWER }, /* PC Power */ 32 { 0x800f040c, KEY_POWER }, /* PC Power */
33 { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */ 33 { 0x800f040d, KEY_MEDIA }, /* Windows MCE button */
34 { 0x800f040e, KEY_MUTE }, 34 { 0x800f040e, KEY_MUTE },
35 { 0x800f040f, KEY_INFO }, 35 { 0x800f040f, KEY_INFO },
36 36
@@ -87,7 +87,7 @@ static struct rc_map_table rc6_mce[] = {
87 87
88 { 0x800f0465, KEY_POWER2 }, /* TV Power */ 88 { 0x800f0465, KEY_POWER2 }, /* TV Power */
89 { 0x800f046e, KEY_PLAYPAUSE }, 89 { 0x800f046e, KEY_PLAYPAUSE },
90 { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ 90 { 0x800f046f, KEY_PLAYER }, /* Start media application (NEW) */
91 91
92 { 0x800f0480, KEY_BRIGHTNESSDOWN }, 92 { 0x800f0480, KEY_BRIGHTNESSDOWN },
93 { 0x800f0481, KEY_PLAYPAUSE }, 93 { 0x800f0481, KEY_PLAYPAUSE },
diff --git a/drivers/media/rc/keymaps/rc-tivo.c b/drivers/media/rc/keymaps/rc-tivo.c
new file mode 100644
index 000000000000..98ad085531fd
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tivo.c
@@ -0,0 +1,98 @@
1/* rc-tivo.c - Keytable for TiVo remotes
2 *
3 * Copyright (c) 2011 by Jarod Wilson <jarod@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <media/rc-map.h>
12
13/*
14 * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle,
15 * which also ships with a TiVo-branded IR transceiver, supported by the mceusb
16 * driver. Note that the remote uses an NEC-ish protocol, but instead of having
17 * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the
18 * NEC extended checksums do pass, so the table presently has the intended
19 * values and the checksum-passed versions for those keys.
20 */
21static struct rc_map_table tivo[] = {
22 { 0xa10c900f, KEY_MEDIA }, /* TiVo Button */
23 { 0xa10c0807, KEY_POWER2 }, /* TV Power */
24 { 0xa10c8807, KEY_TV }, /* Live TV/Swap */
25 { 0xa10c2c03, KEY_VIDEO_NEXT }, /* TV Input */
26 { 0xa10cc807, KEY_INFO },
27 { 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */
28 { 0x0085305f, KEY_CYCLEWINDOWS },
29 { 0xa10c6c03, KEY_EPG }, /* Guide */
30
31 { 0xa10c2807, KEY_UP },
32 { 0xa10c6807, KEY_DOWN },
33 { 0xa10ce807, KEY_LEFT },
34 { 0xa10ca807, KEY_RIGHT },
35
36 { 0xa10c1807, KEY_SCROLLDOWN }, /* Red Thumbs Down */
37 { 0xa10c9807, KEY_SELECT },
38 { 0xa10c5807, KEY_SCROLLUP }, /* Green Thumbs Up */
39
40 { 0xa10c3807, KEY_VOLUMEUP },
41 { 0xa10cb807, KEY_VOLUMEDOWN },
42 { 0xa10cd807, KEY_MUTE },
43 { 0xa10c040b, KEY_RECORD },
44 { 0xa10c7807, KEY_CHANNELUP },
45 { 0xa10cf807, KEY_CHANNELDOWN },
46 { 0x0085301f, KEY_CHANNELDOWN },
47
48 { 0xa10c840b, KEY_PLAY },
49 { 0xa10cc40b, KEY_PAUSE },
50 { 0xa10ca40b, KEY_SLOW },
51 { 0xa10c440b, KEY_REWIND },
52 { 0xa10c240b, KEY_FASTFORWARD },
53 { 0xa10c640b, KEY_PREVIOUS },
54 { 0xa10ce40b, KEY_NEXT }, /* ->| */
55
56 { 0xa10c220d, KEY_ZOOM }, /* Aspect */
57 { 0xa10c120d, KEY_STOP },
58 { 0xa10c520d, KEY_DVD }, /* DVD Menu */
59
60 { 0xa10c140b, KEY_NUMERIC_1 },
61 { 0xa10c940b, KEY_NUMERIC_2 },
62 { 0xa10c540b, KEY_NUMERIC_3 },
63 { 0xa10cd40b, KEY_NUMERIC_4 },
64 { 0xa10c340b, KEY_NUMERIC_5 },
65 { 0xa10cb40b, KEY_NUMERIC_6 },
66 { 0xa10c740b, KEY_NUMERIC_7 },
67 { 0xa10cf40b, KEY_NUMERIC_8 },
68 { 0x0085302f, KEY_NUMERIC_8 },
69 { 0xa10c0c03, KEY_NUMERIC_9 },
70 { 0xa10c8c03, KEY_NUMERIC_0 },
71 { 0xa10ccc03, KEY_ENTER },
72 { 0xa10c4c03, KEY_CLEAR },
73};
74
75static struct rc_map_list tivo_map = {
76 .map = {
77 .scan = tivo,
78 .size = ARRAY_SIZE(tivo),
79 .rc_type = RC_TYPE_NEC,
80 .name = RC_MAP_TIVO,
81 }
82};
83
84static int __init init_rc_map_tivo(void)
85{
86 return rc_map_register(&tivo_map);
87}
88
89static void __exit exit_rc_map_tivo(void)
90{
91 rc_map_unregister(&tivo_map);
92}
93
94module_init(init_rc_map_tivo)
95module_exit(exit_rc_map_tivo)
96
97MODULE_LICENSE("GPL");
98MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 0062ca291959..d8a34c14676a 100644
--- a/drivers/media/rc/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -32,8 +32,8 @@ static struct rc_map_table winfast[] = {
32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ 32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
33 { 0x1e, KEY_VIDEO }, /* Video Source */ 33 { 0x1e, KEY_VIDEO }, /* Video Source */
34 { 0x16, KEY_INFO }, /* Display information */ 34 { 0x16, KEY_INFO }, /* Display information */
35 { 0x04, KEY_LEFT }, 35 { 0x04, KEY_RIGHT },
36 { 0x08, KEY_RIGHT }, 36 { 0x08, KEY_LEFT },
37 { 0x0c, KEY_UP }, 37 { 0x0c, KEY_UP },
38 { 0x10, KEY_DOWN }, 38 { 0x10, KEY_DOWN },
39 { 0x03, KEY_ZOOM }, /* fullscreen */ 39 { 0x03, KEY_ZOOM }, /* fullscreen */
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 0c273ec465c9..ad927fcaa020 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -149,6 +149,8 @@ enum mceusb_model_type {
149 POLARIS_EVK, 149 POLARIS_EVK,
150 CX_HYBRID_TV, 150 CX_HYBRID_TV,
151 MULTIFUNCTION, 151 MULTIFUNCTION,
152 TIVO_KIT,
153 MCE_GEN2_NO_TX,
152}; 154};
153 155
154struct mceusb_model { 156struct mceusb_model {
@@ -172,6 +174,10 @@ static const struct mceusb_model mceusb_model[] = {
172 [MCE_GEN2] = { 174 [MCE_GEN2] = {
173 .mce_gen2 = 1, 175 .mce_gen2 = 1,
174 }, 176 },
177 [MCE_GEN2_NO_TX] = {
178 .mce_gen2 = 1,
179 .no_tx = 1,
180 },
175 [MCE_GEN2_TX_INV] = { 181 [MCE_GEN2_TX_INV] = {
176 .mce_gen2 = 1, 182 .mce_gen2 = 1,
177 .tx_mask_normal = 1, 183 .tx_mask_normal = 1,
@@ -197,6 +203,10 @@ static const struct mceusb_model mceusb_model[] = {
197 .mce_gen2 = 1, 203 .mce_gen2 = 1,
198 .ir_intfnum = 2, 204 .ir_intfnum = 2,
199 }, 205 },
206 [TIVO_KIT] = {
207 .mce_gen2 = 1,
208 .rc_map = RC_MAP_TIVO,
209 },
200}; 210};
201 211
202static struct usb_device_id mceusb_dev_table[] = { 212static struct usb_device_id mceusb_dev_table[] = {
@@ -279,7 +289,8 @@ static struct usb_device_id mceusb_dev_table[] = {
279 /* Formosa21 / eHome Infrared Receiver */ 289 /* Formosa21 / eHome Infrared Receiver */
280 { USB_DEVICE(VENDOR_FORMOSA, 0xe016) }, 290 { USB_DEVICE(VENDOR_FORMOSA, 0xe016) },
281 /* Formosa aim / Trust MCE Infrared Receiver */ 291 /* Formosa aim / Trust MCE Infrared Receiver */
282 { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, 292 { USB_DEVICE(VENDOR_FORMOSA, 0xe017),
293 .driver_info = MCE_GEN2_NO_TX },
283 /* Formosa Industrial Computing / Beanbag Emulation Device */ 294 /* Formosa Industrial Computing / Beanbag Emulation Device */
284 { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, 295 { USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
285 /* Formosa21 / eHome Infrared Receiver */ 296 /* Formosa21 / eHome Infrared Receiver */
@@ -308,7 +319,8 @@ static struct usb_device_id mceusb_dev_table[] = {
308 /* Northstar Systems, Inc. eHome Infrared Transceiver */ 319 /* Northstar Systems, Inc. eHome Infrared Transceiver */
309 { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, 320 { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
310 /* TiVo PC IR Receiver */ 321 /* TiVo PC IR Receiver */
311 { USB_DEVICE(VENDOR_TIVO, 0x2000) }, 322 { USB_DEVICE(VENDOR_TIVO, 0x2000),
323 .driver_info = TIVO_KIT },
312 /* Conexant Hybrid TV "Shelby" Polaris SDK */ 324 /* Conexant Hybrid TV "Shelby" Polaris SDK */
313 { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), 325 { USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
314 .driver_info = POLARIS_EVK }, 326 .driver_info = POLARIS_EVK },
@@ -603,11 +615,10 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
603} 615}
604 616
605/* request incoming or send outgoing usb packet - used to initialize remote */ 617/* request incoming or send outgoing usb packet - used to initialize remote */
606static void mce_request_packet(struct mceusb_dev *ir, 618static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
607 struct usb_endpoint_descriptor *ep, 619 int size, int urb_type)
608 unsigned char *data, int size, int urb_type)
609{ 620{
610 int res; 621 int res, pipe;
611 struct urb *async_urb; 622 struct urb *async_urb;
612 struct device *dev = ir->dev; 623 struct device *dev = ir->dev;
613 unsigned char *async_buf; 624 unsigned char *async_buf;
@@ -627,10 +638,11 @@ static void mce_request_packet(struct mceusb_dev *ir,
627 } 638 }
628 639
629 /* outbound data */ 640 /* outbound data */
630 usb_fill_int_urb(async_urb, ir->usbdev, 641 pipe = usb_sndintpipe(ir->usbdev,
631 usb_sndintpipe(ir->usbdev, ep->bEndpointAddress), 642 ir->usb_ep_out->bEndpointAddress);
643 usb_fill_int_urb(async_urb, ir->usbdev, pipe,
632 async_buf, size, (usb_complete_t)mce_async_callback, 644 async_buf, size, (usb_complete_t)mce_async_callback,
633 ir, ep->bInterval); 645 ir, ir->usb_ep_out->bInterval);
634 memcpy(async_buf, data, size); 646 memcpy(async_buf, data, size);
635 647
636 } else if (urb_type == MCEUSB_RX) { 648 } else if (urb_type == MCEUSB_RX) {
@@ -658,12 +670,12 @@ static void mce_request_packet(struct mceusb_dev *ir,
658 670
659static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) 671static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
660{ 672{
661 mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX); 673 mce_request_packet(ir, data, size, MCEUSB_TX);
662} 674}
663 675
664static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) 676static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
665{ 677{
666 mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX); 678 mce_request_packet(ir, data, size, MCEUSB_RX);
667} 679}
668 680
669/* Send data out the IR blaster port(s) */ 681/* Send data out the IR blaster port(s) */
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index d4d64492a057..bf3060ea6107 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -37,8 +37,6 @@
37 37
38#include "nuvoton-cir.h" 38#include "nuvoton-cir.h"
39 39
40static char *chip_id = "w836x7hg";
41
42/* write val to config reg */ 40/* write val to config reg */
43static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg) 41static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg)
44{ 42{
@@ -233,6 +231,8 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
233 unsigned long flags; 231 unsigned long flags;
234 u8 chip_major, chip_minor; 232 u8 chip_major, chip_minor;
235 int ret = 0; 233 int ret = 0;
234 char chip_id[12];
235 bool chip_unknown = false;
236 236
237 nvt_efm_enable(nvt); 237 nvt_efm_enable(nvt);
238 238
@@ -246,15 +246,39 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
246 } 246 }
247 247
248 chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO); 248 chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
249 nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor);
250 249
251 if (chip_major != CHIP_ID_HIGH || 250 /* these are the known working chip revisions... */
252 (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) { 251 switch (chip_major) {
253 nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x", 252 case CHIP_ID_HIGH_667:
254 chip_id, chip_major, chip_minor); 253 strcpy(chip_id, "w83667hg\0");
255 ret = -ENODEV; 254 if (chip_minor != CHIP_ID_LOW_667)
255 chip_unknown = true;
256 break;
257 case CHIP_ID_HIGH_677B:
258 strcpy(chip_id, "w83677hg\0");
259 if (chip_minor != CHIP_ID_LOW_677B2 &&
260 chip_minor != CHIP_ID_LOW_677B3)
261 chip_unknown = true;
262 break;
263 case CHIP_ID_HIGH_677C:
264 strcpy(chip_id, "w83677hg-c\0");
265 if (chip_minor != CHIP_ID_LOW_677C)
266 chip_unknown = true;
267 break;
268 default:
269 strcpy(chip_id, "w836x7hg\0");
270 chip_unknown = true;
271 break;
256 } 272 }
257 273
274 /* warn, but still let the driver load, if we don't know this chip */
275 if (chip_unknown)
276 nvt_pr(KERN_WARNING, "%s: unknown chip, id: 0x%02x 0x%02x, "
277 "it may not work...", chip_id, chip_major, chip_minor);
278 else
279 nvt_dbg("%s: chip id: 0x%02x 0x%02x",
280 chip_id, chip_major, chip_minor);
281
258 nvt_efm_disable(nvt); 282 nvt_efm_disable(nvt);
259 283
260 spin_lock_irqsave(&nvt->nvt_lock, flags); 284 spin_lock_irqsave(&nvt->nvt_lock, flags);
@@ -267,13 +291,23 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
267 291
268static void nvt_cir_ldev_init(struct nvt_dev *nvt) 292static void nvt_cir_ldev_init(struct nvt_dev *nvt)
269{ 293{
270 u8 val; 294 u8 val, psreg, psmask, psval;
295
296 if (nvt->chip_major == CHIP_ID_HIGH_667) {
297 psreg = CR_MULTIFUNC_PIN_SEL;
298 psmask = MULTIFUNC_PIN_SEL_MASK;
299 psval = MULTIFUNC_ENABLE_CIR | MULTIFUNC_ENABLE_CIRWB;
300 } else {
301 psreg = CR_OUTPUT_PIN_SEL;
302 psmask = OUTPUT_PIN_SEL_MASK;
303 psval = OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB;
304 }
271 305
272 /* output pin selection (Pin95=CIRRX, Pin96=CIRTX1, WB enabled */ 306 /* output pin selection: enable CIR, with WB sensor enabled */
273 val = nvt_cr_read(nvt, CR_OUTPUT_PIN_SEL); 307 val = nvt_cr_read(nvt, psreg);
274 val &= OUTPUT_PIN_SEL_MASK; 308 val &= psmask;
275 val |= (OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB); 309 val |= psval;
276 nvt_cr_write(nvt, val, CR_OUTPUT_PIN_SEL); 310 nvt_cr_write(nvt, val, psreg);
277 311
278 /* Select CIR logical device and enable */ 312 /* Select CIR logical device and enable */
279 nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR); 313 nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
@@ -640,7 +674,7 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
640 rawir.pulse ? "pulse" : "space", 674 rawir.pulse ? "pulse" : "space",
641 rawir.duration); 675 rawir.duration);
642 676
643 ir_raw_event_store(nvt->rdev, &rawir); 677 ir_raw_event_store_with_filter(nvt->rdev, &rawir);
644 } 678 }
645 679
646 /* 680 /*
@@ -1070,18 +1104,20 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
1070 rdev->tx_ir = nvt_tx_ir; 1104 rdev->tx_ir = nvt_tx_ir;
1071 rdev->s_tx_carrier = nvt_set_tx_carrier; 1105 rdev->s_tx_carrier = nvt_set_tx_carrier;
1072 rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; 1106 rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
1107 rdev->input_phys = "nuvoton/cir0";
1073 rdev->input_id.bustype = BUS_HOST; 1108 rdev->input_id.bustype = BUS_HOST;
1074 rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2; 1109 rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2;
1075 rdev->input_id.product = nvt->chip_major; 1110 rdev->input_id.product = nvt->chip_major;
1076 rdev->input_id.version = nvt->chip_minor; 1111 rdev->input_id.version = nvt->chip_minor;
1112 rdev->dev.parent = &pdev->dev;
1077 rdev->driver_name = NVT_DRIVER_NAME; 1113 rdev->driver_name = NVT_DRIVER_NAME;
1078 rdev->map_name = RC_MAP_RC6_MCE; 1114 rdev->map_name = RC_MAP_RC6_MCE;
1115 rdev->timeout = US_TO_NS(1000);
1116 /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
1117 rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
1079#if 0 1118#if 0
1080 rdev->min_timeout = XYZ; 1119 rdev->min_timeout = XYZ;
1081 rdev->max_timeout = XYZ; 1120 rdev->max_timeout = XYZ;
1082 rdev->timeout = XYZ;
1083 /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
1084 rdev->rx_resolution = XYZ;
1085 /* tx bits */ 1121 /* tx bits */
1086 rdev->tx_resolution = XYZ; 1122 rdev->tx_resolution = XYZ;
1087#endif 1123#endif
@@ -1090,8 +1126,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
1090 if (ret) 1126 if (ret)
1091 goto failure; 1127 goto failure;
1092 1128
1093 device_set_wakeup_capable(&pdev->dev, 1); 1129 device_init_wakeup(&pdev->dev, true);
1094 device_set_wakeup_enable(&pdev->dev, 1);
1095 nvt->rdev = rdev; 1130 nvt->rdev = rdev;
1096 nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n"); 1131 nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
1097 if (debug) { 1132 if (debug) {
diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h
index 048135eea702..379795d61ea7 100644
--- a/drivers/media/rc/nuvoton-cir.h
+++ b/drivers/media/rc/nuvoton-cir.h
@@ -330,9 +330,13 @@ struct nvt_dev {
330#define EFER_EFM_DISABLE 0xaa 330#define EFER_EFM_DISABLE 0xaa
331 331
332/* Chip IDs found in CR_CHIP_ID_{HI,LO} */ 332/* Chip IDs found in CR_CHIP_ID_{HI,LO} */
333#define CHIP_ID_HIGH 0xb4 333#define CHIP_ID_HIGH_667 0xa5
334#define CHIP_ID_LOW 0x72 334#define CHIP_ID_HIGH_677B 0xb4
335#define CHIP_ID_LOW2 0x73 335#define CHIP_ID_HIGH_677C 0xc3
336#define CHIP_ID_LOW_667 0x13
337#define CHIP_ID_LOW_677B2 0x72
338#define CHIP_ID_LOW_677B3 0x73
339#define CHIP_ID_LOW_677C 0x33
336 340
337/* Config regs we need to care about */ 341/* Config regs we need to care about */
338#define CR_SOFTWARE_RESET 0x02 342#define CR_SOFTWARE_RESET 0x02
@@ -341,6 +345,7 @@ struct nvt_dev {
341#define CR_CHIP_ID_LO 0x21 345#define CR_CHIP_ID_LO 0x21
342#define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */ 346#define CR_DEV_POWER_DOWN 0x22 /* bit 2 is CIR power, default power on */
343#define CR_OUTPUT_PIN_SEL 0x27 347#define CR_OUTPUT_PIN_SEL 0x27
348#define CR_MULTIFUNC_PIN_SEL 0x2c
344#define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */ 349#define CR_LOGICAL_DEV_EN 0x30 /* valid for all logical devices */
345/* next three regs valid for both the CIR and CIR_WAKE logical devices */ 350/* next three regs valid for both the CIR and CIR_WAKE logical devices */
346#define CR_CIR_BASE_ADDR_HI 0x60 351#define CR_CIR_BASE_ADDR_HI 0x60
@@ -364,10 +369,16 @@ struct nvt_dev {
364#define CIR_INTR_MOUSE_IRQ_BIT 0x80 369#define CIR_INTR_MOUSE_IRQ_BIT 0x80
365#define PME_INTR_CIR_PASS_BIT 0x08 370#define PME_INTR_CIR_PASS_BIT 0x08
366 371
372/* w83677hg CIR pin config */
367#define OUTPUT_PIN_SEL_MASK 0xbc 373#define OUTPUT_PIN_SEL_MASK 0xbc
368#define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */ 374#define OUTPUT_ENABLE_CIR 0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */
369#define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */ 375#define OUTPUT_ENABLE_CIRWB 0x40 /* enable wide-band sensor */
370 376
377/* w83667hg CIR pin config */
378#define MULTIFUNC_PIN_SEL_MASK 0x1f
379#define MULTIFUNC_ENABLE_CIR 0x80 /* Pin75=CIRRX, Pin76=CIRTX1 */
380#define MULTIFUNC_ENABLE_CIRWB 0x20 /* enable wide-band sensor */
381
371/* MCE CIR signal length, related on sample period */ 382/* MCE CIR signal length, related on sample period */
372 383
373/* MCE CIR controller signal length: about 43ms 384/* MCE CIR controller signal length: about 43ms
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 49cee61d79c6..cc846b2619cf 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -146,6 +146,12 @@ static int loop_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
146 if (rawir.duration) 146 if (rawir.duration)
147 ir_raw_event_store_with_filter(dev, &rawir); 147 ir_raw_event_store_with_filter(dev, &rawir);
148 } 148 }
149
150 /* Fake a silence long enough to cause us to go idle */
151 rawir.pulse = false;
152 rawir.duration = dev->timeout;
153 ir_raw_event_store_with_filter(dev, &rawir);
154
149 ir_raw_event_handle(dev); 155 ir_raw_event_handle(dev);
150 156
151out: 157out:
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index a2706648e365..f57cd5677ac2 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -749,6 +749,9 @@ static struct {
749 * it is trigged by reading /sys/class/rc/rc?/protocols. 749 * it is trigged by reading /sys/class/rc/rc?/protocols.
750 * It returns the protocol names of supported protocols. 750 * It returns the protocol names of supported protocols.
751 * Enabled protocols are printed in brackets. 751 * Enabled protocols are printed in brackets.
752 *
753 * dev->lock is taken to guard against races between device
754 * registration, store_protocols and show_protocols.
752 */ 755 */
753static ssize_t show_protocols(struct device *device, 756static ssize_t show_protocols(struct device *device,
754 struct device_attribute *mattr, char *buf) 757 struct device_attribute *mattr, char *buf)
@@ -762,6 +765,8 @@ static ssize_t show_protocols(struct device *device,
762 if (!dev) 765 if (!dev)
763 return -EINVAL; 766 return -EINVAL;
764 767
768 mutex_lock(&dev->lock);
769
765 if (dev->driver_type == RC_DRIVER_SCANCODE) { 770 if (dev->driver_type == RC_DRIVER_SCANCODE) {
766 enabled = dev->rc_map.rc_type; 771 enabled = dev->rc_map.rc_type;
767 allowed = dev->allowed_protos; 772 allowed = dev->allowed_protos;
@@ -784,6 +789,9 @@ static ssize_t show_protocols(struct device *device,
784 if (tmp != buf) 789 if (tmp != buf)
785 tmp--; 790 tmp--;
786 *tmp = '\n'; 791 *tmp = '\n';
792
793 mutex_unlock(&dev->lock);
794
787 return tmp + 1 - buf; 795 return tmp + 1 - buf;
788} 796}
789 797
@@ -802,6 +810,9 @@ static ssize_t show_protocols(struct device *device,
802 * Writing "none" will disable all protocols. 810 * Writing "none" will disable all protocols.
803 * Returns -EINVAL if an invalid protocol combination or unknown protocol name 811 * Returns -EINVAL if an invalid protocol combination or unknown protocol name
804 * is used, otherwise @len. 812 * is used, otherwise @len.
813 *
814 * dev->lock is taken to guard against races between device
815 * registration, store_protocols and show_protocols.
805 */ 816 */
806static ssize_t store_protocols(struct device *device, 817static ssize_t store_protocols(struct device *device,
807 struct device_attribute *mattr, 818 struct device_attribute *mattr,
@@ -815,18 +826,22 @@ static ssize_t store_protocols(struct device *device,
815 u64 mask; 826 u64 mask;
816 int rc, i, count = 0; 827 int rc, i, count = 0;
817 unsigned long flags; 828 unsigned long flags;
829 ssize_t ret;
818 830
819 /* Device is being removed */ 831 /* Device is being removed */
820 if (!dev) 832 if (!dev)
821 return -EINVAL; 833 return -EINVAL;
822 834
835 mutex_lock(&dev->lock);
836
823 if (dev->driver_type == RC_DRIVER_SCANCODE) 837 if (dev->driver_type == RC_DRIVER_SCANCODE)
824 type = dev->rc_map.rc_type; 838 type = dev->rc_map.rc_type;
825 else if (dev->raw) 839 else if (dev->raw)
826 type = dev->raw->enabled_protocols; 840 type = dev->raw->enabled_protocols;
827 else { 841 else {
828 IR_dprintk(1, "Protocol switching not supported\n"); 842 IR_dprintk(1, "Protocol switching not supported\n");
829 return -EINVAL; 843 ret = -EINVAL;
844 goto out;
830 } 845 }
831 846
832 while ((tmp = strsep((char **) &data, " \n")) != NULL) { 847 while ((tmp = strsep((char **) &data, " \n")) != NULL) {
@@ -860,7 +875,8 @@ static ssize_t store_protocols(struct device *device,
860 } 875 }
861 if (i == ARRAY_SIZE(proto_names)) { 876 if (i == ARRAY_SIZE(proto_names)) {
862 IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); 877 IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
863 return -EINVAL; 878 ret = -EINVAL;
879 goto out;
864 } 880 }
865 count++; 881 count++;
866 } 882 }
@@ -875,7 +891,8 @@ static ssize_t store_protocols(struct device *device,
875 891
876 if (!count) { 892 if (!count) {
877 IR_dprintk(1, "Protocol not specified\n"); 893 IR_dprintk(1, "Protocol not specified\n");
878 return -EINVAL; 894 ret = -EINVAL;
895 goto out;
879 } 896 }
880 897
881 if (dev->change_protocol) { 898 if (dev->change_protocol) {
@@ -883,7 +900,8 @@ static ssize_t store_protocols(struct device *device,
883 if (rc < 0) { 900 if (rc < 0) {
884 IR_dprintk(1, "Error setting protocols to 0x%llx\n", 901 IR_dprintk(1, "Error setting protocols to 0x%llx\n",
885 (long long)type); 902 (long long)type);
886 return -EINVAL; 903 ret = -EINVAL;
904 goto out;
887 } 905 }
888 } 906 }
889 907
@@ -898,7 +916,11 @@ static ssize_t store_protocols(struct device *device,
898 IR_dprintk(1, "Current protocol(s): 0x%llx\n", 916 IR_dprintk(1, "Current protocol(s): 0x%llx\n",
899 (long long)type); 917 (long long)type);
900 918
901 return len; 919 ret = len;
920
921out:
922 mutex_unlock(&dev->lock);
923 return ret;
902} 924}
903 925
904static void rc_dev_release(struct device *device) 926static void rc_dev_release(struct device *device)
@@ -974,6 +996,7 @@ struct rc_dev *rc_allocate_device(void)
974 996
975 spin_lock_init(&dev->rc_map.lock); 997 spin_lock_init(&dev->rc_map.lock);
976 spin_lock_init(&dev->keylock); 998 spin_lock_init(&dev->keylock);
999 mutex_init(&dev->lock);
977 setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); 1000 setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
978 1001
979 dev->dev.type = &rc_dev_type; 1002 dev->dev.type = &rc_dev_type;
@@ -1019,12 +1042,21 @@ int rc_register_device(struct rc_dev *dev)
1019 if (dev->close) 1042 if (dev->close)
1020 dev->input_dev->close = ir_close; 1043 dev->input_dev->close = ir_close;
1021 1044
1045 /*
1046 * Take the lock here, as the device sysfs node will appear
1047 * when device_add() is called, which may trigger an ir-keytable udev
1048 * rule, which will in turn call show_protocols and access either
1049 * dev->rc_map.rc_type or dev->raw->enabled_protocols before it has
1050 * been initialized.
1051 */
1052 mutex_lock(&dev->lock);
1053
1022 dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1); 1054 dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1);
1023 dev_set_name(&dev->dev, "rc%ld", dev->devno); 1055 dev_set_name(&dev->dev, "rc%ld", dev->devno);
1024 dev_set_drvdata(&dev->dev, dev); 1056 dev_set_drvdata(&dev->dev, dev);
1025 rc = device_add(&dev->dev); 1057 rc = device_add(&dev->dev);
1026 if (rc) 1058 if (rc)
1027 return rc; 1059 goto out_unlock;
1028 1060
1029 rc = ir_setkeytable(dev, rc_map); 1061 rc = ir_setkeytable(dev, rc_map);
1030 if (rc) 1062 if (rc)
@@ -1046,6 +1078,13 @@ int rc_register_device(struct rc_dev *dev)
1046 */ 1078 */
1047 dev->input_dev->rep[REP_DELAY] = 500; 1079 dev->input_dev->rep[REP_DELAY] = 500;
1048 1080
1081 /*
1082 * As a repeat event on protocols like RC-5 and NEC take as long as
1083 * 110/114ms, using 33ms as a repeat period is not the right thing
1084 * to do.
1085 */
1086 dev->input_dev->rep[REP_PERIOD] = 125;
1087
1049 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); 1088 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
1050 printk(KERN_INFO "%s: %s as %s\n", 1089 printk(KERN_INFO "%s: %s as %s\n",
1051 dev_name(&dev->dev), 1090 dev_name(&dev->dev),
@@ -1058,6 +1097,7 @@ int rc_register_device(struct rc_dev *dev)
1058 if (rc < 0) 1097 if (rc < 0)
1059 goto out_input; 1098 goto out_input;
1060 } 1099 }
1100 mutex_unlock(&dev->lock);
1061 1101
1062 if (dev->change_protocol) { 1102 if (dev->change_protocol) {
1063 rc = dev->change_protocol(dev, rc_map->rc_type); 1103 rc = dev->change_protocol(dev, rc_map->rc_type);
@@ -1083,6 +1123,8 @@ out_table:
1083 ir_free_table(&dev->rc_map); 1123 ir_free_table(&dev->rc_map);
1084out_dev: 1124out_dev:
1085 device_del(&dev->dev); 1125 device_del(&dev->dev);
1126out_unlock:
1127 mutex_unlock(&dev->lock);
1086 return rc; 1128 return rc;
1087} 1129}
1088EXPORT_SYMBOL_GPL(rc_register_device); 1130EXPORT_SYMBOL_GPL(rc_register_device);
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
new file mode 100644
index 000000000000..5147767ccb78
--- /dev/null
+++ b/drivers/media/rc/redrat3.c
@@ -0,0 +1,1344 @@
1/*
2 * USB RedRat3 IR Transceiver rc-core driver
3 *
4 * Copyright (c) 2011 by Jarod Wilson <jarod@redhat.com>
5 * based heavily on the work of Stephen Cox, with additional
6 * help from RedRat Ltd.
7 *
8 * This driver began life based an an old version of the first-generation
9 * lirc_mceusb driver from the lirc 0.7.2 distribution. It was then
10 * significantly rewritten by Stephen Cox with the aid of RedRat Ltd's
11 * Chris Dodge.
12 *
13 * The driver was then ported to rc-core and significantly rewritten again,
14 * by Jarod, using the in-kernel mceusb driver as a guide, after an initial
15 * port effort was started by Stephen.
16 *
17 * TODO LIST:
18 * - fix lirc not showing repeats properly
19 * --
20 *
21 * The RedRat3 is a USB transceiver with both send & receive,
22 * with 2 separate sensors available for receive to enable
23 * both good long range reception for general use, and good
24 * short range reception when required for learning a signal.
25 *
26 * http://www.redrat.co.uk/
27 *
28 * It uses its own little protocol to communicate, the required
29 * parts of which are embedded within this driver.
30 * --
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 *
46 */
47
48#include <linux/device.h>
49#include <linux/module.h>
50#include <linux/slab.h>
51#include <linux/usb.h>
52#include <linux/usb/input.h>
53#include <media/rc-core.h>
54
55/* Driver Information */
56#define DRIVER_VERSION "0.70"
57#define DRIVER_AUTHOR "Jarod Wilson <jarod@redhat.com>"
58#define DRIVER_AUTHOR2 "The Dweller, Stephen Cox"
59#define DRIVER_DESC "RedRat3 USB IR Transceiver Driver"
60#define DRIVER_NAME "redrat3"
61
62/* module parameters */
63#ifdef CONFIG_USB_DEBUG
64static int debug = 1;
65#else
66static int debug;
67#endif
68
69#define RR3_DEBUG_STANDARD 0x1
70#define RR3_DEBUG_FUNCTION_TRACE 0x2
71
72#define rr3_dbg(dev, fmt, ...) \
73 do { \
74 if (debug & RR3_DEBUG_STANDARD) \
75 dev_info(dev, fmt, ## __VA_ARGS__); \
76 } while (0)
77
78#define rr3_ftr(dev, fmt, ...) \
79 do { \
80 if (debug & RR3_DEBUG_FUNCTION_TRACE) \
81 dev_info(dev, fmt, ## __VA_ARGS__); \
82 } while (0)
83
84/* bulk data transfer types */
85#define RR3_ERROR 0x01
86#define RR3_MOD_SIGNAL_IN 0x20
87#define RR3_MOD_SIGNAL_OUT 0x21
88
89/* Get the RR firmware version */
90#define RR3_FW_VERSION 0xb1
91#define RR3_FW_VERSION_LEN 64
92/* Send encoded signal bulk-sent earlier*/
93#define RR3_TX_SEND_SIGNAL 0xb3
94#define RR3_SET_IR_PARAM 0xb7
95#define RR3_GET_IR_PARAM 0xb8
96/* Blink the red LED on the device */
97#define RR3_BLINK_LED 0xb9
98/* Read serial number of device */
99#define RR3_READ_SER_NO 0xba
100#define RR3_SER_NO_LEN 4
101/* Start capture with the RC receiver */
102#define RR3_RC_DET_ENABLE 0xbb
103/* Stop capture with the RC receiver */
104#define RR3_RC_DET_DISABLE 0xbc
105/* Return the status of RC detector capture */
106#define RR3_RC_DET_STATUS 0xbd
107/* Reset redrat */
108#define RR3_RESET 0xa0
109
110/* Max number of lengths in the signal. */
111#define RR3_IR_IO_MAX_LENGTHS 0x01
112/* Periods to measure mod. freq. */
113#define RR3_IR_IO_PERIODS_MF 0x02
114/* Size of memory for main signal data */
115#define RR3_IR_IO_SIG_MEM_SIZE 0x03
116/* Delta value when measuring lengths */
117#define RR3_IR_IO_LENGTH_FUZZ 0x04
118/* Timeout for end of signal detection */
119#define RR3_IR_IO_SIG_TIMEOUT 0x05
120/* Minumum value for pause recognition. */
121#define RR3_IR_IO_MIN_PAUSE 0x06
122
123/* Clock freq. of EZ-USB chip */
124#define RR3_CLK 24000000
125/* Clock periods per timer count */
126#define RR3_CLK_PER_COUNT 12
127/* (RR3_CLK / RR3_CLK_PER_COUNT) */
128#define RR3_CLK_CONV_FACTOR 2000000
129/* USB bulk-in IR data endpoint address */
130#define RR3_BULK_IN_EP_ADDR 0x82
131
132/* Raw Modulated signal data value offsets */
133#define RR3_PAUSE_OFFSET 0
134#define RR3_FREQ_COUNT_OFFSET 4
135#define RR3_NUM_PERIOD_OFFSET 6
136#define RR3_MAX_LENGTHS_OFFSET 8
137#define RR3_NUM_LENGTHS_OFFSET 9
138#define RR3_MAX_SIGS_OFFSET 10
139#define RR3_NUM_SIGS_OFFSET 12
140#define RR3_REPEATS_OFFSET 14
141
142/* Size of the fixed-length portion of the signal */
143#define RR3_HEADER_LENGTH 15
144#define RR3_DRIVER_MAXLENS 128
145#define RR3_MAX_SIG_SIZE 512
146#define RR3_MAX_BUF_SIZE \
147 ((2 * RR3_HEADER_LENGTH) + RR3_DRIVER_MAXLENS + RR3_MAX_SIG_SIZE)
148#define RR3_TIME_UNIT 50
149#define RR3_END_OF_SIGNAL 0x7f
150#define RR3_TX_HEADER_OFFSET 4
151#define RR3_TX_TRAILER_LEN 2
152#define RR3_RX_MIN_TIMEOUT 5
153#define RR3_RX_MAX_TIMEOUT 2000
154
155/* The 8051's CPUCS Register address */
156#define RR3_CPUCS_REG_ADDR 0x7f92
157
158#define USB_RR3USB_VENDOR_ID 0x112a
159#define USB_RR3USB_PRODUCT_ID 0x0001
160#define USB_RR3IIUSB_PRODUCT_ID 0x0005
161
162/* table of devices that work with this driver */
163static struct usb_device_id redrat3_dev_table[] = {
164 /* Original version of the RedRat3 */
165 {USB_DEVICE(USB_RR3USB_VENDOR_ID, USB_RR3USB_PRODUCT_ID)},
166 /* Second Version/release of the RedRat3 - RetRat3-II */
167 {USB_DEVICE(USB_RR3USB_VENDOR_ID, USB_RR3IIUSB_PRODUCT_ID)},
168 {} /* Terminating entry */
169};
170
171/* Structure to hold all of our device specific stuff */
172struct redrat3_dev {
173 /* core device bits */
174 struct rc_dev *rc;
175 struct device *dev;
176
177 /* save off the usb device pointer */
178 struct usb_device *udev;
179
180 /* the receive endpoint */
181 struct usb_endpoint_descriptor *ep_in;
182 /* the buffer to receive data */
183 unsigned char *bulk_in_buf;
184 /* urb used to read ir data */
185 struct urb *read_urb;
186
187 /* the send endpoint */
188 struct usb_endpoint_descriptor *ep_out;
189 /* the buffer to send data */
190 unsigned char *bulk_out_buf;
191 /* the urb used to send data */
192 struct urb *write_urb;
193
194 /* usb dma */
195 dma_addr_t dma_in;
196 dma_addr_t dma_out;
197
198 /* true if write urb is busy */
199 bool write_busy;
200 /* wait for the write to finish */
201 struct completion write_finished;
202
203 /* locks this structure */
204 struct mutex lock;
205
206 /* rx signal timeout timer */
207 struct timer_list rx_timeout;
208
209 /* Is the device currently receiving? */
210 bool recv_in_progress;
211 /* is the detector enabled*/
212 bool det_enabled;
213 /* Is the device currently transmitting?*/
214 bool transmitting;
215
216 /* store for current packet */
217 char pbuf[RR3_MAX_BUF_SIZE];
218 u16 pktlen;
219 u16 pkttype;
220 u16 bytes_read;
221 /* indicate whether we are going to reprocess
222 * the USB callback with a bigger buffer */
223 int buftoosmall;
224 char *datap;
225
226 u32 carrier;
227
228 char name[128];
229 char phys[64];
230};
231
232/* All incoming data buffers adhere to a very specific data format */
233struct redrat3_signal_header {
234 u16 length; /* Length of data being transferred */
235 u16 transfer_type; /* Type of data transferred */
236 u32 pause; /* Pause between main and repeat signals */
237 u16 mod_freq_count; /* Value of timer on mod. freq. measurement */
238 u16 no_periods; /* No. of periods over which mod. freq. is measured */
239 u8 max_lengths; /* Max no. of lengths (i.e. size of array) */
240 u8 no_lengths; /* Actual no. of elements in lengths array */
241 u16 max_sig_size; /* Max no. of values in signal data array */
242 u16 sig_size; /* Acuto no. of values in signal data array */
243 u8 no_repeats; /* No. of repeats of repeat signal section */
244 /* Here forward is the lengths and signal data */
245};
246
247static void redrat3_dump_signal_header(struct redrat3_signal_header *header)
248{
249 pr_info("%s:\n", __func__);
250 pr_info(" * length: %u, transfer_type: 0x%02x\n",
251 header->length, header->transfer_type);
252 pr_info(" * pause: %u, freq_count: %u, no_periods: %u\n",
253 header->pause, header->mod_freq_count, header->no_periods);
254 pr_info(" * lengths: %u (max: %u)\n",
255 header->no_lengths, header->max_lengths);
256 pr_info(" * sig_size: %u (max: %u)\n",
257 header->sig_size, header->max_sig_size);
258 pr_info(" * repeats: %u\n", header->no_repeats);
259}
260
261static void redrat3_dump_signal_data(char *buffer, u16 len)
262{
263 int offset, i;
264 char *data_vals;
265
266 pr_info("%s:", __func__);
267
268 offset = RR3_TX_HEADER_OFFSET + RR3_HEADER_LENGTH
269 + (RR3_DRIVER_MAXLENS * sizeof(u16));
270
271 /* read RR3_DRIVER_MAXLENS from ctrl msg */
272 data_vals = buffer + offset;
273
274 for (i = 0; i < len; i++) {
275 if (i % 10 == 0)
276 pr_cont("\n * ");
277 pr_cont("%02x ", *data_vals++);
278 }
279
280 pr_cont("\n");
281}
282
283/*
284 * redrat3_issue_async
285 *
286 * Issues an async read to the ir data in port..
287 * sets the callback to be redrat3_handle_async
288 */
289static void redrat3_issue_async(struct redrat3_dev *rr3)
290{
291 int res;
292
293 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
294
295 if (!rr3->det_enabled) {
296 dev_warn(rr3->dev, "not issuing async read, "
297 "detector not enabled\n");
298 return;
299 }
300
301 memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize);
302 res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC);
303 if (res)
304 rr3_dbg(rr3->dev, "%s: receive request FAILED! "
305 "(res %d, len %d)\n", __func__, res,
306 rr3->read_urb->transfer_buffer_length);
307}
308
309static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code)
310{
311 if (!rr3->transmitting && (code != 0x40))
312 dev_info(rr3->dev, "fw error code 0x%02x: ", code);
313
314 switch (code) {
315 case 0x00:
316 pr_cont("No Error\n");
317 break;
318
319 /* Codes 0x20 through 0x2f are IR Firmware Errors */
320 case 0x20:
321 pr_cont("Initial signal pulse not long enough "
322 "to measure carrier frequency\n");
323 break;
324 case 0x21:
325 pr_cont("Not enough length values allocated for signal\n");
326 break;
327 case 0x22:
328 pr_cont("Not enough memory allocated for signal data\n");
329 break;
330 case 0x23:
331 pr_cont("Too many signal repeats\n");
332 break;
333 case 0x28:
334 pr_cont("Insufficient memory available for IR signal "
335 "data memory allocation\n");
336 break;
337 case 0x29:
338 pr_cont("Insufficient memory available "
339 "for IrDa signal data memory allocation\n");
340 break;
341
342 /* Codes 0x30 through 0x3f are USB Firmware Errors */
343 case 0x30:
344 pr_cont("Insufficient memory available for bulk "
345 "transfer structure\n");
346 break;
347
348 /*
349 * Other error codes... These are primarily errors that can occur in
350 * the control messages sent to the redrat
351 */
352 case 0x40:
353 if (!rr3->transmitting)
354 pr_cont("Signal capture has been terminated\n");
355 break;
356 case 0x41:
357 pr_cont("Attempt to set/get and unknown signal I/O "
358 "algorithm parameter\n");
359 break;
360 case 0x42:
361 pr_cont("Signal capture already started\n");
362 break;
363
364 default:
365 pr_cont("Unknown Error\n");
366 break;
367 }
368}
369
370static u32 redrat3_val_to_mod_freq(struct redrat3_signal_header *ph)
371{
372 u32 mod_freq = 0;
373
374 if (ph->mod_freq_count != 0)
375 mod_freq = (RR3_CLK * ph->no_periods) /
376 (ph->mod_freq_count * RR3_CLK_PER_COUNT);
377
378 return mod_freq;
379}
380
381/* this function scales down the figures for the same result... */
382static u32 redrat3_len_to_us(u32 length)
383{
384 u32 biglen = length * 1000;
385 u32 divisor = (RR3_CLK_CONV_FACTOR) / 1000;
386 u32 result = (u32) (biglen / divisor);
387
388 /* don't allow zero lengths to go back, breaks lirc */
389 return result ? result : 1;
390}
391
392/*
393 * convert us back into redrat3 lengths
394 *
395 * length * 1000 length * 1000000
396 * ------------- = ---------------- = micro
397 * rr3clk / 1000 rr3clk
398
399 * 6 * 2 4 * 3 micro * rr3clk micro * rr3clk / 1000
400 * ----- = 4 ----- = 6 -------------- = len ---------------------
401 * 3 2 1000000 1000
402 */
403static u32 redrat3_us_to_len(u32 microsec)
404{
405 u32 result;
406 u32 divisor;
407
408 microsec &= IR_MAX_DURATION;
409 divisor = (RR3_CLK_CONV_FACTOR / 1000);
410 result = (u32)(microsec * divisor) / 1000;
411
412 /* don't allow zero lengths to go back, breaks lirc */
413 return result ? result : 1;
414
415}
416
417/* timer callback to send long trailing space on receive timeout */
418static void redrat3_rx_timeout(unsigned long data)
419{
420 struct redrat3_dev *rr3 = (struct redrat3_dev *)data;
421 DEFINE_IR_RAW_EVENT(rawir);
422
423 rawir.pulse = false;
424 rawir.duration = rr3->rc->timeout;
425 rr3_dbg(rr3->dev, "storing trailing space with duration %d\n",
426 rawir.duration);
427 ir_raw_event_store_with_filter(rr3->rc, &rawir);
428
429 rr3_dbg(rr3->dev, "calling ir_raw_event_handle\n");
430 ir_raw_event_handle(rr3->rc);
431
432 rr3_dbg(rr3->dev, "calling ir_raw_event_reset\n");
433 ir_raw_event_reset(rr3->rc);
434}
435
436static void redrat3_process_ir_data(struct redrat3_dev *rr3)
437{
438 DEFINE_IR_RAW_EVENT(rawir);
439 struct redrat3_signal_header header;
440 struct device *dev;
441 int i;
442 unsigned long delay;
443 u32 mod_freq, single_len;
444 u16 *len_vals;
445 u8 *data_vals;
446 u32 tmp32;
447 u16 tmp16;
448 char *sig_data;
449
450 if (!rr3) {
451 pr_err("%s called with no context!\n", __func__);
452 return;
453 }
454
455 rr3_ftr(rr3->dev, "Entered %s\n", __func__);
456
457 dev = rr3->dev;
458 sig_data = rr3->pbuf;
459
460 header.length = rr3->pktlen;
461 header.transfer_type = rr3->pkttype;
462
463 /* Sanity check */
464 if (!(header.length >= RR3_HEADER_LENGTH))
465 dev_warn(dev, "read returned less than rr3 header len\n");
466
467 delay = usecs_to_jiffies(rr3->rc->timeout / 1000);
468 mod_timer(&rr3->rx_timeout, jiffies + delay);
469
470 memcpy(&tmp32, sig_data + RR3_PAUSE_OFFSET, sizeof(tmp32));
471 header.pause = be32_to_cpu(tmp32);
472
473 memcpy(&tmp16, sig_data + RR3_FREQ_COUNT_OFFSET, sizeof(tmp16));
474 header.mod_freq_count = be16_to_cpu(tmp16);
475
476 memcpy(&tmp16, sig_data + RR3_NUM_PERIOD_OFFSET, sizeof(tmp16));
477 header.no_periods = be16_to_cpu(tmp16);
478
479 header.max_lengths = sig_data[RR3_MAX_LENGTHS_OFFSET];
480 header.no_lengths = sig_data[RR3_NUM_LENGTHS_OFFSET];
481
482 memcpy(&tmp16, sig_data + RR3_MAX_SIGS_OFFSET, sizeof(tmp16));
483 header.max_sig_size = be16_to_cpu(tmp16);
484
485 memcpy(&tmp16, sig_data + RR3_NUM_SIGS_OFFSET, sizeof(tmp16));
486 header.sig_size = be16_to_cpu(tmp16);
487
488 header.no_repeats= sig_data[RR3_REPEATS_OFFSET];
489
490 if (debug) {
491 redrat3_dump_signal_header(&header);
492 redrat3_dump_signal_data(sig_data, header.sig_size);
493 }
494
495 mod_freq = redrat3_val_to_mod_freq(&header);
496 rr3_dbg(dev, "Got mod_freq of %u\n", mod_freq);
497
498 /* Here we pull out the 'length' values from the signal */
499 len_vals = (u16 *)(sig_data + RR3_HEADER_LENGTH);
500
501 data_vals = sig_data + RR3_HEADER_LENGTH +
502 (header.max_lengths * sizeof(u16));
503
504 /* process each rr3 encoded byte into an int */
505 for (i = 0; i < header.sig_size; i++) {
506 u16 val = len_vals[data_vals[i]];
507 single_len = redrat3_len_to_us((u32)be16_to_cpu(val));
508
509 /* cap the value to IR_MAX_DURATION */
510 single_len &= IR_MAX_DURATION;
511
512 /* we should always get pulse/space/pulse/space samples */
513 if (i % 2)
514 rawir.pulse = false;
515 else
516 rawir.pulse = true;
517
518 rawir.duration = US_TO_NS(single_len);
519 rr3_dbg(dev, "storing %s with duration %d (i: %d)\n",
520 rawir.pulse ? "pulse" : "space", rawir.duration, i);
521 ir_raw_event_store_with_filter(rr3->rc, &rawir);
522 }
523
524 /* add a trailing space, if need be */
525 if (i % 2) {
526 rawir.pulse = false;
527 /* this duration is made up, and may not be ideal... */
528 rawir.duration = rr3->rc->timeout / 2;
529 rr3_dbg(dev, "storing trailing space with duration %d\n",
530 rawir.duration);
531 ir_raw_event_store_with_filter(rr3->rc, &rawir);
532 }
533
534 rr3_dbg(dev, "calling ir_raw_event_handle\n");
535 ir_raw_event_handle(rr3->rc);
536
537 return;
538}
539
540/* Util fn to send rr3 cmds */
541static u8 redrat3_send_cmd(int cmd, struct redrat3_dev *rr3)
542{
543 struct usb_device *udev;
544 u8 *data;
545 int res;
546
547 data = kzalloc(sizeof(u8), GFP_KERNEL);
548 if (!data)
549 return -ENOMEM;
550
551 udev = rr3->udev;
552 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd,
553 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
554 0x0000, 0x0000, data, sizeof(u8), HZ * 10);
555
556 if (res < 0) {
557 dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d",
558 __func__, res, *data);
559 res = -EIO;
560 } else
561 res = (u8)data[0];
562
563 kfree(data);
564
565 return res;
566}
567
568/* Enables the long range detector and starts async receive */
569static int redrat3_enable_detector(struct redrat3_dev *rr3)
570{
571 struct device *dev = rr3->dev;
572 u8 ret;
573
574 rr3_ftr(dev, "Entering %s\n", __func__);
575
576 ret = redrat3_send_cmd(RR3_RC_DET_ENABLE, rr3);
577 if (ret != 0)
578 dev_dbg(dev, "%s: unexpected ret of %d\n",
579 __func__, ret);
580
581 ret = redrat3_send_cmd(RR3_RC_DET_STATUS, rr3);
582 if (ret != 1) {
583 dev_err(dev, "%s: detector status: %d, should be 1\n",
584 __func__, ret);
585 return -EIO;
586 }
587
588 rr3->det_enabled = true;
589 redrat3_issue_async(rr3);
590
591 return 0;
592}
593
594/* Disables the rr3 long range detector */
595static void redrat3_disable_detector(struct redrat3_dev *rr3)
596{
597 struct device *dev = rr3->dev;
598 u8 ret;
599
600 rr3_ftr(dev, "Entering %s\n", __func__);
601
602 ret = redrat3_send_cmd(RR3_RC_DET_DISABLE, rr3);
603 if (ret != 0)
604 dev_err(dev, "%s: failure!\n", __func__);
605
606 ret = redrat3_send_cmd(RR3_RC_DET_STATUS, rr3);
607 if (ret != 0)
608 dev_warn(dev, "%s: detector status: %d, should be 0\n",
609 __func__, ret);
610
611 rr3->det_enabled = false;
612}
613
614static inline void redrat3_delete(struct redrat3_dev *rr3,
615 struct usb_device *udev)
616{
617 rr3_ftr(rr3->dev, "%s cleaning up\n", __func__);
618 usb_kill_urb(rr3->read_urb);
619 usb_kill_urb(rr3->write_urb);
620
621 usb_free_urb(rr3->read_urb);
622 usb_free_urb(rr3->write_urb);
623
624 usb_free_coherent(udev, rr3->ep_in->wMaxPacketSize,
625 rr3->bulk_in_buf, rr3->dma_in);
626 usb_free_coherent(udev, rr3->ep_out->wMaxPacketSize,
627 rr3->bulk_out_buf, rr3->dma_out);
628
629 kfree(rr3);
630}
631
632static u32 redrat3_get_timeout(struct device *dev,
633 struct rc_dev *rc, struct usb_device *udev)
634{
635 u32 *tmp;
636 u32 timeout = MS_TO_NS(150); /* a sane default, if things go haywire */
637 int len, ret, pipe;
638
639 len = sizeof(*tmp);
640 tmp = kzalloc(len, GFP_KERNEL);
641 if (!tmp) {
642 dev_warn(dev, "Memory allocation faillure\n");
643 return timeout;
644 }
645
646 pipe = usb_rcvctrlpipe(udev, 0);
647 ret = usb_control_msg(udev, pipe, RR3_GET_IR_PARAM,
648 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
649 RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
650 if (ret != len) {
651 dev_warn(dev, "Failed to read timeout from hardware\n");
652 return timeout;
653 }
654
655 timeout = US_TO_NS(redrat3_len_to_us(be32_to_cpu(*tmp)));
656 if (timeout < rc->min_timeout)
657 timeout = rc->min_timeout;
658 else if (timeout > rc->max_timeout)
659 timeout = rc->max_timeout;
660
661 rr3_dbg(dev, "Got timeout of %d ms\n", timeout / (1000 * 1000));
662 return timeout;
663}
664
665static void redrat3_reset(struct redrat3_dev *rr3)
666{
667 struct usb_device *udev = rr3->udev;
668 struct device *dev = rr3->dev;
669 int rc, rxpipe, txpipe;
670 u8 *val;
671 int len = sizeof(u8);
672
673 rr3_ftr(dev, "Entering %s\n", __func__);
674
675 rxpipe = usb_rcvctrlpipe(udev, 0);
676 txpipe = usb_sndctrlpipe(udev, 0);
677
678 val = kzalloc(len, GFP_KERNEL);
679 if (!val) {
680 dev_err(dev, "Memory allocation failure\n");
681 return;
682 }
683
684 *val = 0x01;
685 rc = usb_control_msg(udev, rxpipe, RR3_RESET,
686 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
687 RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25);
688 rr3_dbg(dev, "reset returned 0x%02x\n", rc);
689
690 *val = 5;
691 rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
692 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
693 RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25);
694 rr3_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc);
695
696 *val = RR3_DRIVER_MAXLENS;
697 rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
698 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
699 RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25);
700 rr3_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc);
701
702 kfree(val);
703}
704
705static void redrat3_get_firmware_rev(struct redrat3_dev *rr3)
706{
707 int rc = 0;
708 char *buffer;
709
710 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
711
712 buffer = kzalloc(sizeof(char) * (RR3_FW_VERSION_LEN + 1), GFP_KERNEL);
713 if (!buffer) {
714 dev_err(rr3->dev, "Memory allocation failure\n");
715 return;
716 }
717
718 rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0),
719 RR3_FW_VERSION,
720 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
721 0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5);
722
723 if (rc >= 0)
724 dev_info(rr3->dev, "Firmware rev: %s", buffer);
725 else
726 dev_err(rr3->dev, "Problem fetching firmware ID\n");
727
728 kfree(buffer);
729 rr3_ftr(rr3->dev, "Exiting %s\n", __func__);
730}
731
732static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len)
733{
734 u16 tx_error;
735 u16 hdrlen;
736
737 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
738
739 /* grab the Length and type of transfer */
740 memcpy(&(rr3->pktlen), (unsigned char *) rr3->bulk_in_buf,
741 sizeof(rr3->pktlen));
742 memcpy(&(rr3->pkttype), ((unsigned char *) rr3->bulk_in_buf +
743 sizeof(rr3->pktlen)),
744 sizeof(rr3->pkttype));
745
746 /*data needs conversion to know what its real values are*/
747 rr3->pktlen = be16_to_cpu(rr3->pktlen);
748 rr3->pkttype = be16_to_cpu(rr3->pkttype);
749
750 switch (rr3->pkttype) {
751 case RR3_ERROR:
752 memcpy(&tx_error, ((unsigned char *)rr3->bulk_in_buf
753 + (sizeof(rr3->pktlen) + sizeof(rr3->pkttype))),
754 sizeof(tx_error));
755 tx_error = be16_to_cpu(tx_error);
756 redrat3_dump_fw_error(rr3, tx_error);
757 break;
758
759 case RR3_MOD_SIGNAL_IN:
760 hdrlen = sizeof(rr3->pktlen) + sizeof(rr3->pkttype);
761 rr3->bytes_read = len;
762 rr3->bytes_read -= hdrlen;
763 rr3->datap = &(rr3->pbuf[0]);
764
765 memcpy(rr3->datap, ((unsigned char *)rr3->bulk_in_buf + hdrlen),
766 rr3->bytes_read);
767 rr3->datap += rr3->bytes_read;
768 rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n",
769 rr3->bytes_read, rr3->pktlen);
770 break;
771
772 default:
773 rr3_dbg(rr3->dev, "ignoring packet with type 0x%02x, "
774 "len of %d, 0x%02x\n", rr3->pkttype, len, rr3->pktlen);
775 break;
776 }
777}
778
779static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len)
780{
781
782 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
783
784 memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len);
785 rr3->datap += len;
786
787 rr3->bytes_read += len;
788 rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n",
789 rr3->bytes_read, rr3->pktlen);
790}
791
792/* gather IR data from incoming urb, process it when we have enough */
793static int redrat3_get_ir_data(struct redrat3_dev *rr3, int len)
794{
795 struct device *dev = rr3->dev;
796 int ret = 0;
797
798 rr3_ftr(dev, "Entering %s\n", __func__);
799
800 if (rr3->pktlen > RR3_MAX_BUF_SIZE) {
801 dev_err(rr3->dev, "error: packet larger than buffer\n");
802 ret = -EINVAL;
803 goto out;
804 }
805
806 if ((rr3->bytes_read == 0) &&
807 (len >= (sizeof(rr3->pkttype) + sizeof(rr3->pktlen)))) {
808 redrat3_read_packet_start(rr3, len);
809 } else if (rr3->bytes_read != 0) {
810 redrat3_read_packet_continue(rr3, len);
811 } else if (rr3->bytes_read == 0) {
812 dev_err(dev, "error: no packet data read\n");
813 ret = -ENODATA;
814 goto out;
815 }
816
817 if (rr3->bytes_read > rr3->pktlen) {
818 dev_err(dev, "bytes_read (%d) greater than pktlen (%d)\n",
819 rr3->bytes_read, rr3->pktlen);
820 ret = -EINVAL;
821 goto out;
822 } else if (rr3->bytes_read < rr3->pktlen)
823 /* we're still accumulating data */
824 return 0;
825
826 /* if we get here, we've got IR data to decode */
827 if (rr3->pkttype == RR3_MOD_SIGNAL_IN)
828 redrat3_process_ir_data(rr3);
829 else
830 rr3_dbg(dev, "discarding non-signal data packet "
831 "(type 0x%02x)\n", rr3->pkttype);
832
833out:
834 rr3->bytes_read = 0;
835 rr3->pktlen = 0;
836 rr3->pkttype = 0;
837 return ret;
838}
839
840/* callback function from USB when async USB request has completed */
841static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
842{
843 struct redrat3_dev *rr3;
844
845 if (!urb)
846 return;
847
848 rr3 = urb->context;
849 if (!rr3) {
850 pr_err("%s called with invalid context!\n", __func__);
851 usb_unlink_urb(urb);
852 return;
853 }
854
855 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
856
857 if (!rr3->det_enabled) {
858 rr3_dbg(rr3->dev, "received a read callback but detector "
859 "disabled - ignoring\n");
860 return;
861 }
862
863 switch (urb->status) {
864 case 0:
865 redrat3_get_ir_data(rr3, urb->actual_length);
866 break;
867
868 case -ECONNRESET:
869 case -ENOENT:
870 case -ESHUTDOWN:
871 usb_unlink_urb(urb);
872 return;
873
874 case -EPIPE:
875 default:
876 dev_warn(rr3->dev, "Error: urb status = %d\n", urb->status);
877 rr3->bytes_read = 0;
878 rr3->pktlen = 0;
879 rr3->pkttype = 0;
880 break;
881 }
882
883 if (!rr3->transmitting)
884 redrat3_issue_async(rr3);
885 else
886 rr3_dbg(rr3->dev, "IR transmit in progress\n");
887}
888
889static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
890{
891 struct redrat3_dev *rr3;
892 int len;
893
894 if (!urb)
895 return;
896
897 rr3 = urb->context;
898 if (rr3) {
899 len = urb->actual_length;
900 rr3_ftr(rr3->dev, "%s: called (status=%d len=%d)\n",
901 __func__, urb->status, len);
902 }
903}
904
905static u16 mod_freq_to_val(unsigned int mod_freq)
906{
907 int mult = 6000000;
908
909 /* Clk used in mod. freq. generation is CLK24/4. */
910 return (u16)(65536 - (mult / mod_freq));
911}
912
913static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier)
914{
915 struct redrat3_dev *rr3 = dev->priv;
916
917 rr3->carrier = carrier;
918
919 return carrier;
920}
921
922static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
923{
924 struct redrat3_dev *rr3 = rcdev->priv;
925 struct device *dev = rr3->dev;
926 struct redrat3_signal_header header;
927 int i, j, count, ret, ret_len, offset;
928 int lencheck, cur_sample_len, pipe;
929 char *buffer = NULL, *sigdata = NULL;
930 int *sample_lens = NULL;
931 u32 tmpi;
932 u16 tmps;
933 u8 *datap;
934 u8 curlencheck = 0;
935 u16 *lengths_ptr;
936 int sendbuf_len;
937
938 rr3_ftr(dev, "Entering %s\n", __func__);
939
940 if (rr3->transmitting) {
941 dev_warn(dev, "%s: transmitter already in use\n", __func__);
942 return -EAGAIN;
943 }
944
945 count = n / sizeof(int);
946 if (count > (RR3_DRIVER_MAXLENS * 2))
947 return -EINVAL;
948
949 rr3->transmitting = true;
950
951 redrat3_disable_detector(rr3);
952
953 if (rr3->det_enabled) {
954 dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__);
955 ret = -EIO;
956 goto out;
957 }
958
959 sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL);
960 if (!sample_lens) {
961 ret = -ENOMEM;
962 goto out;
963 }
964
965 for (i = 0; i < count; i++) {
966 for (lencheck = 0; lencheck < curlencheck; lencheck++) {
967 cur_sample_len = redrat3_us_to_len(txbuf[i]);
968 if (sample_lens[lencheck] == cur_sample_len)
969 break;
970 }
971 if (lencheck == curlencheck) {
972 cur_sample_len = redrat3_us_to_len(txbuf[i]);
973 rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n",
974 i, txbuf[i], curlencheck, cur_sample_len);
975 if (curlencheck < 255) {
976 /* now convert the value to a proper
977 * rr3 value.. */
978 sample_lens[curlencheck] = cur_sample_len;
979 curlencheck++;
980 } else {
981 dev_err(dev, "signal too long\n");
982 ret = -EINVAL;
983 goto out;
984 }
985 }
986 }
987
988 sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL);
989 if (!sigdata) {
990 ret = -ENOMEM;
991 goto out;
992 }
993
994 sigdata[count] = RR3_END_OF_SIGNAL;
995 sigdata[count + 1] = RR3_END_OF_SIGNAL;
996 for (i = 0; i < count; i++) {
997 for (j = 0; j < curlencheck; j++) {
998 if (sample_lens[j] == redrat3_us_to_len(txbuf[i]))
999 sigdata[i] = j;
1000 }
1001 }
1002
1003 offset = RR3_TX_HEADER_OFFSET;
1004 sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS)
1005 + count + RR3_TX_TRAILER_LEN + offset;
1006
1007 buffer = kzalloc(sendbuf_len, GFP_KERNEL);
1008 if (!buffer) {
1009 ret = -ENOMEM;
1010 goto out;
1011 }
1012
1013 /* fill in our packet header */
1014 header.length = sendbuf_len - offset;
1015 header.transfer_type = RR3_MOD_SIGNAL_OUT;
1016 header.pause = redrat3_len_to_us(100);
1017 header.mod_freq_count = mod_freq_to_val(rr3->carrier);
1018 header.no_periods = 0; /* n/a to transmit */
1019 header.max_lengths = RR3_DRIVER_MAXLENS;
1020 header.no_lengths = curlencheck;
1021 header.max_sig_size = RR3_MAX_SIG_SIZE;
1022 header.sig_size = count + RR3_TX_TRAILER_LEN;
1023 /* we currently rely on repeat handling in the IR encoding source */
1024 header.no_repeats = 0;
1025
1026 tmps = cpu_to_be16(header.length);
1027 memcpy(buffer, &tmps, 2);
1028
1029 tmps = cpu_to_be16(header.transfer_type);
1030 memcpy(buffer + 2, &tmps, 2);
1031
1032 tmpi = cpu_to_be32(header.pause);
1033 memcpy(buffer + offset, &tmpi, sizeof(tmpi));
1034
1035 tmps = cpu_to_be16(header.mod_freq_count);
1036 memcpy(buffer + offset + RR3_FREQ_COUNT_OFFSET, &tmps, 2);
1037
1038 buffer[offset + RR3_NUM_LENGTHS_OFFSET] = header.no_lengths;
1039
1040 tmps = cpu_to_be16(header.sig_size);
1041 memcpy(buffer + offset + RR3_NUM_SIGS_OFFSET, &tmps, 2);
1042
1043 buffer[offset + RR3_REPEATS_OFFSET] = header.no_repeats;
1044
1045 lengths_ptr = (u16 *)(buffer + offset + RR3_HEADER_LENGTH);
1046 for (i = 0; i < curlencheck; ++i)
1047 lengths_ptr[i] = cpu_to_be16(sample_lens[i]);
1048
1049 datap = (u8 *)(buffer + offset + RR3_HEADER_LENGTH +
1050 (sizeof(u16) * RR3_DRIVER_MAXLENS));
1051 memcpy(datap, sigdata, (count + RR3_TX_TRAILER_LEN));
1052
1053 if (debug) {
1054 redrat3_dump_signal_header(&header);
1055 redrat3_dump_signal_data(buffer, header.sig_size);
1056 }
1057
1058 pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress);
1059 tmps = usb_bulk_msg(rr3->udev, pipe, buffer,
1060 sendbuf_len, &ret_len, 10 * HZ);
1061 rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, tmps);
1062
1063 /* now tell the hardware to transmit what we sent it */
1064 pipe = usb_rcvctrlpipe(rr3->udev, 0);
1065 ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL,
1066 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
1067 0, 0, buffer, 2, HZ * 10);
1068
1069 if (ret < 0)
1070 dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
1071 else
1072 ret = n;
1073
1074out:
1075 kfree(sample_lens);
1076 kfree(buffer);
1077 kfree(sigdata);
1078
1079 rr3->transmitting = false;
1080
1081 redrat3_enable_detector(rr3);
1082
1083 return ret;
1084}
1085
1086static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
1087{
1088 struct device *dev = rr3->dev;
1089 struct rc_dev *rc;
1090 int ret = -ENODEV;
1091 u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);
1092
1093 rc = rc_allocate_device();
1094 if (!rc) {
1095 dev_err(dev, "remote input dev allocation failed\n");
1096 goto out;
1097 }
1098
1099 snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s "
1100 "Infrared Remote Transceiver (%04x:%04x)",
1101 prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "",
1102 le16_to_cpu(rr3->udev->descriptor.idVendor), prod);
1103
1104 usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys));
1105
1106 rc->input_name = rr3->name;
1107 rc->input_phys = rr3->phys;
1108 usb_to_input_id(rr3->udev, &rc->input_id);
1109 rc->dev.parent = dev;
1110 rc->priv = rr3;
1111 rc->driver_type = RC_DRIVER_IR_RAW;
1112 rc->allowed_protos = RC_TYPE_ALL;
1113 rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
1114 rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
1115 rc->timeout = redrat3_get_timeout(dev, rc, rr3->udev);
1116 rc->tx_ir = redrat3_transmit_ir;
1117 rc->s_tx_carrier = redrat3_set_tx_carrier;
1118 rc->driver_name = DRIVER_NAME;
1119 rc->map_name = RC_MAP_HAUPPAUGE;
1120
1121 ret = rc_register_device(rc);
1122 if (ret < 0) {
1123 dev_err(dev, "remote dev registration failed\n");
1124 goto out;
1125 }
1126
1127 return rc;
1128
1129out:
1130 rc_free_device(rc);
1131 return NULL;
1132}
1133
1134static int __devinit redrat3_dev_probe(struct usb_interface *intf,
1135 const struct usb_device_id *id)
1136{
1137 struct usb_device *udev = interface_to_usbdev(intf);
1138 struct device *dev = &intf->dev;
1139 struct usb_host_interface *uhi;
1140 struct redrat3_dev *rr3;
1141 struct usb_endpoint_descriptor *ep;
1142 struct usb_endpoint_descriptor *ep_in = NULL;
1143 struct usb_endpoint_descriptor *ep_out = NULL;
1144 u8 addr, attrs;
1145 int pipe, i;
1146 int retval = -ENOMEM;
1147
1148 rr3_ftr(dev, "%s called\n", __func__);
1149
1150 uhi = intf->cur_altsetting;
1151
1152 /* find our bulk-in and bulk-out endpoints */
1153 for (i = 0; i < uhi->desc.bNumEndpoints; ++i) {
1154 ep = &uhi->endpoint[i].desc;
1155 addr = ep->bEndpointAddress;
1156 attrs = ep->bmAttributes;
1157
1158 if ((ep_in == NULL) &&
1159 ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
1160 ((attrs & USB_ENDPOINT_XFERTYPE_MASK) ==
1161 USB_ENDPOINT_XFER_BULK)) {
1162 rr3_dbg(dev, "found bulk-in endpoint at 0x%02x\n",
1163 ep->bEndpointAddress);
1164 /* data comes in on 0x82, 0x81 is for other data... */
1165 if (ep->bEndpointAddress == RR3_BULK_IN_EP_ADDR)
1166 ep_in = ep;
1167 }
1168
1169 if ((ep_out == NULL) &&
1170 ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
1171 ((attrs & USB_ENDPOINT_XFERTYPE_MASK) ==
1172 USB_ENDPOINT_XFER_BULK)) {
1173 rr3_dbg(dev, "found bulk-out endpoint at 0x%02x\n",
1174 ep->bEndpointAddress);
1175 ep_out = ep;
1176 }
1177 }
1178
1179 if (!ep_in || !ep_out) {
1180 dev_err(dev, "Couldn't find both in and out endpoints\n");
1181 retval = -ENODEV;
1182 goto no_endpoints;
1183 }
1184
1185 /* allocate memory for our device state and initialize it */
1186 rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL);
1187 if (rr3 == NULL) {
1188 dev_err(dev, "Memory allocation failure\n");
1189 goto error;
1190 }
1191
1192 rr3->dev = &intf->dev;
1193
1194 /* set up bulk-in endpoint */
1195 rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL);
1196 if (!rr3->read_urb) {
1197 dev_err(dev, "Read urb allocation failure\n");
1198 goto error;
1199 }
1200
1201 rr3->ep_in = ep_in;
1202 rr3->bulk_in_buf = usb_alloc_coherent(udev, ep_in->wMaxPacketSize,
1203 GFP_ATOMIC, &rr3->dma_in);
1204 if (!rr3->bulk_in_buf) {
1205 dev_err(dev, "Read buffer allocation failure\n");
1206 goto error;
1207 }
1208
1209 pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress);
1210 usb_fill_bulk_urb(rr3->read_urb, udev, pipe,
1211 rr3->bulk_in_buf, ep_in->wMaxPacketSize,
1212 (usb_complete_t)redrat3_handle_async, rr3);
1213
1214 /* set up bulk-out endpoint*/
1215 rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL);
1216 if (!rr3->write_urb) {
1217 dev_err(dev, "Write urb allocation failure\n");
1218 goto error;
1219 }
1220
1221 rr3->ep_out = ep_out;
1222 rr3->bulk_out_buf = usb_alloc_coherent(udev, ep_out->wMaxPacketSize,
1223 GFP_ATOMIC, &rr3->dma_out);
1224 if (!rr3->bulk_out_buf) {
1225 dev_err(dev, "Write buffer allocation failure\n");
1226 goto error;
1227 }
1228
1229 pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress);
1230 usb_fill_bulk_urb(rr3->write_urb, udev, pipe,
1231 rr3->bulk_out_buf, ep_out->wMaxPacketSize,
1232 (usb_complete_t)redrat3_write_bulk_callback, rr3);
1233
1234 mutex_init(&rr3->lock);
1235 rr3->udev = udev;
1236
1237 redrat3_reset(rr3);
1238 redrat3_get_firmware_rev(rr3);
1239
1240 /* might be all we need to do? */
1241 retval = redrat3_enable_detector(rr3);
1242 if (retval < 0)
1243 goto error;
1244
1245 /* default.. will get overridden by any sends with a freq defined */
1246 rr3->carrier = 38000;
1247
1248 rr3->rc = redrat3_init_rc_dev(rr3);
1249 if (!rr3->rc)
1250 goto error;
1251
1252 setup_timer(&rr3->rx_timeout, redrat3_rx_timeout, (unsigned long)rr3);
1253
1254 /* we can register the device now, as it is ready */
1255 usb_set_intfdata(intf, rr3);
1256
1257 rr3_ftr(dev, "Exiting %s\n", __func__);
1258 return 0;
1259
1260error:
1261 redrat3_delete(rr3, rr3->udev);
1262
1263no_endpoints:
1264 dev_err(dev, "%s: retval = %x", __func__, retval);
1265
1266 return retval;
1267}
1268
1269static void __devexit redrat3_dev_disconnect(struct usb_interface *intf)
1270{
1271 struct usb_device *udev = interface_to_usbdev(intf);
1272 struct redrat3_dev *rr3 = usb_get_intfdata(intf);
1273
1274 rr3_ftr(&intf->dev, "Entering %s\n", __func__);
1275
1276 if (!rr3)
1277 return;
1278
1279 redrat3_disable_detector(rr3);
1280
1281 usb_set_intfdata(intf, NULL);
1282 rc_unregister_device(rr3->rc);
1283 redrat3_delete(rr3, udev);
1284
1285 rr3_ftr(&intf->dev, "RedRat3 IR Transceiver now disconnected\n");
1286}
1287
1288static int redrat3_dev_suspend(struct usb_interface *intf, pm_message_t message)
1289{
1290 struct redrat3_dev *rr3 = usb_get_intfdata(intf);
1291 rr3_ftr(rr3->dev, "suspend\n");
1292 usb_kill_urb(rr3->read_urb);
1293 return 0;
1294}
1295
1296static int redrat3_dev_resume(struct usb_interface *intf)
1297{
1298 struct redrat3_dev *rr3 = usb_get_intfdata(intf);
1299 rr3_ftr(rr3->dev, "resume\n");
1300 if (usb_submit_urb(rr3->read_urb, GFP_ATOMIC))
1301 return -EIO;
1302 return 0;
1303}
1304
1305static struct usb_driver redrat3_dev_driver = {
1306 .name = DRIVER_NAME,
1307 .probe = redrat3_dev_probe,
1308 .disconnect = redrat3_dev_disconnect,
1309 .suspend = redrat3_dev_suspend,
1310 .resume = redrat3_dev_resume,
1311 .reset_resume = redrat3_dev_resume,
1312 .id_table = redrat3_dev_table
1313};
1314
1315static int __init redrat3_dev_init(void)
1316{
1317 int ret;
1318
1319 ret = usb_register(&redrat3_dev_driver);
1320 if (ret < 0)
1321 pr_err(DRIVER_NAME
1322 ": usb register failed, result = %d\n", ret);
1323
1324 return ret;
1325}
1326
1327static void __exit redrat3_dev_exit(void)
1328{
1329 usb_deregister(&redrat3_dev_driver);
1330}
1331
1332module_init(redrat3_dev_init);
1333module_exit(redrat3_dev_exit);
1334
1335MODULE_DESCRIPTION(DRIVER_DESC);
1336MODULE_AUTHOR(DRIVER_AUTHOR);
1337MODULE_AUTHOR(DRIVER_AUTHOR2);
1338MODULE_LICENSE("GPL");
1339MODULE_DEVICE_TABLE(usb, redrat3_dev_table);
1340
1341module_param(debug, int, S_IRUGO | S_IWUSR);
1342MODULE_PARM_DESC(debug, "Enable module debug spew. 0 = no debugging (default) "
1343 "0x1 = standard debug messages, 0x2 = function tracing debug. "
1344 "Flag bits are addative (i.e., 0x3 for both debug types).");
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 186de5522001..5d06b899e859 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -19,11 +19,12 @@
19 * o DSDT dumps 19 * o DSDT dumps
20 * 20 *
21 * Supported features: 21 * Supported features:
22 * o IR Receive
23 * o IR Transmit
22 * o Wake-On-CIR functionality 24 * o Wake-On-CIR functionality
23 * 25 *
24 * To do: 26 * To do:
25 * o Learning 27 * o Learning
26 * o IR Transmit
27 * 28 *
28 * This program is free software; you can redistribute it and/or modify 29 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by 30 * it under the terms of the GNU General Public License as published by
@@ -50,6 +51,8 @@
50#include <linux/io.h> 51#include <linux/io.h>
51#include <linux/bitrev.h> 52#include <linux/bitrev.h>
52#include <linux/slab.h> 53#include <linux/slab.h>
54#include <linux/wait.h>
55#include <linux/sched.h>
53#include <media/rc-core.h> 56#include <media/rc-core.h>
54 57
55#define DRVNAME "winbond-cir" 58#define DRVNAME "winbond-cir"
@@ -118,14 +121,24 @@
118#define WBCIR_IRQ_NONE 0x00 121#define WBCIR_IRQ_NONE 0x00
119/* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 122/* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
120#define WBCIR_IRQ_RX 0x01 123#define WBCIR_IRQ_RX 0x01
124/* TX data low bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
125#define WBCIR_IRQ_TX_LOW 0x02
121/* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */ 126/* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
122#define WBCIR_IRQ_ERR 0x04 127#define WBCIR_IRQ_ERR 0x04
128/* TX data empty bit for WBCEIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
129#define WBCIR_IRQ_TX_EMPTY 0x20
123/* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */ 130/* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */
124#define WBCIR_LED_ENABLE 0x80 131#define WBCIR_LED_ENABLE 0x80
125/* RX data available bit for WBCIR_REG_SP3_LSR */ 132/* RX data available bit for WBCIR_REG_SP3_LSR */
126#define WBCIR_RX_AVAIL 0x01 133#define WBCIR_RX_AVAIL 0x01
134/* RX data overrun error bit for WBCIR_REG_SP3_LSR */
135#define WBCIR_RX_OVERRUN 0x02
136/* TX End-Of-Transmission bit for WBCIR_REG_SP3_ASCR */
137#define WBCIR_TX_EOT 0x04
127/* RX disable bit for WBCIR_REG_SP3_ASCR */ 138/* RX disable bit for WBCIR_REG_SP3_ASCR */
128#define WBCIR_RX_DISABLE 0x20 139#define WBCIR_RX_DISABLE 0x20
140/* TX data underrun error bit for WBCIR_REG_SP3_ASCR */
141#define WBCIR_TX_UNDERRUN 0x40
129/* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */ 142/* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */
130#define WBCIR_EXT_ENABLE 0x01 143#define WBCIR_EXT_ENABLE 0x01
131/* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */ 144/* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */
@@ -154,6 +167,21 @@ enum wbcir_protocol {
154 IR_PROTOCOL_RC6 = 0x2, 167 IR_PROTOCOL_RC6 = 0x2,
155}; 168};
156 169
170/* Possible states for IR reception */
171enum wbcir_rxstate {
172 WBCIR_RXSTATE_INACTIVE = 0,
173 WBCIR_RXSTATE_ACTIVE,
174 WBCIR_RXSTATE_ERROR
175};
176
177/* Possible states for IR transmission */
178enum wbcir_txstate {
179 WBCIR_TXSTATE_INACTIVE = 0,
180 WBCIR_TXSTATE_ACTIVE,
181 WBCIR_TXSTATE_DONE,
182 WBCIR_TXSTATE_ERROR
183};
184
157/* Misc */ 185/* Misc */
158#define WBCIR_NAME "Winbond CIR" 186#define WBCIR_NAME "Winbond CIR"
159#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */ 187#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */
@@ -166,22 +194,29 @@ enum wbcir_protocol {
166/* Per-device data */ 194/* Per-device data */
167struct wbcir_data { 195struct wbcir_data {
168 spinlock_t spinlock; 196 spinlock_t spinlock;
197 struct rc_dev *dev;
198 struct led_classdev led;
169 199
170 unsigned long wbase; /* Wake-Up Baseaddr */ 200 unsigned long wbase; /* Wake-Up Baseaddr */
171 unsigned long ebase; /* Enhanced Func. Baseaddr */ 201 unsigned long ebase; /* Enhanced Func. Baseaddr */
172 unsigned long sbase; /* Serial Port Baseaddr */ 202 unsigned long sbase; /* Serial Port Baseaddr */
173 unsigned int irq; /* Serial Port IRQ */ 203 unsigned int irq; /* Serial Port IRQ */
204 u8 irqmask;
174 205
175 struct rc_dev *dev; 206 /* RX state */
176 207 enum wbcir_rxstate rxstate;
177 struct led_trigger *rxtrigger; 208 struct led_trigger *rxtrigger;
178 struct led_trigger *txtrigger; 209 struct ir_raw_event rxev;
179 struct led_classdev led;
180 210
181 /* RX irdata state */ 211 /* TX state */
182 bool irdata_active; 212 enum wbcir_txstate txstate;
183 bool irdata_error; 213 struct led_trigger *txtrigger;
184 struct ir_raw_event ev; 214 u32 txlen;
215 u32 txoff;
216 u32 *txbuf;
217 wait_queue_head_t txwaitq;
218 u8 txmask;
219 u32 txcarrier;
185}; 220};
186 221
187static enum wbcir_protocol protocol = IR_PROTOCOL_RC6; 222static enum wbcir_protocol protocol = IR_PROTOCOL_RC6;
@@ -193,6 +228,10 @@ static int invert; /* default = 0 */
193module_param(invert, bool, 0444); 228module_param(invert, bool, 0444);
194MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); 229MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver");
195 230
231static int txandrx; /* default = 0 */
232module_param(txandrx, bool, 0444);
233MODULE_PARM_DESC(invert, "Allow simultaneous TX and RX");
234
196static unsigned int wake_sc = 0x800F040C; 235static unsigned int wake_sc = 0x800F040C;
197module_param(wake_sc, uint, 0644); 236module_param(wake_sc, uint, 0644);
198MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command"); 237MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command");
@@ -228,6 +267,17 @@ wbcir_select_bank(struct wbcir_data *data, enum wbcir_bank bank)
228 outb(bank, data->sbase + WBCIR_REG_SP3_BSR); 267 outb(bank, data->sbase + WBCIR_REG_SP3_BSR);
229} 268}
230 269
270static inline void
271wbcir_set_irqmask(struct wbcir_data *data, u8 irqmask)
272{
273 if (data->irqmask == irqmask)
274 return;
275
276 wbcir_select_bank(data, WBCIR_BANK_0);
277 outb(irqmask, data->sbase + WBCIR_REG_SP3_IER);
278 data->irqmask = irqmask;
279}
280
231static enum led_brightness 281static enum led_brightness
232wbcir_led_brightness_get(struct led_classdev *led_cdev) 282wbcir_led_brightness_get(struct led_classdev *led_cdev)
233{ 283{
@@ -279,97 +329,297 @@ wbcir_to_rc6cells(u8 val)
279 * 329 *
280 *****************************************************************************/ 330 *****************************************************************************/
281 331
332static void
333wbcir_idle_rx(struct rc_dev *dev, bool idle)
334{
335 struct wbcir_data *data = dev->priv;
336
337 if (!idle && data->rxstate == WBCIR_RXSTATE_INACTIVE) {
338 data->rxstate = WBCIR_RXSTATE_ACTIVE;
339 led_trigger_event(data->rxtrigger, LED_FULL);
340 }
341
342 if (idle && data->rxstate != WBCIR_RXSTATE_INACTIVE)
343 /* Tell hardware to go idle by setting RXINACTIVE */
344 outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
345}
346
347static void
348wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
349{
350 u8 irdata;
351 DEFINE_IR_RAW_EVENT(rawir);
352
353 /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
354 while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) {
355 irdata = inb(data->sbase + WBCIR_REG_SP3_RXDATA);
356 if (data->rxstate == WBCIR_RXSTATE_ERROR)
357 continue;
358 rawir.pulse = irdata & 0x80 ? false : true;
359 rawir.duration = US_TO_NS((irdata & 0x7F) * 10);
360 ir_raw_event_store_with_filter(data->dev, &rawir);
361 }
362
363 /* Check if we should go idle */
364 if (data->dev->idle) {
365 led_trigger_event(data->rxtrigger, LED_OFF);
366 data->rxstate = WBCIR_RXSTATE_INACTIVE;
367 }
368
369 ir_raw_event_handle(data->dev);
370}
371
372static void
373wbcir_irq_tx(struct wbcir_data *data)
374{
375 unsigned int space;
376 unsigned int used;
377 u8 bytes[16];
378 u8 byte;
379
380 if (!data->txbuf)
381 return;
382
383 switch (data->txstate) {
384 case WBCIR_TXSTATE_INACTIVE:
385 /* TX FIFO empty */
386 space = 16;
387 led_trigger_event(data->txtrigger, LED_FULL);
388 break;
389 case WBCIR_TXSTATE_ACTIVE:
390 /* TX FIFO low (3 bytes or less) */
391 space = 13;
392 break;
393 case WBCIR_TXSTATE_ERROR:
394 space = 0;
395 break;
396 default:
397 return;
398 }
399
400 /*
401 * TX data is run-length coded in bytes: YXXXXXXX
402 * Y = space (1) or pulse (0)
403 * X = duration, encoded as (X + 1) * 10us (i.e 10 to 1280 us)
404 */
405 for (used = 0; used < space && data->txoff != data->txlen; used++) {
406 if (data->txbuf[data->txoff] == 0) {
407 data->txoff++;
408 continue;
409 }
410 byte = min((u32)0x80, data->txbuf[data->txoff]);
411 data->txbuf[data->txoff] -= byte;
412 byte--;
413 byte |= (data->txoff % 2 ? 0x80 : 0x00); /* pulse/space */
414 bytes[used] = byte;
415 }
416
417 while (data->txbuf[data->txoff] == 0 && data->txoff != data->txlen)
418 data->txoff++;
419
420 if (used == 0) {
421 /* Finished */
422 if (data->txstate == WBCIR_TXSTATE_ERROR)
423 /* Clear TX underrun bit */
424 outb(WBCIR_TX_UNDERRUN, data->sbase + WBCIR_REG_SP3_ASCR);
425 else
426 data->txstate = WBCIR_TXSTATE_DONE;
427 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
428 led_trigger_event(data->txtrigger, LED_OFF);
429 wake_up(&data->txwaitq);
430 } else if (data->txoff == data->txlen) {
431 /* At the end of transmission, tell the hw before last byte */
432 outsb(data->sbase + WBCIR_REG_SP3_TXDATA, bytes, used - 1);
433 outb(WBCIR_TX_EOT, data->sbase + WBCIR_REG_SP3_ASCR);
434 outb(bytes[used - 1], data->sbase + WBCIR_REG_SP3_TXDATA);
435 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
436 WBCIR_IRQ_TX_EMPTY);
437 } else {
438 /* More data to follow... */
439 outsb(data->sbase + WBCIR_REG_SP3_RXDATA, bytes, used);
440 if (data->txstate == WBCIR_TXSTATE_INACTIVE) {
441 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
442 WBCIR_IRQ_TX_LOW);
443 data->txstate = WBCIR_TXSTATE_ACTIVE;
444 }
445 }
446}
447
282static irqreturn_t 448static irqreturn_t
283wbcir_irq_handler(int irqno, void *cookie) 449wbcir_irq_handler(int irqno, void *cookie)
284{ 450{
285 struct pnp_dev *device = cookie; 451 struct pnp_dev *device = cookie;
286 struct wbcir_data *data = pnp_get_drvdata(device); 452 struct wbcir_data *data = pnp_get_drvdata(device);
287 unsigned long flags; 453 unsigned long flags;
288 u8 irdata[8];
289 u8 disable = true;
290 u8 status; 454 u8 status;
291 int i;
292 455
293 spin_lock_irqsave(&data->spinlock, flags); 456 spin_lock_irqsave(&data->spinlock, flags);
294
295 wbcir_select_bank(data, WBCIR_BANK_0); 457 wbcir_select_bank(data, WBCIR_BANK_0);
296
297 status = inb(data->sbase + WBCIR_REG_SP3_EIR); 458 status = inb(data->sbase + WBCIR_REG_SP3_EIR);
459 status &= data->irqmask;
298 460
299 if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) { 461 if (!status) {
300 spin_unlock_irqrestore(&data->spinlock, flags); 462 spin_unlock_irqrestore(&data->spinlock, flags);
301 return IRQ_NONE; 463 return IRQ_NONE;
302 } 464 }
303 465
304 /* Check for e.g. buffer overflow */
305 if (status & WBCIR_IRQ_ERR) { 466 if (status & WBCIR_IRQ_ERR) {
306 data->irdata_error = true; 467 /* RX overflow? (read clears bit) */
307 ir_raw_event_reset(data->dev); 468 if (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_OVERRUN) {
308 } 469 data->rxstate = WBCIR_RXSTATE_ERROR;
309 470 ir_raw_event_reset(data->dev);
310 if (!(status & WBCIR_IRQ_RX)) 471 }
311 goto out;
312 472
313 if (!data->irdata_active) { 473 /* TX underflow? */
314 data->irdata_active = true; 474 if (inb(data->sbase + WBCIR_REG_SP3_ASCR) & WBCIR_TX_UNDERRUN)
315 led_trigger_event(data->rxtrigger, LED_FULL); 475 data->txstate = WBCIR_TXSTATE_ERROR;
316 } 476 }
317 477
318 /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ 478 if (status & WBCIR_IRQ_RX)
319 insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8); 479 wbcir_irq_rx(data, device);
320 480
321 for (i = 0; i < 8; i++) { 481 if (status & (WBCIR_IRQ_TX_LOW | WBCIR_IRQ_TX_EMPTY))
322 u8 pulse; 482 wbcir_irq_tx(data);
323 u32 duration;
324 483
325 if (irdata[i] != 0xFF && irdata[i] != 0x00) 484 spin_unlock_irqrestore(&data->spinlock, flags);
326 disable = false; 485 return IRQ_HANDLED;
327 486}
328 if (data->irdata_error)
329 continue;
330 487
331 pulse = irdata[i] & 0x80 ? false : true; 488/*****************************************************************************
332 duration = (irdata[i] & 0x7F) * 10000; /* ns */ 489 *
490 * RC-CORE INTERFACE FUNCTIONS
491 *
492 *****************************************************************************/
333 493
334 if (data->ev.pulse != pulse) { 494static int
335 if (data->ev.duration != 0) { 495wbcir_txcarrier(struct rc_dev *dev, u32 carrier)
336 ir_raw_event_store(data->dev, &data->ev); 496{
337 data->ev.duration = 0; 497 struct wbcir_data *data = dev->priv;
338 } 498 unsigned long flags;
499 u8 val;
500 u32 freq;
501
502 freq = DIV_ROUND_CLOSEST(carrier, 1000);
503 if (freq < 30 || freq > 60)
504 return -EINVAL;
505
506 switch (freq) {
507 case 58:
508 case 59:
509 case 60:
510 val = freq - 58;
511 freq *= 1000;
512 break;
513 case 57:
514 val = freq - 27;
515 freq = 56900;
516 break;
517 default:
518 val = freq - 27;
519 freq *= 1000;
520 break;
521 }
339 522
340 data->ev.pulse = pulse; 523 spin_lock_irqsave(&data->spinlock, flags);
341 } 524 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
525 spin_unlock_irqrestore(&data->spinlock, flags);
526 return -EBUSY;
527 }
342 528
343 data->ev.duration += duration; 529 if (data->txcarrier != freq) {
530 wbcir_select_bank(data, WBCIR_BANK_7);
531 wbcir_set_bits(data->sbase + WBCIR_REG_SP3_IRTXMC, val, 0x1F);
532 data->txcarrier = freq;
344 } 533 }
345 534
346 if (disable) { 535 spin_unlock_irqrestore(&data->spinlock, flags);
347 if (data->ev.duration != 0 && !data->irdata_error) { 536 return 0;
348 ir_raw_event_store(data->dev, &data->ev); 537}
349 data->ev.duration = 0;
350 }
351 538
352 /* Set RXINACTIVE */ 539static int
353 outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR); 540wbcir_txmask(struct rc_dev *dev, u32 mask)
541{
542 struct wbcir_data *data = dev->priv;
543 unsigned long flags;
544 u8 val;
354 545
355 /* Drain the FIFO */ 546 /* Four outputs, only one output can be enabled at a time */
356 while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) 547 switch (mask) {
357 inb(data->sbase + WBCIR_REG_SP3_RXDATA); 548 case 0x1:
549 val = 0x0;
550 break;
551 case 0x2:
552 val = 0x1;
553 break;
554 case 0x4:
555 val = 0x2;
556 break;
557 case 0x8:
558 val = 0x3;
559 break;
560 default:
561 return -EINVAL;
562 }
358 563
359 ir_raw_event_reset(data->dev); 564 spin_lock_irqsave(&data->spinlock, flags);
360 data->irdata_error = false; 565 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
361 data->irdata_active = false; 566 spin_unlock_irqrestore(&data->spinlock, flags);
362 led_trigger_event(data->rxtrigger, LED_OFF); 567 return -EBUSY;
363 } 568 }
364 569
365 ir_raw_event_handle(data->dev); 570 if (data->txmask != mask) {
571 wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, val, 0x0c);
572 data->txmask = mask;
573 }
366 574
367out:
368 spin_unlock_irqrestore(&data->spinlock, flags); 575 spin_unlock_irqrestore(&data->spinlock, flags);
369 return IRQ_HANDLED; 576 return 0;
370} 577}
371 578
579static int
580wbcir_tx(struct rc_dev *dev, int *buf, u32 bufsize)
581{
582 struct wbcir_data *data = dev->priv;
583 u32 count;
584 unsigned i;
585 unsigned long flags;
586
587 /* bufsize has been sanity checked by the caller */
588 count = bufsize / sizeof(int);
372 589
590 /* Not sure if this is possible, but better safe than sorry */
591 spin_lock_irqsave(&data->spinlock, flags);
592 if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
593 spin_unlock_irqrestore(&data->spinlock, flags);
594 return -EBUSY;
595 }
596
597 /* Convert values to multiples of 10us */
598 for (i = 0; i < count; i++)
599 buf[i] = DIV_ROUND_CLOSEST(buf[i], 10);
600
601 /* Fill the TX fifo once, the irq handler will do the rest */
602 data->txbuf = buf;
603 data->txlen = count;
604 data->txoff = 0;
605 wbcir_irq_tx(data);
606
607 /* Wait for the TX to complete */
608 while (data->txstate == WBCIR_TXSTATE_ACTIVE) {
609 spin_unlock_irqrestore(&data->spinlock, flags);
610 wait_event(data->txwaitq, data->txstate != WBCIR_TXSTATE_ACTIVE);
611 spin_lock_irqsave(&data->spinlock, flags);
612 }
613
614 /* We're done */
615 if (data->txstate == WBCIR_TXSTATE_ERROR)
616 count = -EAGAIN;
617 data->txstate = WBCIR_TXSTATE_INACTIVE;
618 data->txbuf = NULL;
619 spin_unlock_irqrestore(&data->spinlock, flags);
620
621 return count;
622}
373 623
374/***************************************************************************** 624/*****************************************************************************
375 * 625 *
@@ -382,7 +632,7 @@ wbcir_shutdown(struct pnp_dev *device)
382{ 632{
383 struct device *dev = &device->dev; 633 struct device *dev = &device->dev;
384 struct wbcir_data *data = pnp_get_drvdata(device); 634 struct wbcir_data *data = pnp_get_drvdata(device);
385 int do_wake = 1; 635 bool do_wake = true;
386 u8 match[11]; 636 u8 match[11];
387 u8 mask[11]; 637 u8 mask[11];
388 u8 rc6_csl = 0; 638 u8 rc6_csl = 0;
@@ -392,14 +642,14 @@ wbcir_shutdown(struct pnp_dev *device)
392 memset(mask, 0, sizeof(mask)); 642 memset(mask, 0, sizeof(mask));
393 643
394 if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) { 644 if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) {
395 do_wake = 0; 645 do_wake = false;
396 goto finish; 646 goto finish;
397 } 647 }
398 648
399 switch (protocol) { 649 switch (protocol) {
400 case IR_PROTOCOL_RC5: 650 case IR_PROTOCOL_RC5:
401 if (wake_sc > 0xFFF) { 651 if (wake_sc > 0xFFF) {
402 do_wake = 0; 652 do_wake = false;
403 dev_err(dev, "RC5 - Invalid wake scancode\n"); 653 dev_err(dev, "RC5 - Invalid wake scancode\n");
404 break; 654 break;
405 } 655 }
@@ -418,7 +668,7 @@ wbcir_shutdown(struct pnp_dev *device)
418 668
419 case IR_PROTOCOL_NEC: 669 case IR_PROTOCOL_NEC:
420 if (wake_sc > 0xFFFFFF) { 670 if (wake_sc > 0xFFFFFF) {
421 do_wake = 0; 671 do_wake = false;
422 dev_err(dev, "NEC - Invalid wake scancode\n"); 672 dev_err(dev, "NEC - Invalid wake scancode\n");
423 break; 673 break;
424 } 674 }
@@ -440,7 +690,7 @@ wbcir_shutdown(struct pnp_dev *device)
440 690
441 if (wake_rc6mode == 0) { 691 if (wake_rc6mode == 0) {
442 if (wake_sc > 0xFFFF) { 692 if (wake_sc > 0xFFFF) {
443 do_wake = 0; 693 do_wake = false;
444 dev_err(dev, "RC6 - Invalid wake scancode\n"); 694 dev_err(dev, "RC6 - Invalid wake scancode\n");
445 break; 695 break;
446 } 696 }
@@ -496,7 +746,7 @@ wbcir_shutdown(struct pnp_dev *device)
496 } else if (wake_sc <= 0x007FFFFF) { 746 } else if (wake_sc <= 0x007FFFFF) {
497 rc6_csl = 60; 747 rc6_csl = 60;
498 } else { 748 } else {
499 do_wake = 0; 749 do_wake = false;
500 dev_err(dev, "RC6 - Invalid wake scancode\n"); 750 dev_err(dev, "RC6 - Invalid wake scancode\n");
501 break; 751 break;
502 } 752 }
@@ -508,14 +758,14 @@ wbcir_shutdown(struct pnp_dev *device)
508 mask[i++] = 0x0F; 758 mask[i++] = 0x0F;
509 759
510 } else { 760 } else {
511 do_wake = 0; 761 do_wake = false;
512 dev_err(dev, "RC6 - Invalid wake mode\n"); 762 dev_err(dev, "RC6 - Invalid wake mode\n");
513 } 763 }
514 764
515 break; 765 break;
516 766
517 default: 767 default:
518 do_wake = 0; 768 do_wake = false;
519 break; 769 break;
520 } 770 }
521 771
@@ -551,21 +801,18 @@ finish:
551 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01); 801 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
552 } 802 }
553 803
554 /* Disable interrupts */
555 wbcir_select_bank(data, WBCIR_BANK_0);
556 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
557
558 /* Disable LED */
559 data->irdata_active = false;
560 led_trigger_event(data->rxtrigger, LED_OFF);
561
562 /* 804 /*
563 * ACPI will set the HW disable bit for SP3 which means that the 805 * ACPI will set the HW disable bit for SP3 which means that the
564 * output signals are left in an undefined state which may cause 806 * output signals are left in an undefined state which may cause
565 * spurious interrupts which we need to ignore until the hardware 807 * spurious interrupts which we need to ignore until the hardware
566 * is reinitialized. 808 * is reinitialized.
567 */ 809 */
810 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
568 disable_irq(data->irq); 811 disable_irq(data->irq);
812
813 /* Disable LED */
814 led_trigger_event(data->rxtrigger, LED_OFF);
815 led_trigger_event(data->txtrigger, LED_OFF);
569} 816}
570 817
571static int 818static int
@@ -581,8 +828,7 @@ wbcir_init_hw(struct wbcir_data *data)
581 u8 tmp; 828 u8 tmp;
582 829
583 /* Disable interrupts */ 830 /* Disable interrupts */
584 wbcir_select_bank(data, WBCIR_BANK_0); 831 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
585 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
586 832
587 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ 833 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
588 tmp = protocol << 4; 834 tmp = protocol << 4;
@@ -606,10 +852,11 @@ wbcir_init_hw(struct wbcir_data *data)
606 outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL); 852 outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL);
607 853
608 /* 854 /*
609 * Clear IR LED, set SP3 clock to 24Mhz 855 * Clear IR LED, set SP3 clock to 24Mhz, set TX mask to IRTX1,
610 * set SP3_IRRX_SW to binary 01, helpfully not documented 856 * set SP3_IRRX_SW to binary 01, helpfully not documented
611 */ 857 */
612 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); 858 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
859 data->txmask = 0x1;
613 860
614 /* Enable extended mode */ 861 /* Enable extended mode */
615 wbcir_select_bank(data, WBCIR_BANK_2); 862 wbcir_select_bank(data, WBCIR_BANK_2);
@@ -657,18 +904,21 @@ wbcir_init_hw(struct wbcir_data *data)
657 wbcir_select_bank(data, WBCIR_BANK_4); 904 wbcir_select_bank(data, WBCIR_BANK_4);
658 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1); 905 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
659 906
660 /* Enable MSR interrupt, Clear AUX_IRX */ 907 /* Disable MSR interrupt, clear AUX_IRX, mask RX during TX? */
661 wbcir_select_bank(data, WBCIR_BANK_5); 908 wbcir_select_bank(data, WBCIR_BANK_5);
662 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2); 909 outb(txandrx ? 0x03 : 0x02, data->sbase + WBCIR_REG_SP3_IRCR2);
663 910
664 /* Disable CRC */ 911 /* Disable CRC */
665 wbcir_select_bank(data, WBCIR_BANK_6); 912 wbcir_select_bank(data, WBCIR_BANK_6);
666 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3); 913 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
667 914
668 /* Set RX/TX (de)modulation freq, not really used */ 915 /* Set RX demodulation freq, not really used */
669 wbcir_select_bank(data, WBCIR_BANK_7); 916 wbcir_select_bank(data, WBCIR_BANK_7);
670 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC); 917 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
918
919 /* Set TX modulation, 36kHz, 7us pulse width */
671 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC); 920 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
921 data->txcarrier = 36000;
672 922
673 /* Set invert and pin direction */ 923 /* Set invert and pin direction */
674 if (invert) 924 if (invert)
@@ -683,16 +933,23 @@ wbcir_init_hw(struct wbcir_data *data)
683 /* Clear AUX status bits */ 933 /* Clear AUX status bits */
684 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR); 934 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
685 935
686 /* Clear IR decoding state */ 936 /* Clear RX state */
687 data->irdata_active = false; 937 data->rxstate = WBCIR_RXSTATE_INACTIVE;
688 led_trigger_event(data->rxtrigger, LED_OFF); 938 data->rxev.duration = 0;
689 data->irdata_error = false;
690 data->ev.duration = 0;
691 ir_raw_event_reset(data->dev); 939 ir_raw_event_reset(data->dev);
692 ir_raw_event_handle(data->dev); 940 ir_raw_event_handle(data->dev);
693 941
942 /*
943 * Check TX state, if we did a suspend/resume cycle while TX was
944 * active, we will have a process waiting in txwaitq.
945 */
946 if (data->txstate == WBCIR_TXSTATE_ACTIVE) {
947 data->txstate = WBCIR_TXSTATE_ERROR;
948 wake_up(&data->txwaitq);
949 }
950
694 /* Enable interrupts */ 951 /* Enable interrupts */
695 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER); 952 wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
696} 953}
697 954
698static int 955static int
@@ -729,6 +986,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
729 pnp_set_drvdata(device, data); 986 pnp_set_drvdata(device, data);
730 987
731 spin_lock_init(&data->spinlock); 988 spin_lock_init(&data->spinlock);
989 init_waitqueue_head(&data->txwaitq);
732 data->ebase = pnp_port_start(device, 0); 990 data->ebase = pnp_port_start(device, 0);
733 data->wbase = pnp_port_start(device, 1); 991 data->wbase = pnp_port_start(device, 1);
734 data->sbase = pnp_port_start(device, 2); 992 data->sbase = pnp_port_start(device, 2);
@@ -807,6 +1065,11 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
807 data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND; 1065 data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND;
808 data->dev->input_id.product = WBCIR_ID_FAMILY; 1066 data->dev->input_id.product = WBCIR_ID_FAMILY;
809 data->dev->input_id.version = WBCIR_ID_CHIP; 1067 data->dev->input_id.version = WBCIR_ID_CHIP;
1068 data->dev->map_name = RC_MAP_RC6_MCE;
1069 data->dev->s_idle = wbcir_idle_rx;
1070 data->dev->s_tx_mask = wbcir_txmask;
1071 data->dev->s_tx_carrier = wbcir_txcarrier;
1072 data->dev->tx_ir = wbcir_tx;
810 data->dev->priv = data; 1073 data->dev->priv = data;
811 data->dev->dev.parent = &device->dev; 1074 data->dev->dev.parent = &device->dev;
812 1075
@@ -849,9 +1112,7 @@ wbcir_remove(struct pnp_dev *device)
849 struct wbcir_data *data = pnp_get_drvdata(device); 1112 struct wbcir_data *data = pnp_get_drvdata(device);
850 1113
851 /* Disable interrupts */ 1114 /* Disable interrupts */
852 wbcir_select_bank(data, WBCIR_BANK_0); 1115 wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
853 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
854
855 free_irq(data->irq, device); 1116 free_irq(data->irq, device);
856 1117
857 /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */ 1118 /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 00f51dd121f3..3be180b3ba27 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -128,10 +128,10 @@ config VIDEO_IR_I2C
128# Encoder / Decoder module configuration 128# Encoder / Decoder module configuration
129# 129#
130 130
131menu "Encoders/decoders and other helper chips" 131menu "Encoders, decoders, sensors and other helper chips"
132 visible if !VIDEO_HELPER_CHIPS_AUTO 132 visible if !VIDEO_HELPER_CHIPS_AUTO
133 133
134comment "Audio decoders" 134comment "Audio decoders, processors and mixers"
135 135
136config VIDEO_TVAUDIO 136config VIDEO_TVAUDIO
137 tristate "Simple audio decoder chips" 137 tristate "Simple audio decoder chips"
@@ -210,15 +210,6 @@ config VIDEO_CS53L32A
210 To compile this driver as a module, choose M here: the 210 To compile this driver as a module, choose M here: the
211 module will be called cs53l32a. 211 module will be called cs53l32a.
212 212
213config VIDEO_M52790
214 tristate "Mitsubishi M52790 A/V switch"
215 depends on VIDEO_V4L2 && I2C
216 ---help---
217 Support for the Mitsubishi M52790 A/V switch.
218
219 To compile this driver as a module, choose M here: the
220 module will be called m52790.
221
222config VIDEO_TLV320AIC23B 213config VIDEO_TLV320AIC23B
223 tristate "Texas Instruments TLV320AIC23B audio codec" 214 tristate "Texas Instruments TLV320AIC23B audio codec"
224 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 215 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
@@ -321,29 +312,6 @@ config VIDEO_KS0127
321 To compile this driver as a module, choose M here: the 312 To compile this driver as a module, choose M here: the
322 module will be called ks0127. 313 module will be called ks0127.
323 314
324config VIDEO_OV7670
325 tristate "OmniVision OV7670 sensor support"
326 depends on I2C && VIDEO_V4L2
327 ---help---
328 This is a Video4Linux2 sensor-level driver for the OmniVision
329 OV7670 VGA camera. It currently only works with the M88ALP01
330 controller.
331
332config VIDEO_MT9V011
333 tristate "Micron mt9v011 sensor support"
334 depends on I2C && VIDEO_V4L2
335 ---help---
336 This is a Video4Linux2 sensor-level driver for the Micron
337 mt0v011 1.3 Mpixel camera. It currently only works with the
338 em28xx driver.
339
340config VIDEO_TCM825X
341 tristate "TCM825x camera sensor support"
342 depends on I2C && VIDEO_V4L2
343 ---help---
344 This is a driver for the Toshiba TCM825x VGA camera sensor.
345 It is used for example in Nokia N800.
346
347config VIDEO_SAA7110 315config VIDEO_SAA7110
348 tristate "Philips SAA7110 video decoder" 316 tristate "Philips SAA7110 video decoder"
349 depends on VIDEO_V4L2 && I2C 317 depends on VIDEO_V4L2 && I2C
@@ -362,15 +330,6 @@ config VIDEO_SAA711X
362 To compile this driver as a module, choose M here: the 330 To compile this driver as a module, choose M here: the
363 module will be called saa7115. 331 module will be called saa7115.
364 332
365config VIDEO_SAA717X
366 tristate "Philips SAA7171/3/4 audio/video decoders"
367 depends on VIDEO_V4L2 && I2C
368 ---help---
369 Support for the Philips SAA7171/3/4 audio/video decoders.
370
371 To compile this driver as a module, choose M here: the
372 module will be called saa717x.
373
374config VIDEO_SAA7191 333config VIDEO_SAA7191
375 tristate "Philips SAA7191 video decoder" 334 tristate "Philips SAA7191 video decoder"
376 depends on VIDEO_V4L2 && I2C 335 depends on VIDEO_V4L2 && I2C
@@ -420,6 +379,15 @@ config VIDEO_VPX3220
420 379
421comment "Video and audio decoders" 380comment "Video and audio decoders"
422 381
382config VIDEO_SAA717X
383 tristate "Philips SAA7171/3/4 audio/video decoders"
384 depends on VIDEO_V4L2 && I2C
385 ---help---
386 Support for the Philips SAA7171/3/4 audio/video decoders.
387
388 To compile this driver as a module, choose M here: the
389 module will be called saa717x.
390
423source "drivers/media/video/cx25840/Kconfig" 391source "drivers/media/video/cx25840/Kconfig"
424 392
425comment "MPEG video encoders" 393comment "MPEG video encoders"
@@ -474,15 +442,6 @@ config VIDEO_ADV7175
474 To compile this driver as a module, choose M here: the 442 To compile this driver as a module, choose M here: the
475 module will be called adv7175. 443 module will be called adv7175.
476 444
477config VIDEO_THS7303
478 tristate "THS7303 Video Amplifier"
479 depends on I2C
480 help
481 Support for TI THS7303 video amplifier
482
483 To compile this driver as a module, choose M here: the
484 module will be called ths7303.
485
486config VIDEO_ADV7343 445config VIDEO_ADV7343
487 tristate "ADV7343 video encoder" 446 tristate "ADV7343 video encoder"
488 depends on I2C 447 depends on I2C
@@ -498,6 +457,38 @@ config VIDEO_AK881X
498 help 457 help
499 Video output driver for AKM AK8813 and AK8814 TV encoders 458 Video output driver for AKM AK8813 and AK8814 TV encoders
500 459
460comment "Camera sensor devices"
461
462config VIDEO_OV7670
463 tristate "OmniVision OV7670 sensor support"
464 depends on I2C && VIDEO_V4L2
465 ---help---
466 This is a Video4Linux2 sensor-level driver for the OmniVision
467 OV7670 VGA camera. It currently only works with the M88ALP01
468 controller.
469
470config VIDEO_MT9V011
471 tristate "Micron mt9v011 sensor support"
472 depends on I2C && VIDEO_V4L2
473 ---help---
474 This is a Video4Linux2 sensor-level driver for the Micron
475 mt0v011 1.3 Mpixel camera. It currently only works with the
476 em28xx driver.
477
478config VIDEO_MT9V032
479 tristate "Micron MT9V032 sensor support"
480 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
481 ---help---
482 This is a Video4Linux2 sensor-level driver for the Micron
483 MT9V032 752x480 CMOS sensor.
484
485config VIDEO_TCM825X
486 tristate "TCM825x camera sensor support"
487 depends on I2C && VIDEO_V4L2
488 ---help---
489 This is a driver for the Toshiba TCM825x VGA camera sensor.
490 It is used for example in Nokia N800.
491
501comment "Video improvement chips" 492comment "Video improvement chips"
502 493
503config VIDEO_UPD64031A 494config VIDEO_UPD64031A
@@ -523,6 +514,26 @@ config VIDEO_UPD64083
523 To compile this driver as a module, choose M here: the 514 To compile this driver as a module, choose M here: the
524 module will be called upd64083. 515 module will be called upd64083.
525 516
517comment "Miscelaneous helper chips"
518
519config VIDEO_THS7303
520 tristate "THS7303 Video Amplifier"
521 depends on I2C
522 help
523 Support for TI THS7303 video amplifier
524
525 To compile this driver as a module, choose M here: the
526 module will be called ths7303.
527
528config VIDEO_M52790
529 tristate "Mitsubishi M52790 A/V switch"
530 depends on VIDEO_V4L2 && I2C
531 ---help---
532 Support for the Mitsubishi M52790 A/V switch.
533
534 To compile this driver as a module, choose M here: the
535 module will be called m52790.
536
526endmenu # encoder / decoder chips 537endmenu # encoder / decoder chips
527 538
528config VIDEO_SH_VOU 539config VIDEO_SH_VOU
@@ -682,7 +693,7 @@ config VIDEO_TIMBERDALE
682 select VIDEO_ADV7180 693 select VIDEO_ADV7180
683 select VIDEOBUF_DMA_CONTIG 694 select VIDEOBUF_DMA_CONTIG
684 ---help--- 695 ---help---
685 Add support for the Video In peripherial of the timberdale FPGA. 696 Add support for the Video In peripherial of the timberdale FPGA.
686 697
687source "drivers/media/video/cx88/Kconfig" 698source "drivers/media/video/cx88/Kconfig"
688 699
@@ -916,7 +927,7 @@ config VIDEO_OMAP2
916 This is a v4l2 driver for the TI OMAP2 camera capture interface 927 This is a v4l2 driver for the TI OMAP2 camera capture interface
917 928
918config VIDEO_MX2_HOSTSUPPORT 929config VIDEO_MX2_HOSTSUPPORT
919 bool 930 bool
920 931
921config VIDEO_MX2 932config VIDEO_MX2
922 tristate "i.MX27/i.MX25 Camera Sensor Interface driver" 933 tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
@@ -927,6 +938,26 @@ config VIDEO_MX2
927 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor 938 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
928 Interface 939 Interface
929 940
941config VIDEO_SAMSUNG_S5P_FIMC
942 tristate "Samsung S5P and EXYNOS4 camera host interface driver"
943 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
944 select VIDEOBUF2_DMA_CONTIG
945 select V4L2_MEM2MEM_DEV
946 ---help---
947 This is a v4l2 driver for Samsung S5P and EXYNOS4 camera
948 host interface and video postprocessor.
949
950 To compile this driver as a module, choose M here: the
951 module will be called s5p-fimc.
952
953config VIDEO_S5P_MIPI_CSIS
954 tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver"
955 depends on VIDEO_V4L2 && PM_RUNTIME && VIDEO_V4L2_SUBDEV_API
956 ---help---
957 This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver.
958
959 To compile this driver as a module, choose M here: the
960 module will be called s5p-csis.
930 961
931# 962#
932# USB Multimedia device configuration 963# USB Multimedia device configuration
@@ -983,7 +1014,7 @@ config USB_STKWEBCAM
983 Supported devices are typically found in some Asus laptops, 1014 Supported devices are typically found in some Asus laptops,
984 with USB id 174f:a311 and 05e1:0501. Other Syntek cameras 1015 with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
985 may be supported by the stk11xx driver, from which this is 1016 may be supported by the stk11xx driver, from which this is
986 derived, see <http://sourceforge.net/projects/syntekdriver/> 1017 derived, see <http://sourceforge.net/projects/syntekdriver/>
987 1018
988 To compile this driver as a module, choose M here: the 1019 To compile this driver as a module, choose M here: the
989 module will be called stkwebcam. 1020 module will be called stkwebcam.
@@ -1022,13 +1053,5 @@ config VIDEO_MEM2MEM_TESTDEV
1022 This is a virtual test device for the memory-to-memory driver 1053 This is a virtual test device for the memory-to-memory driver
1023 framework. 1054 framework.
1024 1055
1025config VIDEO_SAMSUNG_S5P_FIMC
1026 tristate "Samsung S5P FIMC (video postprocessor) driver"
1027 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
1028 select VIDEOBUF2_DMA_CONTIG
1029 select V4L2_MEM2MEM_DEV
1030 help
1031 This is a v4l2 driver for the S5P camera interface
1032 (video postprocessor)
1033 1056
1034endif # V4L_MEM2MEM_DRIVERS 1057endif # V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index ace5d8b57221..9519160c2e01 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o 66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o 68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
69obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
69obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 70obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
70obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 71obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
71 72
@@ -164,6 +165,7 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
164obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o 165obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
165obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 166obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
166obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o 167obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
168
167obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ 169obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
168 170
169obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 171obj-$(CONFIG_ARCH_DAVINCI) += davinci/
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 91399c94cd18..a97cf2750bd9 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4303,7 +4303,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4303 goto fail0; 4303 goto fail0;
4304 } 4304 }
4305 4305
4306 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); 4306 btv->revision = dev->revision;
4307 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 4307 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
4308 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", 4308 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
4309 bttv_num,btv->id, btv->revision, pci_name(dev)); 4309 bttv_num,btv->id, btv->revision, pci_name(dev));
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 5111bbcefad5..0073a8c55336 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1313,7 +1313,7 @@ static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p)
1313static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio) 1313static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
1314{ 1314{
1315 struct camera_data *cam = video_drvdata(file); 1315 struct camera_data *cam = video_drvdata(file);
1316 struct cpia2_fh *fh = fh; 1316 struct cpia2_fh *fh = _fh;
1317 1317
1318 if (cam->streaming && prio != fh->prio && 1318 if (cam->streaming && prio != fh->prio &&
1319 fh->prio == V4L2_PRIORITY_RECORD) 1319 fh->prio == V4L2_PRIORITY_RECORD)
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index d9d2f6ad6ffb..53b3c7702573 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_CX18
2 tristate "Conexant cx23418 MPEG encoder support" 2 tristate "Conexant cx23418 MPEG encoder support"
3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL 3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select VIDEOBUF_VMALLOC
5 depends on RC_CORE 6 depends on RC_CORE
6 select VIDEO_TUNER 7 select VIDEO_TUNER
7 select VIDEO_TVEEPROM 8 select VIDEO_TVEEPROM
@@ -9,6 +10,9 @@ config VIDEO_CX18
9 select VIDEO_CS5345 10 select VIDEO_CS5345
10 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 11 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
11 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 12 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
13 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
14 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
15 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
12 ---help--- 16 ---help---
13 This is a video4linux driver for Conexant cx23418 based 17 This is a video4linux driver for Conexant cx23418 based
14 PCI combo video recorder devices. 18 PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 68ad1963f421..c07c849b1aaf 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -39,6 +39,16 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
39 .tv = { 0x61, 0x60, I2C_CLIENT_END }, 39 .tv = { 0x61, 0x60, I2C_CLIENT_END },
40}; 40};
41 41
42/*
43 * usual i2c tuner addresses to probe with additional demod address for
44 * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
45 */
46static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
47 .radio = { I2C_CLIENT_END },
48 .demod = { 0x42, 0x43, I2C_CLIENT_END },
49 .tv = { 0x61, 0x60, I2C_CLIENT_END },
50};
51
42/* Please add new PCI IDs to: http://pci-ids.ucw.cz/ 52/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
43 This keeps the PCI ID database up to date. Note that the entries 53 This keeps the PCI ID database up to date. Note that the entries
44 must be added under vendor 0x4444 (Conexant) as subsystem IDs. 54 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
@@ -131,15 +141,15 @@ static const struct cx18_card cx18_card_hvr1600_s5h1411 = {
131 .tune_lane = 0, 141 .tune_lane = 0,
132 .initial_emrs = 0, 142 .initial_emrs = 0,
133 }, 143 },
134 .gpio_init.initial_value = 0x3001, 144 .gpio_init.initial_value = 0x3801,
135 .gpio_init.direction = 0x3001, 145 .gpio_init.direction = 0x3801,
136 .gpio_i2c_slave_reset = { 146 .gpio_i2c_slave_reset = {
137 .active_lo_mask = 0x3001, 147 .active_lo_mask = 0x3801,
138 .msecs_asserted = 10, 148 .msecs_asserted = 10,
139 .msecs_recovery = 40, 149 .msecs_recovery = 40,
140 .ir_reset_mask = 0x0001, 150 .ir_reset_mask = 0x0001,
141 }, 151 },
142 .i2c = &cx18_i2c_std, 152 .i2c = &cx18_i2c_nxp,
143}; 153};
144 154
145static const struct cx18_card cx18_card_hvr1600_samsung = { 155static const struct cx18_card cx18_card_hvr1600_samsung = {
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 3e750068f275..add7391ecaba 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -109,7 +109,7 @@ struct cx18_card_tuner {
109 109
110struct cx18_card_tuner_i2c { 110struct cx18_card_tuner_i2c {
111 unsigned short radio[2];/* radio tuner i2c address to probe */ 111 unsigned short radio[2];/* radio tuner i2c address to probe */
112 unsigned short demod[2];/* demodulator i2c address to probe */ 112 unsigned short demod[3];/* demodulator i2c address to probe */
113 unsigned short tv[4]; /* tv tuner i2c addresses to probe */ 113 unsigned short tv[4]; /* tv tuner i2c addresses to probe */
114}; 114};
115 115
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 321c1b79794c..9e2f870f4258 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -423,7 +423,16 @@ static void cx18_process_eeprom(struct cx18 *cx)
423 return; 423 return;
424 424
425 /* autodetect tuner standard */ 425 /* autodetect tuner standard */
426 if (tv.tuner_formats & V4L2_STD_PAL) { 426#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
427 V4L2_STD_MN | \
428 V4L2_STD_PAL_I | \
429 V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
430 V4L2_STD_DK)
431 if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
432 == TVEEPROM_TUNER_FORMAT_ALL) {
433 CX18_DEBUG_INFO("Worldwide tuner detected\n");
434 cx->std = V4L2_STD_ALL;
435 } else if (tv.tuner_formats & V4L2_STD_PAL) {
427 CX18_DEBUG_INFO("PAL tuner detected\n"); 436 CX18_DEBUG_INFO("PAL tuner detected\n");
428 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; 437 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
429 } else if (tv.tuner_formats & V4L2_STD_NTSC) { 438 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
@@ -818,7 +827,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
818 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 827 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
819 pci_write_config_word(pci_dev, PCI_COMMAND, cmd); 828 pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
820 829
821 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev); 830 cx->card_rev = pci_dev->revision;
822 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); 831 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
823 832
824 if (pci_latency < 64 && cx18_pci_latency) { 833 if (pci_latency < 64 && cx18_pci_latency) {
@@ -1001,7 +1010,15 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1001 if (cx->card->hw_all & CX18_HW_TVEEPROM) { 1010 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
1002 /* Based on the model number the cardtype may be changed. 1011 /* Based on the model number the cardtype may be changed.
1003 The PCI IDs are not always reliable. */ 1012 The PCI IDs are not always reliable. */
1013 const struct cx18_card *orig_card = cx->card;
1004 cx18_process_eeprom(cx); 1014 cx18_process_eeprom(cx);
1015
1016 if (cx->card != orig_card) {
1017 /* Changed the cardtype; re-reset the I2C chips */
1018 cx18_gpio_init(cx);
1019 cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
1020 core, reset, (u32) CX18_GPIO_RESET_I2C);
1021 }
1005 } 1022 }
1006 if (cx->card->comment) 1023 if (cx->card->comment)
1007 CX18_INFO("%s", cx->card->comment); 1024 CX18_INFO("%s", cx->card->comment);
@@ -1087,6 +1104,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1087 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) 1104 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
1088 are not. */ 1105 are not. */
1089 cx->tuner_std = cx->std; 1106 cx->tuner_std = cx->std;
1107 if (cx->std == V4L2_STD_ALL)
1108 cx->std = V4L2_STD_NTSC_M;
1090 1109
1091 retval = cx18_streams_setup(cx); 1110 retval = cx18_streams_setup(cx);
1092 if (retval) { 1111 if (retval) {
@@ -1133,6 +1152,7 @@ int cx18_init_on_first_open(struct cx18 *cx)
1133 int fw_retry_count = 3; 1152 int fw_retry_count = 3;
1134 struct v4l2_frequency vf; 1153 struct v4l2_frequency vf;
1135 struct cx18_open_id fh; 1154 struct cx18_open_id fh;
1155 v4l2_std_id std;
1136 1156
1137 fh.cx = cx; 1157 fh.cx = cx;
1138 1158
@@ -1220,7 +1240,8 @@ int cx18_init_on_first_open(struct cx18 *cx)
1220 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code 1240 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
1221 in one place. */ 1241 in one place. */
1222 cx->std++; /* Force full standard initialization */ 1242 cx->std++; /* Force full standard initialization */
1223 cx18_s_std(NULL, &fh, &cx->tuner_std); 1243 std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
1244 cx18_s_std(NULL, &fh, &std);
1224 cx18_s_frequency(NULL, &fh, &vf); 1245 cx18_s_frequency(NULL, &fh, &vf);
1225 return 0; 1246 return 0;
1226} 1247}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index b86a740c68df..086427288de8 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -65,6 +65,10 @@
65#include "dvb_net.h" 65#include "dvb_net.h"
66#include "dvbdev.h" 66#include "dvbdev.h"
67 67
68/* Videobuf / YUV support */
69#include <media/videobuf-core.h>
70#include <media/videobuf-vmalloc.h>
71
68#ifndef CONFIG_PCI 72#ifndef CONFIG_PCI
69# error "This driver requires kernel PCI support." 73# error "This driver requires kernel PCI support."
70#endif 74#endif
@@ -403,6 +407,23 @@ struct cx18_stream {
403 struct cx18_queue q_idle; /* idle - not in rotation */ 407 struct cx18_queue q_idle; /* idle - not in rotation */
404 408
405 struct work_struct out_work_order; 409 struct work_struct out_work_order;
410
411 /* Videobuf for YUV video */
412 u32 pixelformat;
413 struct list_head vb_capture; /* video capture queue */
414 spinlock_t vb_lock;
415 struct timer_list vb_timeout;
416
417 struct videobuf_queue vbuf_q;
418 spinlock_t vbuf_q_lock; /* Protect vbuf_q */
419 enum v4l2_buf_type vb_type;
420};
421
422struct cx18_videobuf_buffer {
423 /* Common video buffer sub-system struct */
424 struct videobuf_buffer vb;
425 v4l2_std_id tvnorm; /* selected tv norm */
426 u32 bytes_used;
406}; 427};
407 428
408struct cx18_open_id { 429struct cx18_open_id {
@@ -410,6 +431,10 @@ struct cx18_open_id {
410 u32 open_id; 431 u32 open_id;
411 int type; 432 int type;
412 struct cx18 *cx; 433 struct cx18 *cx;
434
435 struct videobuf_queue vbuf_q;
436 spinlock_t s_lock; /* Protect vbuf_q */
437 enum v4l2_buf_type vb_type;
413}; 438};
414 439
415static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh) 440static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index e9802d99439b..07411f34885a 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -597,6 +597,13 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
597 mutex_unlock(&cx->serialize_lock); 597 mutex_unlock(&cx->serialize_lock);
598 if (rc) 598 if (rc)
599 return rc; 599 return rc;
600
601 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
602 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
603 return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
604 filp->f_flags & O_NONBLOCK);
605 }
606
600 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); 607 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
601} 608}
602 609
@@ -622,6 +629,15 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
622 CX18_DEBUG_FILE("Encoder poll started capture\n"); 629 CX18_DEBUG_FILE("Encoder poll started capture\n");
623 } 630 }
624 631
632 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
633 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
634 int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
635 if (eof && videobuf_poll == POLLERR)
636 return POLLHUP;
637 else
638 return videobuf_poll;
639 }
640
625 /* add stream's waitq to the poll list */ 641 /* add stream's waitq to the poll list */
626 CX18_DEBUG_HI_FILE("Encoder poll\n"); 642 CX18_DEBUG_HI_FILE("Encoder poll\n");
627 poll_wait(filp, &s->waitq, wait); 643 poll_wait(filp, &s->waitq, wait);
@@ -633,6 +649,58 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
633 return 0; 649 return 0;
634} 650}
635 651
652int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
653{
654 struct cx18_open_id *id = file->private_data;
655 struct cx18 *cx = id->cx;
656 struct cx18_stream *s = &cx->streams[id->type];
657 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
658
659 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
660 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
661
662 /* Start a capture if there is none */
663 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
664 int rc;
665
666 mutex_lock(&cx->serialize_lock);
667 rc = cx18_start_capture(id);
668 mutex_unlock(&cx->serialize_lock);
669 if (rc) {
670 CX18_DEBUG_INFO(
671 "Could not start capture for %s (%d)\n",
672 s->name, rc);
673 return -EINVAL;
674 }
675 CX18_DEBUG_FILE("Encoder mmap started capture\n");
676 }
677
678 return videobuf_mmap_mapper(&s->vbuf_q, vma);
679 }
680
681 return -EINVAL;
682}
683
684void cx18_vb_timeout(unsigned long data)
685{
686 struct cx18_stream *s = (struct cx18_stream *)data;
687 struct cx18_videobuf_buffer *buf;
688 unsigned long flags;
689
690 /* Return all of the buffers in error state, so the vbi/vid inode
691 * can return from blocking.
692 */
693 spin_lock_irqsave(&s->vb_lock, flags);
694 while (!list_empty(&s->vb_capture)) {
695 buf = list_entry(s->vb_capture.next,
696 struct cx18_videobuf_buffer, vb.queue);
697 list_del(&buf->vb.queue);
698 buf->vb.state = VIDEOBUF_ERROR;
699 wake_up(&buf->vb.done);
700 }
701 spin_unlock_irqrestore(&s->vb_lock, flags);
702}
703
636void cx18_stop_capture(struct cx18_open_id *id, int gop_end) 704void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
637{ 705{
638 struct cx18 *cx = id->cx; 706 struct cx18 *cx = id->cx;
@@ -716,6 +784,8 @@ int cx18_v4l2_close(struct file *filp)
716 cx18_release_stream(s); 784 cx18_release_stream(s);
717 } else { 785 } else {
718 cx18_stop_capture(id, 0); 786 cx18_stop_capture(id, 0);
787 if (id->type == CX18_ENC_STREAM_TYPE_YUV)
788 videobuf_mmap_free(&id->vbuf_q);
719 } 789 }
720 kfree(id); 790 kfree(id);
721 mutex_unlock(&cx->serialize_lock); 791 mutex_unlock(&cx->serialize_lock);
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 5c8fcb884f0a..b9e5110ad043 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -33,6 +33,8 @@ int cx18_start_capture(struct cx18_open_id *id);
33void cx18_stop_capture(struct cx18_open_id *id, int gop_end); 33void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx); 34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx); 35void cx18_unmute(struct cx18 *cx);
36int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
37void cx18_vb_timeout(unsigned long data);
36 38
37/* Shared with cx18-alsa module */ 39/* Shared with cx18-alsa module */
38int cx18_claim_stream(struct cx18_open_id *id, int type); 40int cx18_claim_stream(struct cx18_open_id *id, int type);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 4f041c033c54..1933d4d11bf2 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -150,6 +150,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
150{ 150{
151 struct cx18_open_id *id = fh2id(fh); 151 struct cx18_open_id *id = fh2id(fh);
152 struct cx18 *cx = id->cx; 152 struct cx18 *cx = id->cx;
153 struct cx18_stream *s = &cx->streams[id->type];
153 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 154 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
154 155
155 pixfmt->width = cx->cxhdl.width; 156 pixfmt->width = cx->cxhdl.width;
@@ -158,9 +159,13 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
158 pixfmt->field = V4L2_FIELD_INTERLACED; 159 pixfmt->field = V4L2_FIELD_INTERLACED;
159 pixfmt->priv = 0; 160 pixfmt->priv = 0;
160 if (id->type == CX18_ENC_STREAM_TYPE_YUV) { 161 if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
161 pixfmt->pixelformat = V4L2_PIX_FMT_HM12; 162 pixfmt->pixelformat = s->pixelformat;
162 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ 163 /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
163 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; 164 UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
165 if (s->pixelformat == V4L2_PIX_FMT_HM12)
166 pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
167 else
168 pixfmt->sizeimage = pixfmt->height * 720 * 2;
164 pixfmt->bytesperline = 720; 169 pixfmt->bytesperline = 720;
165 } else { 170 } else {
166 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; 171 pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -237,7 +242,6 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
237 h = min(h, cx->is_50hz ? 576 : 480); 242 h = min(h, cx->is_50hz ? 576 : 480);
238 h = max(h, min_h); 243 h = max(h, min_h);
239 244
240 cx18_g_fmt_vid_cap(file, fh, fmt);
241 fmt->fmt.pix.width = w; 245 fmt->fmt.pix.width = w;
242 fmt->fmt.pix.height = h; 246 fmt->fmt.pix.height = h;
243 return 0; 247 return 0;
@@ -274,6 +278,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
274 struct cx18_open_id *id = fh2id(fh); 278 struct cx18_open_id *id = fh2id(fh);
275 struct cx18 *cx = id->cx; 279 struct cx18 *cx = id->cx;
276 struct v4l2_mbus_framefmt mbus_fmt; 280 struct v4l2_mbus_framefmt mbus_fmt;
281 struct cx18_stream *s = &cx->streams[id->type];
277 int ret; 282 int ret;
278 int w, h; 283 int w, h;
279 284
@@ -283,12 +288,15 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
283 w = fmt->fmt.pix.width; 288 w = fmt->fmt.pix.width;
284 h = fmt->fmt.pix.height; 289 h = fmt->fmt.pix.height;
285 290
286 if (cx->cxhdl.width == w && cx->cxhdl.height == h) 291 if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
292 s->pixelformat == fmt->fmt.pix.pixelformat)
287 return 0; 293 return 0;
288 294
289 if (atomic_read(&cx->ana_capturing) > 0) 295 if (atomic_read(&cx->ana_capturing) > 0)
290 return -EBUSY; 296 return -EBUSY;
291 297
298 s->pixelformat = fmt->fmt.pix.pixelformat;
299
292 mbus_fmt.width = cx->cxhdl.width = w; 300 mbus_fmt.width = cx->cxhdl.width = w;
293 mbus_fmt.height = cx->cxhdl.height = h; 301 mbus_fmt.height = cx->cxhdl.height = h;
294 mbus_fmt.code = V4L2_MBUS_FMT_FIXED; 302 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
@@ -540,16 +548,19 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
540static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, 548static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
541 struct v4l2_fmtdesc *fmt) 549 struct v4l2_fmtdesc *fmt)
542{ 550{
543 static struct v4l2_fmtdesc formats[] = { 551 static const struct v4l2_fmtdesc formats[] = {
544 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0, 552 { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
545 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 } 553 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
546 }, 554 },
547 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED, 555 { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
548 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 } 556 "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
549 } 557 },
558 { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
559 "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
560 },
550 }; 561 };
551 562
552 if (fmt->index > 1) 563 if (fmt->index > ARRAY_SIZE(formats) - 1)
553 return -EINVAL; 564 return -EINVAL;
554 *fmt = formats[fmt->index]; 565 *fmt = formats[fmt->index];
555 return 0; 566 return 0;
@@ -863,6 +874,117 @@ static int cx18_g_enc_index(struct file *file, void *fh,
863 return 0; 874 return 0;
864} 875}
865 876
877static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
878{
879 struct videobuf_queue *q = NULL;
880 struct cx18 *cx = id->cx;
881 struct cx18_stream *s = &cx->streams[id->type];
882
883 switch (s->vb_type) {
884 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
885 q = &s->vbuf_q;
886 break;
887 case V4L2_BUF_TYPE_VBI_CAPTURE:
888 break;
889 default:
890 break;
891 }
892 return q;
893}
894
895static int cx18_streamon(struct file *file, void *priv,
896 enum v4l2_buf_type type)
897{
898 struct cx18_open_id *id = file->private_data;
899 struct cx18 *cx = id->cx;
900 struct cx18_stream *s = &cx->streams[id->type];
901
902 /* Start the hardware only if we're the video device */
903 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
904 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
905 return -EINVAL;
906
907 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
908 return -EINVAL;
909
910 /* Establish a buffer timeout */
911 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
912
913 return videobuf_streamon(cx18_vb_queue(id));
914}
915
916static int cx18_streamoff(struct file *file, void *priv,
917 enum v4l2_buf_type type)
918{
919 struct cx18_open_id *id = file->private_data;
920 struct cx18 *cx = id->cx;
921 struct cx18_stream *s = &cx->streams[id->type];
922
923 /* Start the hardware only if we're the video device */
924 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
925 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
926 return -EINVAL;
927
928 if (id->type != CX18_ENC_STREAM_TYPE_YUV)
929 return -EINVAL;
930
931 return videobuf_streamoff(cx18_vb_queue(id));
932}
933
934static int cx18_reqbufs(struct file *file, void *priv,
935 struct v4l2_requestbuffers *rb)
936{
937 struct cx18_open_id *id = file->private_data;
938 struct cx18 *cx = id->cx;
939 struct cx18_stream *s = &cx->streams[id->type];
940
941 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
942 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
943 return -EINVAL;
944
945 return videobuf_reqbufs(cx18_vb_queue(id), rb);
946}
947
948static int cx18_querybuf(struct file *file, void *priv,
949 struct v4l2_buffer *b)
950{
951 struct cx18_open_id *id = file->private_data;
952 struct cx18 *cx = id->cx;
953 struct cx18_stream *s = &cx->streams[id->type];
954
955 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
956 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
957 return -EINVAL;
958
959 return videobuf_querybuf(cx18_vb_queue(id), b);
960}
961
962static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
963{
964 struct cx18_open_id *id = file->private_data;
965 struct cx18 *cx = id->cx;
966 struct cx18_stream *s = &cx->streams[id->type];
967
968 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
969 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
970 return -EINVAL;
971
972 return videobuf_qbuf(cx18_vb_queue(id), b);
973}
974
975static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
976{
977 struct cx18_open_id *id = file->private_data;
978 struct cx18 *cx = id->cx;
979 struct cx18_stream *s = &cx->streams[id->type];
980
981 if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
982 (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
983 return -EINVAL;
984
985 return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
986}
987
866static int cx18_encoder_cmd(struct file *file, void *fh, 988static int cx18_encoder_cmd(struct file *file, void *fh,
867 struct v4l2_encoder_cmd *enc) 989 struct v4l2_encoder_cmd *enc)
868{ 990{
@@ -1081,6 +1203,12 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1081 .vidioc_s_register = cx18_s_register, 1203 .vidioc_s_register = cx18_s_register,
1082#endif 1204#endif
1083 .vidioc_default = cx18_default, 1205 .vidioc_default = cx18_default,
1206 .vidioc_streamon = cx18_streamon,
1207 .vidioc_streamoff = cx18_streamoff,
1208 .vidioc_reqbufs = cx18_reqbufs,
1209 .vidioc_querybuf = cx18_querybuf,
1210 .vidioc_qbuf = cx18_qbuf,
1211 .vidioc_dqbuf = cx18_dqbuf,
1084}; 1212};
1085 1213
1086void cx18_set_funcs(struct video_device *vdev) 1214void cx18_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 9605d54bd083..c07191e09fcb 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = {
81 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), 81 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
82 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), 82 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
83 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), 83 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
84 API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0),
84 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), 85 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
85 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), 86 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
86 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), 87 API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
@@ -158,6 +159,60 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
158 } 159 }
159} 160}
160 161
162static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
163 struct cx18_mdl *mdl)
164{
165 struct cx18_videobuf_buffer *vb_buf;
166 struct cx18_buffer *buf;
167 u8 *p;
168 u32 offset = 0;
169 int dispatch = 0;
170
171 if (mdl->bytesused == 0)
172 return;
173
174 /* Acquire a videobuf buffer, clone to and and release it */
175 spin_lock(&s->vb_lock);
176 if (list_empty(&s->vb_capture))
177 goto out;
178
179 vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer,
180 vb.queue);
181
182 p = videobuf_to_vmalloc(&vb_buf->vb);
183 if (!p)
184 goto out;
185
186 offset = vb_buf->bytes_used;
187 list_for_each_entry(buf, &mdl->buf_list, list) {
188 if (buf->bytesused == 0)
189 break;
190
191 if ((offset + buf->bytesused) <= vb_buf->vb.bsize) {
192 memcpy(p + offset, buf->buf, buf->bytesused);
193 offset += buf->bytesused;
194 vb_buf->bytes_used += buf->bytesused;
195 }
196 }
197
198 /* If we've filled the buffer as per the callers res then dispatch it */
199 if (vb_buf->bytes_used >= (vb_buf->vb.width * vb_buf->vb.height * 2)) {
200 dispatch = 1;
201 vb_buf->bytes_used = 0;
202 }
203
204 if (dispatch) {
205 vb_buf->vb.ts = ktime_to_timeval(ktime_get());
206 list_del(&vb_buf->vb.queue);
207 vb_buf->vb.state = VIDEOBUF_DONE;
208 wake_up(&vb_buf->vb.done);
209 }
210
211 mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
212
213out:
214 spin_unlock(&s->vb_lock);
215}
161 216
162static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, 217static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
163 struct cx18_mdl *mdl) 218 struct cx18_mdl *mdl)
@@ -263,6 +318,9 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
263 } else { 318 } else {
264 cx18_enqueue(s, mdl, &s->q_full); 319 cx18_enqueue(s, mdl, &s->q_full);
265 } 320 }
321 } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) {
322 cx18_mdl_send_to_videobuf(s, mdl);
323 cx18_enqueue(s, mdl, &s->q_free);
266 } else { 324 } else {
267 cx18_enqueue(s, mdl, &s->q_full); 325 cx18_enqueue(s, mdl, &s->q_full);
268 if (s->type == CX18_ENC_STREAM_TYPE_IDX) 326 if (s->type == CX18_ENC_STREAM_TYPE_IDX)
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 6fbc356113c1..852f420fd271 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -44,6 +44,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
44 .unlocked_ioctl = cx18_v4l2_ioctl, 44 .unlocked_ioctl = cx18_v4l2_ioctl,
45 .release = cx18_v4l2_close, 45 .release = cx18_v4l2_close,
46 .poll = cx18_v4l2_enc_poll, 46 .poll = cx18_v4l2_enc_poll,
47 .mmap = cx18_v4l2_mmap,
47}; 48};
48 49
49/* offset from 0 to register ts v4l2 minors on */ 50/* offset from 0 to register ts v4l2 minors on */
@@ -97,6 +98,141 @@ static struct {
97 }, 98 },
98}; 99};
99 100
101
102void cx18_dma_free(struct videobuf_queue *q,
103 struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
104{
105 videobuf_waiton(q, &buf->vb, 0, 0);
106 videobuf_vmalloc_free(&buf->vb);
107 buf->vb.state = VIDEOBUF_NEEDS_INIT;
108}
109
110static int cx18_prepare_buffer(struct videobuf_queue *q,
111 struct cx18_stream *s,
112 struct cx18_videobuf_buffer *buf,
113 u32 pixelformat,
114 unsigned int width, unsigned int height,
115 enum v4l2_field field)
116{
117 struct cx18 *cx = s->cx;
118 int rc = 0;
119
120 /* check settings */
121 buf->bytes_used = 0;
122
123 if ((width < 48) || (height < 32))
124 return -EINVAL;
125
126 buf->vb.size = (width * height * 2);
127 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
128 return -EINVAL;
129
130 /* alloc + fill struct (if changed) */
131 if (buf->vb.width != width || buf->vb.height != height ||
132 buf->vb.field != field || s->pixelformat != pixelformat ||
133 buf->tvnorm != cx->std) {
134
135 buf->vb.width = width;
136 buf->vb.height = height;
137 buf->vb.field = field;
138 buf->tvnorm = cx->std;
139 s->pixelformat = pixelformat;
140
141 cx18_dma_free(q, s, buf);
142 }
143
144 if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
145 return -EINVAL;
146
147 if (buf->vb.field == 0)
148 buf->vb.field = V4L2_FIELD_INTERLACED;
149
150 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
151 buf->vb.width = width;
152 buf->vb.height = height;
153 buf->vb.field = field;
154 buf->tvnorm = cx->std;
155 s->pixelformat = pixelformat;
156
157 rc = videobuf_iolock(q, &buf->vb, NULL);
158 if (rc != 0)
159 goto fail;
160 }
161 buf->vb.state = VIDEOBUF_PREPARED;
162 return 0;
163
164fail:
165 cx18_dma_free(q, s, buf);
166 return rc;
167
168}
169
170/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
171 1440 is a single line of 4:2:2 YUV at 720 luma samples wide
172*/
173#define VB_MIN_BUFFERS 32
174#define VB_MIN_BUFSIZE 4147200
175
176static int buffer_setup(struct videobuf_queue *q,
177 unsigned int *count, unsigned int *size)
178{
179 struct cx18_stream *s = q->priv_data;
180 struct cx18 *cx = s->cx;
181
182 *size = 2 * cx->cxhdl.width * cx->cxhdl.height;
183 if (*count == 0)
184 *count = VB_MIN_BUFFERS;
185
186 while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
187 (*count)--;
188
189 q->field = V4L2_FIELD_INTERLACED;
190 q->last = V4L2_FIELD_INTERLACED;
191
192 return 0;
193}
194
195static int buffer_prepare(struct videobuf_queue *q,
196 struct videobuf_buffer *vb,
197 enum v4l2_field field)
198{
199 struct cx18_videobuf_buffer *buf =
200 container_of(vb, struct cx18_videobuf_buffer, vb);
201 struct cx18_stream *s = q->priv_data;
202 struct cx18 *cx = s->cx;
203
204 return cx18_prepare_buffer(q, s, buf, s->pixelformat,
205 cx->cxhdl.width, cx->cxhdl.height, field);
206}
207
208static void buffer_release(struct videobuf_queue *q,
209 struct videobuf_buffer *vb)
210{
211 struct cx18_videobuf_buffer *buf =
212 container_of(vb, struct cx18_videobuf_buffer, vb);
213 struct cx18_stream *s = q->priv_data;
214
215 cx18_dma_free(q, s, buf);
216}
217
218static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
219{
220 struct cx18_videobuf_buffer *buf =
221 container_of(vb, struct cx18_videobuf_buffer, vb);
222 struct cx18_stream *s = q->priv_data;
223
224 buf->vb.state = VIDEOBUF_QUEUED;
225
226 list_add_tail(&buf->vb.queue, &s->vb_capture);
227}
228
229static struct videobuf_queue_ops cx18_videobuf_qops = {
230 .buf_setup = buffer_setup,
231 .buf_prepare = buffer_prepare,
232 .buf_queue = buffer_queue,
233 .buf_release = buffer_release,
234};
235
100static void cx18_stream_init(struct cx18 *cx, int type) 236static void cx18_stream_init(struct cx18 *cx, int type)
101{ 237{
102 struct cx18_stream *s = &cx->streams[type]; 238 struct cx18_stream *s = &cx->streams[type];
@@ -132,6 +268,26 @@ static void cx18_stream_init(struct cx18 *cx, int type)
132 cx18_queue_init(&s->q_idle); 268 cx18_queue_init(&s->q_idle);
133 269
134 INIT_WORK(&s->out_work_order, cx18_out_work_handler); 270 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
271
272 INIT_LIST_HEAD(&s->vb_capture);
273 s->vb_timeout.function = cx18_vb_timeout;
274 s->vb_timeout.data = (unsigned long)s;
275 init_timer(&s->vb_timeout);
276 spin_lock_init(&s->vb_lock);
277 if (type == CX18_ENC_STREAM_TYPE_YUV) {
278 spin_lock_init(&s->vbuf_q_lock);
279
280 s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
281 videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
282 &cx->pci_dev->dev, &s->vbuf_q_lock,
283 V4L2_BUF_TYPE_VIDEO_CAPTURE,
284 V4L2_FIELD_INTERLACED,
285 sizeof(struct cx18_videobuf_buffer),
286 s, &cx->serialize_lock);
287
288 /* Assume the previous pixel default */
289 s->pixelformat = V4L2_PIX_FMT_HM12;
290 }
135} 291}
136 292
137static int cx18_prep_dev(struct cx18 *cx, int type) 293static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -372,6 +528,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
372 if (vdev == NULL) 528 if (vdev == NULL)
373 continue; 529 continue;
374 530
531 if (type == CX18_ENC_STREAM_TYPE_YUV)
532 videobuf_mmap_free(&cx->streams[type].vbuf_q);
533
375 cx18_stream_free(&cx->streams[type]); 534 cx18_stream_free(&cx->streams[type]);
376 535
377 /* Unregister or release device */ 536 /* Unregister or release device */
@@ -581,7 +740,10 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
581 * Set the MDL size to the exact size needed for one frame. 740 * Set the MDL size to the exact size needed for one frame.
582 * Use enough buffers per MDL to cover the MDL size 741 * Use enough buffers per MDL to cover the MDL size
583 */ 742 */
584 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2; 743 if (s->pixelformat == V4L2_PIX_FMT_HM12)
744 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
745 else
746 s->mdl_size = 720 * s->cx->cxhdl.height * 2;
585 s->bufs_per_mdl = s->mdl_size / s->buf_size; 747 s->bufs_per_mdl = s->mdl_size / s->buf_size;
586 if (s->mdl_size % s->buf_size) 748 if (s->mdl_size % s->buf_size)
587 s->bufs_per_mdl++; 749 s->bufs_per_mdl++;
@@ -729,6 +891,19 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
729 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) 891 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
730 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 892 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
731 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1); 893 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
894
895 /* Enable the Video Format Converter for UYVY 4:2:2 support,
896 * rather than the default HM12 Macroblovk 4:2:0 support.
897 */
898 if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
899 if (s->pixelformat == V4L2_PIX_FMT_UYVY)
900 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
901 s->handle, 1);
902 else
903 /* If in doubt, default to HM12 */
904 cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
905 s->handle, 0);
906 }
732 } 907 }
733 908
734 if (atomic_read(&cx->tot_capturing) == 0) { 909 if (atomic_read(&cx->tot_capturing) == 0) {
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 3e1aec4bcfde..cd189b6bbe20 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,7 +24,7 @@
24 24
25#define CX18_DRIVER_NAME "cx18" 25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1 26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 4 27#define CX18_DRIVER_VERSION_MINOR 5
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0 28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29 29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) 30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 935f557acbd0..767a8d23e3f2 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -342,6 +342,12 @@
342 ReturnCode */ 342 ReturnCode */
343#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022) 343#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
344 344
345/* Description: Set VFC parameters
346 IN[0] - task handle
347 IN[1] - VFC enable flag, 1 - enable, 0 - disable
348*/
349#define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023)
350
345/* Below is the list of commands related to the data exchange */ 351/* Below is the list of commands related to the data exchange */
346#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000) 352#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
347 353
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index f49230d170e6..22703815a31f 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -401,6 +401,44 @@ struct cx231xx_board cx231xx_boards[] = {
401 .gpio = NULL, 401 .gpio = NULL,
402 } }, 402 } },
403 }, 403 },
404 [CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = {
405 .name = "Kworld UB430 USB Hybrid",
406 .tuner_type = TUNER_NXP_TDA18271,
407 .tuner_addr = 0x60,
408 .decoder = CX231XX_AVDECODER,
409 .output_mode = OUT_MODE_VIP11,
410 .demod_xfer_mode = 0,
411 .ctl_pin_status_mask = 0xFFFFFFC4,
412 .agc_analog_digital_select_gpio = 0x11, /* According with PV cxPolaris.inf file */
413 .tuner_sif_gpio = -1,
414 .tuner_scl_gpio = -1,
415 .tuner_sda_gpio = -1,
416 .gpio_pin_status_mask = 0x4001000,
417 .tuner_i2c_master = 2,
418 .demod_i2c_master = 1,
419 .ir_i2c_master = 2,
420 .has_dvb = 1,
421 .demod_addr = 0x10,
422 .norm = V4L2_STD_PAL_M,
423 .input = {{
424 .type = CX231XX_VMUX_TELEVISION,
425 .vmux = CX231XX_VIN_3_1,
426 .amux = CX231XX_AMUX_VIDEO,
427 .gpio = NULL,
428 }, {
429 .type = CX231XX_VMUX_COMPOSITE1,
430 .vmux = CX231XX_VIN_2_1,
431 .amux = CX231XX_AMUX_LINE_IN,
432 .gpio = NULL,
433 }, {
434 .type = CX231XX_VMUX_SVIDEO,
435 .vmux = CX231XX_VIN_1_1 |
436 (CX231XX_VIN_1_2 << 8) |
437 CX25840_SVIDEO_ON,
438 .amux = CX231XX_AMUX_LINE_IN,
439 .gpio = NULL,
440 } },
441 },
404 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { 442 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
405 .name = "Pixelview PlayTV USB Hybrid", 443 .name = "Pixelview PlayTV USB Hybrid",
406 .tuner_type = TUNER_NXP_TDA18271, 444 .tuner_type = TUNER_NXP_TDA18271,
@@ -469,6 +507,31 @@ struct cx231xx_board cx231xx_boards[] = {
469 } 507 }
470 }, 508 },
471 }, 509 },
510
511 [CX231XX_BOARD_ICONBIT_U100] = {
512 .name = "Iconbit Analog Stick U100 FM",
513 .tuner_type = TUNER_ABSENT,
514 .decoder = CX231XX_AVDECODER,
515 .output_mode = OUT_MODE_VIP11,
516 .demod_xfer_mode = 0,
517 .ctl_pin_status_mask = 0xFFFFFFC4,
518 .agc_analog_digital_select_gpio = 0x1C,
519 .gpio_pin_status_mask = 0x4001000,
520
521 .input = {{
522 .type = CX231XX_VMUX_COMPOSITE1,
523 .vmux = CX231XX_VIN_2_1,
524 .amux = CX231XX_AMUX_LINE_IN,
525 .gpio = NULL,
526 }, {
527 .type = CX231XX_VMUX_SVIDEO,
528 .vmux = CX231XX_VIN_1_1 |
529 (CX231XX_VIN_1_2 << 8) |
530 CX25840_SVIDEO_ON,
531 .amux = CX231XX_AMUX_LINE_IN,
532 .gpio = NULL,
533 } },
534 },
472}; 535};
473const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); 536const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
474 537
@@ -500,6 +563,10 @@ struct usb_device_id cx231xx_id_table[] = {
500 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, 563 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
501 {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014), 564 {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
502 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, 565 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
566 {USB_DEVICE(0x1b80, 0xe424),
567 .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID},
568 {USB_DEVICE(0x1f4d, 0x0237),
569 .driver_info = CX231XX_BOARD_ICONBIT_U100},
503 {}, 570 {},
504}; 571};
505 572
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index 363aa6004221..da9a4a0aab79 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -704,6 +704,7 @@ static int dvb_init(struct cx231xx *dev)
704 break; 704 break;
705 705
706 case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: 706 case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
707 case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
707 708
708 printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n", 709 printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
709 __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); 710 __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index bd4a9cf29577..46dd84067816 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -65,6 +65,8 @@
65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10 66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
67#define CX231XX_BOARD_PV_XCAPTURE_USB 11 67#define CX231XX_BOARD_PV_XCAPTURE_USB 11
68#define CX231XX_BOARD_KWORLD_UB430_USB_HYBRID 12
69#define CX231XX_BOARD_ICONBIT_U100 13
68 70
69/* Limits minimum and default number of buffers */ 71/* Limits minimum and default number of buffers */
70#define CX231XX_MIN_BUF 4 72#define CX231XX_MIN_BUF 4
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index ea88722cb4ab..2354336862cf 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -1399,6 +1399,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1399 else 1399 else
1400 altera_init(&netup_config, fw); 1400 altera_init(&netup_config, fw);
1401 1401
1402 release_firmware(fw);
1402 break; 1403 break;
1403 } 1404 }
1404 } 1405 }
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 9933810b4e33..64d9b2136ff6 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -2045,7 +2045,7 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
2045 } 2045 }
2046 2046
2047 /* print pci info */ 2047 /* print pci info */
2048 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 2048 dev->pci_rev = pci_dev->revision;
2049 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 2049 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
2050 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 2050 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
2051 "latency: %d, mmio: 0x%llx\n", dev->name, 2051 "latency: %d, mmio: 0x%llx\n", dev->name,
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index bca307eb1e24..11e49bbc4a66 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1060,18 +1060,21 @@ static int mpeg_open(struct file *file)
1060 1060
1061 /* Make sure we can acquire the hardware */ 1061 /* Make sure we can acquire the hardware */
1062 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1062 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1063 if (drv) { 1063 if (!drv) {
1064 err = drv->request_acquire(drv); 1064 dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
1065 if(err != 0) { 1065 mutex_unlock(&dev->core->lock);
1066 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); 1066 return -ENODEV;
1067 mutex_unlock(&dev->core->lock); 1067 }
1068 return err; 1068
1069 } 1069 err = drv->request_acquire(drv);
1070 if (err != 0) {
1071 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
1072 mutex_unlock(&dev->core->lock);
1073 return err;
1070 } 1074 }
1071 1075
1072 if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { 1076 if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
1073 if (drv) 1077 drv->request_release(drv);
1074 drv->request_release(drv);
1075 mutex_unlock(&dev->core->lock); 1078 mutex_unlock(&dev->core->lock);
1076 return -EINVAL; 1079 return -EINVAL;
1077 } 1080 }
@@ -1080,8 +1083,7 @@ static int mpeg_open(struct file *file)
1080 /* allocate + initialize per filehandle data */ 1083 /* allocate + initialize per filehandle data */
1081 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 1084 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1082 if (NULL == fh) { 1085 if (NULL == fh) {
1083 if (drv) 1086 drv->request_release(drv);
1084 drv->request_release(drv);
1085 mutex_unlock(&dev->core->lock); 1087 mutex_unlock(&dev->core->lock);
1086 return -ENOMEM; 1088 return -ENOMEM;
1087 } 1089 }
@@ -1099,7 +1101,7 @@ static int mpeg_open(struct file *file)
1099 cx88_set_scale(dev->core, dev->width, dev->height, 1101 cx88_set_scale(dev->core, dev->width, dev->height,
1100 fh->mpegq.field); 1102 fh->mpegq.field);
1101 1103
1102 atomic_inc(&dev->core->mpeg_users); 1104 dev->core->mpeg_users++;
1103 mutex_unlock(&dev->core->lock); 1105 mutex_unlock(&dev->core->lock);
1104 return 0; 1106 return 0;
1105} 1107}
@@ -1110,7 +1112,9 @@ static int mpeg_release(struct file *file)
1110 struct cx8802_dev *dev = fh->dev; 1112 struct cx8802_dev *dev = fh->dev;
1111 struct cx8802_driver *drv = NULL; 1113 struct cx8802_driver *drv = NULL;
1112 1114
1113 if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1) 1115 mutex_lock(&dev->core->lock);
1116
1117 if (dev->mpeg_active && dev->core->mpeg_users == 1)
1114 blackbird_stop_codec(dev); 1118 blackbird_stop_codec(dev);
1115 1119
1116 cx8802_cancel_buffers(fh->dev); 1120 cx8802_cancel_buffers(fh->dev);
@@ -1119,17 +1123,18 @@ static int mpeg_release(struct file *file)
1119 1123
1120 videobuf_mmap_free(&fh->mpegq); 1124 videobuf_mmap_free(&fh->mpegq);
1121 1125
1122 mutex_lock(&dev->core->lock);
1123 file->private_data = NULL; 1126 file->private_data = NULL;
1124 kfree(fh); 1127 kfree(fh);
1125 mutex_unlock(&dev->core->lock);
1126 1128
1127 /* Make sure we release the hardware */ 1129 /* Make sure we release the hardware */
1128 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1130 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1131 WARN_ON(!drv);
1129 if (drv) 1132 if (drv)
1130 drv->request_release(drv); 1133 drv->request_release(drv);
1131 1134
1132 atomic_dec(&dev->core->mpeg_users); 1135 dev->core->mpeg_users--;
1136
1137 mutex_unlock(&dev->core->lock);
1133 1138
1134 return 0; 1139 return 0;
1135} 1140}
@@ -1334,11 +1339,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1334 blackbird_register_video(dev); 1339 blackbird_register_video(dev);
1335 1340
1336 /* initial device configuration: needed ? */ 1341 /* initial device configuration: needed ? */
1337 mutex_lock(&dev->core->lock);
1338// init_controls(core); 1342// init_controls(core);
1339 cx88_set_tvnorm(core,core->tvnorm); 1343 cx88_set_tvnorm(core,core->tvnorm);
1340 cx88_video_mux(core,0); 1344 cx88_video_mux(core,0);
1341 mutex_unlock(&dev->core->lock);
1342 1345
1343 return 0; 1346 return 0;
1344 1347
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 7b8c9d3b6efc..c69df7ebb6a7 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -133,6 +133,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
133 return -EINVAL; 133 return -EINVAL;
134 } 134 }
135 135
136 mutex_lock(&dev->core->lock);
136 drv = cx8802_get_driver(dev, CX88_MPEG_DVB); 137 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
137 if (drv) { 138 if (drv) {
138 if (acquire){ 139 if (acquire){
@@ -143,6 +144,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
143 dev->frontends.active_fe_id = 0; 144 dev->frontends.active_fe_id = 0;
144 } 145 }
145 } 146 }
147 mutex_unlock(&dev->core->lock);
146 148
147 return ret; 149 return ret;
148} 150}
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index addf9545e9bf..1a7b983f8297 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -78,6 +78,7 @@ static void flush_request_modules(struct cx8802_dev *dev)
78 78
79 79
80static LIST_HEAD(cx8802_devlist); 80static LIST_HEAD(cx8802_devlist);
81static DEFINE_MUTEX(cx8802_mutex);
81/* ------------------------------------------------------------------ */ 82/* ------------------------------------------------------------------ */
82 83
83static int cx8802_start_dma(struct cx8802_dev *dev, 84static int cx8802_start_dma(struct cx8802_dev *dev,
@@ -474,7 +475,7 @@ static int cx8802_init_common(struct cx8802_dev *dev)
474 return -EIO; 475 return -EIO;
475 } 476 }
476 477
477 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 478 dev->pci_rev = dev->pci->revision;
478 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 479 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
479 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 480 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
480 "latency: %d, mmio: 0x%llx\n", dev->core->name, 481 "latency: %d, mmio: 0x%llx\n", dev->core->name,
@@ -624,13 +625,11 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
624 625
625 if (drv->advise_acquire) 626 if (drv->advise_acquire)
626 { 627 {
627 mutex_lock(&drv->core->lock);
628 core->active_ref++; 628 core->active_ref++;
629 if (core->active_type_id == CX88_BOARD_NONE) { 629 if (core->active_type_id == CX88_BOARD_NONE) {
630 core->active_type_id = drv->type_id; 630 core->active_type_id = drv->type_id;
631 drv->advise_acquire(drv); 631 drv->advise_acquire(drv);
632 } 632 }
633 mutex_unlock(&drv->core->lock);
634 633
635 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); 634 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
636 } 635 }
@@ -643,14 +642,12 @@ static int cx8802_request_release(struct cx8802_driver *drv)
643{ 642{
644 struct cx88_core *core = drv->core; 643 struct cx88_core *core = drv->core;
645 644
646 mutex_lock(&drv->core->lock);
647 if (drv->advise_release && --core->active_ref == 0) 645 if (drv->advise_release && --core->active_ref == 0)
648 { 646 {
649 drv->advise_release(drv); 647 drv->advise_release(drv);
650 core->active_type_id = CX88_BOARD_NONE; 648 core->active_type_id = CX88_BOARD_NONE;
651 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); 649 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
652 } 650 }
653 mutex_unlock(&drv->core->lock);
654 651
655 return 0; 652 return 0;
656} 653}
@@ -693,6 +690,8 @@ int cx8802_register_driver(struct cx8802_driver *drv)
693 return err; 690 return err;
694 } 691 }
695 692
693 mutex_lock(&cx8802_mutex);
694
696 list_for_each_entry(dev, &cx8802_devlist, devlist) { 695 list_for_each_entry(dev, &cx8802_devlist, devlist) {
697 printk(KERN_INFO 696 printk(KERN_INFO
698 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", 697 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -702,8 +701,10 @@ int cx8802_register_driver(struct cx8802_driver *drv)
702 701
703 /* Bring up a new struct for each driver instance */ 702 /* Bring up a new struct for each driver instance */
704 driver = kzalloc(sizeof(*drv),GFP_KERNEL); 703 driver = kzalloc(sizeof(*drv),GFP_KERNEL);
705 if (driver == NULL) 704 if (driver == NULL) {
706 return -ENOMEM; 705 err = -ENOMEM;
706 goto out;
707 }
707 708
708 /* Snapshot of the driver registration data */ 709 /* Snapshot of the driver registration data */
709 drv->core = dev->core; 710 drv->core = dev->core;
@@ -713,21 +714,23 @@ int cx8802_register_driver(struct cx8802_driver *drv)
713 drv->request_release = cx8802_request_release; 714 drv->request_release = cx8802_request_release;
714 memcpy(driver, drv, sizeof(*driver)); 715 memcpy(driver, drv, sizeof(*driver));
715 716
717 mutex_lock(&drv->core->lock);
716 err = drv->probe(driver); 718 err = drv->probe(driver);
717 if (err == 0) { 719 if (err == 0) {
718 i++; 720 i++;
719 mutex_lock(&drv->core->lock);
720 list_add_tail(&driver->drvlist, &dev->drvlist); 721 list_add_tail(&driver->drvlist, &dev->drvlist);
721 mutex_unlock(&drv->core->lock);
722 } else { 722 } else {
723 printk(KERN_ERR 723 printk(KERN_ERR
724 "%s/2: cx8802 probe failed, err = %d\n", 724 "%s/2: cx8802 probe failed, err = %d\n",
725 dev->core->name, err); 725 dev->core->name, err);
726 } 726 }
727 727 mutex_unlock(&drv->core->lock);
728 } 728 }
729 729
730 return i ? 0 : -ENODEV; 730 err = i ? 0 : -ENODEV;
731out:
732 mutex_unlock(&cx8802_mutex);
733 return err;
731} 734}
732 735
733int cx8802_unregister_driver(struct cx8802_driver *drv) 736int cx8802_unregister_driver(struct cx8802_driver *drv)
@@ -741,6 +744,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
741 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", 744 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
742 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); 745 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
743 746
747 mutex_lock(&cx8802_mutex);
748
744 list_for_each_entry(dev, &cx8802_devlist, devlist) { 749 list_for_each_entry(dev, &cx8802_devlist, devlist) {
745 printk(KERN_INFO 750 printk(KERN_INFO
746 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", 751 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -748,6 +753,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
748 dev->pci->subsystem_device, dev->core->board.name, 753 dev->pci->subsystem_device, dev->core->board.name,
749 dev->core->boardnr); 754 dev->core->boardnr);
750 755
756 mutex_lock(&dev->core->lock);
757
751 list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) { 758 list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
752 /* only unregister the correct driver type */ 759 /* only unregister the correct driver type */
753 if (d->type_id != drv->type_id) 760 if (d->type_id != drv->type_id)
@@ -755,17 +762,18 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
755 762
756 err = d->remove(d); 763 err = d->remove(d);
757 if (err == 0) { 764 if (err == 0) {
758 mutex_lock(&drv->core->lock);
759 list_del(&d->drvlist); 765 list_del(&d->drvlist);
760 mutex_unlock(&drv->core->lock);
761 kfree(d); 766 kfree(d);
762 } else 767 } else
763 printk(KERN_ERR "%s/2: cx8802 driver remove " 768 printk(KERN_ERR "%s/2: cx8802 driver remove "
764 "failed (%d)\n", dev->core->name, err); 769 "failed (%d)\n", dev->core->name, err);
765 } 770 }
766 771
772 mutex_unlock(&dev->core->lock);
767 } 773 }
768 774
775 mutex_unlock(&cx8802_mutex);
776
769 return err; 777 return err;
770} 778}
771 779
@@ -803,7 +811,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
803 goto fail_free; 811 goto fail_free;
804 812
805 INIT_LIST_HEAD(&dev->drvlist); 813 INIT_LIST_HEAD(&dev->drvlist);
814 mutex_lock(&cx8802_mutex);
806 list_add_tail(&dev->devlist,&cx8802_devlist); 815 list_add_tail(&dev->devlist,&cx8802_devlist);
816 mutex_unlock(&cx8802_mutex);
807 817
808 /* now autoload cx88-dvb or cx88-blackbird */ 818 /* now autoload cx88-dvb or cx88-blackbird */
809 request_modules(dev); 819 request_modules(dev);
@@ -827,6 +837,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
827 837
828 flush_request_modules(dev); 838 flush_request_modules(dev);
829 839
840 mutex_lock(&dev->core->lock);
841
830 if (!list_empty(&dev->drvlist)) { 842 if (!list_empty(&dev->drvlist)) {
831 struct cx8802_driver *drv, *tmp; 843 struct cx8802_driver *drv, *tmp;
832 int err; 844 int err;
@@ -838,9 +850,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
838 list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { 850 list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
839 err = drv->remove(drv); 851 err = drv->remove(drv);
840 if (err == 0) { 852 if (err == 0) {
841 mutex_lock(&drv->core->lock);
842 list_del(&drv->drvlist); 853 list_del(&drv->drvlist);
843 mutex_unlock(&drv->core->lock);
844 } else 854 } else
845 printk(KERN_ERR "%s/2: cx8802 driver remove " 855 printk(KERN_ERR "%s/2: cx8802 driver remove "
846 "failed (%d)\n", dev->core->name, err); 856 "failed (%d)\n", dev->core->name, err);
@@ -848,6 +858,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
848 } 858 }
849 } 859 }
850 860
861 mutex_unlock(&dev->core->lock);
862
851 /* Destroy any 8802 reference. */ 863 /* Destroy any 8802 reference. */
852 dev->core->dvbdev = NULL; 864 dev->core->dvbdev = NULL;
853 865
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 287a41ee1c4f..cef4f282e5aa 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -824,7 +824,7 @@ static int video_open(struct file *file)
824 call_all(core, tuner, s_radio); 824 call_all(core, tuner, s_radio);
825 } 825 }
826 826
827 atomic_inc(&core->users); 827 core->users++;
828 mutex_unlock(&core->lock); 828 mutex_unlock(&core->lock);
829 829
830 return 0; 830 return 0;
@@ -922,7 +922,8 @@ static int video_release(struct file *file)
922 file->private_data = NULL; 922 file->private_data = NULL;
923 kfree(fh); 923 kfree(fh);
924 924
925 if(atomic_dec_and_test(&dev->core->users)) 925 dev->core->users--;
926 if (!dev->core->users)
926 call_all(dev->core, core, s_power, 0); 927 call_all(dev->core, core, s_power, 0);
927 mutex_unlock(&dev->core->lock); 928 mutex_unlock(&dev->core->lock);
928 929
@@ -1832,7 +1833,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1832 dev->core = core; 1833 dev->core = core;
1833 1834
1834 /* print pci info */ 1835 /* print pci info */
1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1836 dev->pci_rev = pci_dev->revision;
1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1837 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1838 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1838 "latency: %d, mmio: 0x%llx\n", core->name, 1839 "latency: %d, mmio: 0x%llx\n", core->name,
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 9b3742a7746c..a399a8b086ba 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -389,8 +389,8 @@ struct cx88_core {
389 struct mutex lock; 389 struct mutex lock;
390 /* various v4l controls */ 390 /* various v4l controls */
391 u32 freq; 391 u32 freq;
392 atomic_t users; 392 int users;
393 atomic_t mpeg_users; 393 int mpeg_users;
394 394
395 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ 395 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
396 struct cx8802_dev *dvbdev; 396 struct cx8802_dev *dvbdev;
@@ -505,6 +505,8 @@ struct cx8802_driver {
505 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state); 505 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
506 int (*resume)(struct pci_dev *pci_dev); 506 int (*resume)(struct pci_dev *pci_dev);
507 507
508 /* Callers to the following functions must hold core->lock */
509
508 /* MPEG 8802 -> mini driver - Driver probe and configuration */ 510 /* MPEG 8802 -> mini driver - Driver probe and configuration */
509 int (*probe)(struct cx8802_driver *drv); 511 int (*probe)(struct cx8802_driver *drv);
510 int (*remove)(struct cx8802_driver *drv); 512 int (*remove)(struct cx8802_driver *drv);
@@ -561,8 +563,9 @@ struct cx8802_dev {
561 /* for switching modulation types */ 563 /* for switching modulation types */
562 unsigned char ts_gen_cntrl; 564 unsigned char ts_gen_cntrl;
563 565
564 /* List of attached drivers */ 566 /* List of attached drivers; must hold core->lock to access */
565 struct list_head drvlist; 567 struct list_head drvlist;
568
566 struct work_struct request_module_wk; 569 struct work_struct request_module_wk;
567}; 570};
568 571
@@ -685,6 +688,8 @@ int cx88_audio_thread(void *data);
685 688
686int cx8802_register_driver(struct cx8802_driver *drv); 689int cx8802_register_driver(struct cx8802_driver *drv);
687int cx8802_unregister_driver(struct cx8802_driver *drv); 690int cx8802_unregister_driver(struct cx8802_driver *drv);
691
692/* Caller must hold core->lock */
688struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); 693struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
689 694
690/* ----------------------------------------------------------- */ 695/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 985100ea17a4..3cb78f26df90 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -38,6 +38,8 @@ config VIDEO_EM28XX_DVB
38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
39 select DVB_TDA10023 if !DVB_FE_CUSTOMISE 39 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
40 select DVB_S921 if !DVB_FE_CUSTOMISE 40 select DVB_S921 if !DVB_FE_CUSTOMISE
41 select DVB_DRXD if !DVB_FE_CUSTOMISE
42 select DVB_CXD2820R if !DVB_FE_CUSTOMISE
41 select VIDEOBUF_DVB 43 select VIDEOBUF_DVB
42 ---help--- 44 ---help---
43 This adds support for DVB cards based on the 45 This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 69fcea82d01c..4e37375decf5 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -100,6 +100,13 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
100 { -1, -1, -1, -1}, 100 { -1, -1, -1, -1},
101}; 101};
102 102
103/* Board Hauppauge WinTV HVR 900 (R2) digital */
104static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
105 {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
106 {EM2880_R04_GPO, 0x0c, 0x0f, 10},
107 { -1, -1, -1, -1},
108};
109
103/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ 110/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
104static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { 111static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
105 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, 112 {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
@@ -282,6 +289,16 @@ static struct em28xx_reg_seq leadership_reset[] = {
282 { -1, -1, -1, -1}, 289 { -1, -1, -1, -1},
283}; 290};
284 291
292/* 2013:024f PCTV Systems nanoStick T2 290e
293 * GPIO_6 - demod reset
294 * GPIO_7 - LED
295 */
296static struct em28xx_reg_seq pctv_290e[] = {
297 {EM2874_R80_GPIO, 0x00, 0xff, 80},
298 {EM2874_R80_GPIO, 0x40, 0xff, 80}, /* GPIO_6 = 1 */
299 {EM2874_R80_GPIO, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */
300 {-1, -1, -1, -1},
301};
285 302
286/* 303/*
287 * Board definitions 304 * Board definitions
@@ -859,6 +876,8 @@ struct em28xx_board em28xx_boards[] = {
859 .tuner_type = TUNER_XC2028, 876 .tuner_type = TUNER_XC2028,
860 .tuner_gpio = default_tuner_gpio, 877 .tuner_gpio = default_tuner_gpio,
861 .mts_firmware = 1, 878 .mts_firmware = 1,
879 .has_dvb = 1,
880 .dvb_gpio = hauppauge_wintv_hvr_900R2_digital,
862 .ir_codes = RC_MAP_HAUPPAUGE, 881 .ir_codes = RC_MAP_HAUPPAUGE,
863 .decoder = EM28XX_TVP5150, 882 .decoder = EM28XX_TVP5150,
864 .input = { { 883 .input = { {
@@ -1448,12 +1467,14 @@ struct em28xx_board em28xx_boards[] = {
1448 .gpio = pinnacle_hybrid_pro_analog, 1467 .gpio = pinnacle_hybrid_pro_analog,
1449 } }, 1468 } },
1450 }, 1469 },
1451 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { 1470 [EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = {
1452 .name = "Pinnacle Hybrid Pro (2)", 1471 .name = "Pinnacle Hybrid Pro (330e)",
1453 .valid = EM28XX_BOARD_NOT_VALIDATED,
1454 .tuner_type = TUNER_XC2028, 1472 .tuner_type = TUNER_XC2028,
1455 .tuner_gpio = default_tuner_gpio, 1473 .tuner_gpio = default_tuner_gpio,
1456 .mts_firmware = 1, 1474 .mts_firmware = 1,
1475 .has_dvb = 1,
1476 .dvb_gpio = hauppauge_wintv_hvr_900R2_digital,
1477 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
1457 .decoder = EM28XX_TVP5150, 1478 .decoder = EM28XX_TVP5150,
1458 .input = { { 1479 .input = { {
1459 .type = EM28XX_VMUX_TELEVISION, 1480 .type = EM28XX_VMUX_TELEVISION,
@@ -1749,6 +1770,17 @@ struct em28xx_board em28xx_boards[] = {
1749 .dvb_gpio = kworld_a340_digital, 1770 .dvb_gpio = kworld_a340_digital,
1750 .tuner_gpio = default_tuner_gpio, 1771 .tuner_gpio = default_tuner_gpio,
1751 }, 1772 },
1773 /* 2013:024f PCTV Systems nanoStick T2 290e.
1774 * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */
1775 [EM28174_BOARD_PCTV_290E] = {
1776 .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
1777 EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
1778 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1779 .name = "PCTV Systems nanoStick T2 290e",
1780 .tuner_type = TUNER_ABSENT,
1781 .tuner_gpio = pctv_290e,
1782 .has_dvb = 1,
1783 },
1752}; 1784};
1753const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1785const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1754 1786
@@ -1863,7 +1895,7 @@ struct usb_device_id em28xx_id_table[] = {
1863 { USB_DEVICE(0x2304, 0x021a), 1895 { USB_DEVICE(0x2304, 0x021a),
1864 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, 1896 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
1865 { USB_DEVICE(0x2304, 0x0226), 1897 { USB_DEVICE(0x2304, 0x0226),
1866 .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO }, 1898 .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
1867 { USB_DEVICE(0x2304, 0x0227), 1899 { USB_DEVICE(0x2304, 0x0227),
1868 .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, 1900 .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
1869 { USB_DEVICE(0x0413, 0x6023), 1901 { USB_DEVICE(0x0413, 0x6023),
@@ -1876,6 +1908,8 @@ struct usb_device_id em28xx_id_table[] = {
1876 .driver_info = EM2860_BOARD_GADMEI_UTV330 }, 1908 .driver_info = EM2860_BOARD_GADMEI_UTV330 },
1877 { USB_DEVICE(0x1b80, 0xa340), 1909 { USB_DEVICE(0x1b80, 0xa340),
1878 .driver_info = EM2870_BOARD_KWORLD_A340 }, 1910 .driver_info = EM2870_BOARD_KWORLD_A340 },
1911 { USB_DEVICE(0x2013, 0x024f),
1912 .driver_info = EM28174_BOARD_PCTV_290E },
1879 { }, 1913 { },
1880}; 1914};
1881MODULE_DEVICE_TABLE(usb, em28xx_id_table); 1915MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2229,7 +2263,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2229 ctl->demod = XC3028_FE_ZARLINK456; 2263 ctl->demod = XC3028_FE_ZARLINK456;
2230 break; 2264 break;
2231 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 2265 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
2232 /* djh - Not sure which demod we need here */ 2266 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
2233 ctl->demod = XC3028_FE_DEFAULT; 2267 ctl->demod = XC3028_FE_DEFAULT;
2234 break; 2268 break;
2235 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: 2269 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
@@ -2799,6 +2833,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2799 dev->reg_gpio_num = EM2874_R80_GPIO; 2833 dev->reg_gpio_num = EM2874_R80_GPIO;
2800 dev->wait_after_write = 0; 2834 dev->wait_after_write = 0;
2801 break; 2835 break;
2836 case CHIP_ID_EM28174:
2837 em28xx_info("chip ID is em28174\n");
2838 dev->reg_gpio_num = EM2874_R80_GPIO;
2839 dev->wait_after_write = 0;
2840 break;
2802 case CHIP_ID_EM2883: 2841 case CHIP_ID_EM2883:
2803 em28xx_info("chip ID is em2882/em2883\n"); 2842 em28xx_info("chip ID is em2882/em2883\n");
2804 dev->wait_after_write = 0; 2843 dev->wait_after_write = 0;
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 44c63cbd6dda..e33f145d867a 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -489,7 +489,8 @@ int em28xx_audio_setup(struct em28xx *dev)
489 int vid1, vid2, feat, cfg; 489 int vid1, vid2, feat, cfg;
490 u32 vid; 490 u32 vid;
491 491
492 if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874) { 492 if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
493 || dev->chip_id == CHIP_ID_EM28174) {
493 /* Digital only device - don't load any alsa module */ 494 /* Digital only device - don't load any alsa module */
494 dev->audio_mode.has_audio = 0; 495 dev->audio_mode.has_audio = 0;
495 dev->has_audio_class = 0; 496 dev->has_audio_class = 0;
@@ -614,7 +615,7 @@ int em28xx_capture_start(struct em28xx *dev, int start)
614{ 615{
615 int rc; 616 int rc;
616 617
617 if (dev->chip_id == CHIP_ID_EM2874) { 618 if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
618 /* The Transport Stream Enable Register moved in em2874 */ 619 /* The Transport Stream Enable Register moved in em2874 */
619 if (!start) { 620 if (!start) {
620 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, 621 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
@@ -1111,6 +1112,10 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
1111 /* FIXME - for now assume 564 like it was before, but the 1112 /* FIXME - for now assume 564 like it was before, but the
1112 em2874 code should be added to return the proper value... */ 1113 em2874 code should be added to return the proper value... */
1113 packet_size = 564; 1114 packet_size = 564;
1115 } else if (dev->chip_id == CHIP_ID_EM28174) {
1116 /* FIXME same as em2874. 564 was enough for 22 Mbit DVB-T
1117 but too much for 44 Mbit DVB-C. */
1118 packet_size = 752;
1114 } else { 1119 } else {
1115 /* TS max packet size stored in bits 1-0 of R01 */ 1120 /* TS max packet size stored in bits 1-0 of R01 */
1116 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2); 1121 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index c7c04bf712aa..7904ca4b6913 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -38,6 +38,8 @@
38#include "tda1002x.h" 38#include "tda1002x.h"
39#include "tda18271.h" 39#include "tda18271.h"
40#include "s921.h" 40#include "s921.h"
41#include "drxd.h"
42#include "cxd2820r.h"
41 43
42MODULE_DESCRIPTION("driver for em28xx based DVB cards"); 44MODULE_DESCRIPTION("driver for em28xx based DVB cards");
43MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 45MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -58,7 +60,7 @@ if (debug >= level) \
58#define EM28XX_DVB_MAX_PACKETS 64 60#define EM28XX_DVB_MAX_PACKETS 64
59 61
60struct em28xx_dvb { 62struct em28xx_dvb {
61 struct dvb_frontend *frontend; 63 struct dvb_frontend *fe[2];
62 64
63 /* feed count management */ 65 /* feed count management */
64 struct mutex lock; 66 struct mutex lock;
@@ -285,12 +287,13 @@ static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = {
285 .if2 = 45600, 287 .if2 = 45600,
286}; 288};
287 289
288#ifdef EM28XX_DRX397XD_SUPPORT 290static struct drxd_config em28xx_drxd = {
289/* [TODO] djh - not sure yet what the device config needs to contain */ 291 .index = 0, .demod_address = 0x70, .demod_revision = 0xa2,
290static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { 292 .demoda_address = 0x00, .pll_address = 0x00,
291 .demod_address = (0xe0 >> 1), 293 .pll_type = DRXD_PLL_NONE, .clock = 12000, .insert_rs_byte = 1,
294 .pll_set = NULL, .osc_deviation = NULL, .IF = 42800000,
295 .disable_i2c_gate_ctrl = 1,
292}; 296};
293#endif
294 297
295static int mt352_terratec_xs_init(struct dvb_frontend *fe) 298static int mt352_terratec_xs_init(struct dvb_frontend *fe)
296{ 299{
@@ -332,6 +335,26 @@ static struct tda10023_config em28xx_tda10023_config = {
332 .invert = 1, 335 .invert = 1,
333}; 336};
334 337
338static struct cxd2820r_config em28xx_cxd2820r_config = {
339 .i2c_address = (0xd8 >> 1),
340 .ts_mode = CXD2820R_TS_SERIAL,
341 .if_dvbt_6 = 3300,
342 .if_dvbt_7 = 3500,
343 .if_dvbt_8 = 4000,
344 .if_dvbt2_6 = 3300,
345 .if_dvbt2_7 = 3500,
346 .if_dvbt2_8 = 4000,
347 .if_dvbc = 5000,
348
349 /* enable LNA for DVB-T2 and DVB-C */
350 .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
351 .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
352};
353
354static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
355 .output_opt = TDA18271_OUTPUT_LT_OFF,
356};
357
335/* ------------------------------------------------------------------ */ 358/* ------------------------------------------------------------------ */
336 359
337static int attach_xc3028(u8 addr, struct em28xx *dev) 360static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -343,17 +366,17 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
343 cfg.i2c_adap = &dev->i2c_adap; 366 cfg.i2c_adap = &dev->i2c_adap;
344 cfg.i2c_addr = addr; 367 cfg.i2c_addr = addr;
345 368
346 if (!dev->dvb->frontend) { 369 if (!dev->dvb->fe[0]) {
347 em28xx_errdev("/2: dvb frontend not attached. " 370 em28xx_errdev("/2: dvb frontend not attached. "
348 "Can't attach xc3028\n"); 371 "Can't attach xc3028\n");
349 return -EINVAL; 372 return -EINVAL;
350 } 373 }
351 374
352 fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); 375 fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg);
353 if (!fe) { 376 if (!fe) {
354 em28xx_errdev("/2: xc3028 attach failed\n"); 377 em28xx_errdev("/2: xc3028 attach failed\n");
355 dvb_frontend_detach(dev->dvb->frontend); 378 dvb_frontend_detach(dev->dvb->fe[0]);
356 dev->dvb->frontend = NULL; 379 dev->dvb->fe[0] = NULL;
357 return -EINVAL; 380 return -EINVAL;
358 } 381 }
359 382
@@ -383,16 +406,28 @@ static int register_dvb(struct em28xx_dvb *dvb,
383 } 406 }
384 407
385 /* Ensure all frontends negotiate bus access */ 408 /* Ensure all frontends negotiate bus access */
386 dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; 409 dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
410 if (dvb->fe[1])
411 dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
387 412
388 dvb->adapter.priv = dev; 413 dvb->adapter.priv = dev;
389 414
390 /* register frontend */ 415 /* register frontend */
391 result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 416 result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]);
392 if (result < 0) { 417 if (result < 0) {
393 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", 418 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
394 dev->name, result); 419 dev->name, result);
395 goto fail_frontend; 420 goto fail_frontend0;
421 }
422
423 /* register 2nd frontend */
424 if (dvb->fe[1]) {
425 result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]);
426 if (result < 0) {
427 printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
428 dev->name, result);
429 goto fail_frontend1;
430 }
396 } 431 }
397 432
398 /* register demux stuff */ 433 /* register demux stuff */
@@ -458,9 +493,14 @@ fail_fe_hw:
458fail_dmxdev: 493fail_dmxdev:
459 dvb_dmx_release(&dvb->demux); 494 dvb_dmx_release(&dvb->demux);
460fail_dmx: 495fail_dmx:
461 dvb_unregister_frontend(dvb->frontend); 496 if (dvb->fe[1])
462fail_frontend: 497 dvb_unregister_frontend(dvb->fe[1]);
463 dvb_frontend_detach(dvb->frontend); 498 dvb_unregister_frontend(dvb->fe[0]);
499fail_frontend1:
500 if (dvb->fe[1])
501 dvb_frontend_detach(dvb->fe[1]);
502fail_frontend0:
503 dvb_frontend_detach(dvb->fe[0]);
464 dvb_unregister_adapter(&dvb->adapter); 504 dvb_unregister_adapter(&dvb->adapter);
465fail_adapter: 505fail_adapter:
466 return result; 506 return result;
@@ -473,12 +513,15 @@ static void unregister_dvb(struct em28xx_dvb *dvb)
473 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 513 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
474 dvb_dmxdev_release(&dvb->dmxdev); 514 dvb_dmxdev_release(&dvb->dmxdev);
475 dvb_dmx_release(&dvb->demux); 515 dvb_dmx_release(&dvb->demux);
476 dvb_unregister_frontend(dvb->frontend); 516 if (dvb->fe[1])
477 dvb_frontend_detach(dvb->frontend); 517 dvb_unregister_frontend(dvb->fe[1]);
518 dvb_unregister_frontend(dvb->fe[0]);
519 if (dvb->fe[1])
520 dvb_frontend_detach(dvb->fe[1]);
521 dvb_frontend_detach(dvb->fe[0]);
478 dvb_unregister_adapter(&dvb->adapter); 522 dvb_unregister_adapter(&dvb->adapter);
479} 523}
480 524
481
482static int dvb_init(struct em28xx *dev) 525static int dvb_init(struct em28xx *dev)
483{ 526{
484 int result = 0; 527 int result = 0;
@@ -497,16 +540,17 @@ static int dvb_init(struct em28xx *dev)
497 return -ENOMEM; 540 return -ENOMEM;
498 } 541 }
499 dev->dvb = dvb; 542 dev->dvb = dvb;
543 dvb->fe[0] = dvb->fe[1] = NULL;
500 544
501 mutex_lock(&dev->lock); 545 mutex_lock(&dev->lock);
502 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 546 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
503 /* init frontend */ 547 /* init frontend */
504 switch (dev->model) { 548 switch (dev->model) {
505 case EM2874_LEADERSHIP_ISDBT: 549 case EM2874_LEADERSHIP_ISDBT:
506 dvb->frontend = dvb_attach(s921_attach, 550 dvb->fe[0] = dvb_attach(s921_attach,
507 &sharp_isdbt, &dev->i2c_adap); 551 &sharp_isdbt, &dev->i2c_adap);
508 552
509 if (!dvb->frontend) { 553 if (!dvb->fe[0]) {
510 result = -EINVAL; 554 result = -EINVAL;
511 goto out_free; 555 goto out_free;
512 } 556 }
@@ -516,7 +560,7 @@ static int dvb_init(struct em28xx *dev)
516 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 560 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
517 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: 561 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
518 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: 562 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
519 dvb->frontend = dvb_attach(lgdt330x_attach, 563 dvb->fe[0] = dvb_attach(lgdt330x_attach,
520 &em2880_lgdt3303_dev, 564 &em2880_lgdt3303_dev,
521 &dev->i2c_adap); 565 &dev->i2c_adap);
522 if (attach_xc3028(0x61, dev) < 0) { 566 if (attach_xc3028(0x61, dev) < 0) {
@@ -525,7 +569,7 @@ static int dvb_init(struct em28xx *dev)
525 } 569 }
526 break; 570 break;
527 case EM2880_BOARD_KWORLD_DVB_310U: 571 case EM2880_BOARD_KWORLD_DVB_310U:
528 dvb->frontend = dvb_attach(zl10353_attach, 572 dvb->fe[0] = dvb_attach(zl10353_attach,
529 &em28xx_zl10353_with_xc3028, 573 &em28xx_zl10353_with_xc3028,
530 &dev->i2c_adap); 574 &dev->i2c_adap);
531 if (attach_xc3028(0x61, dev) < 0) { 575 if (attach_xc3028(0x61, dev) < 0) {
@@ -536,7 +580,7 @@ static int dvb_init(struct em28xx *dev)
536 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 580 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
537 case EM2882_BOARD_TERRATEC_HYBRID_XS: 581 case EM2882_BOARD_TERRATEC_HYBRID_XS:
538 case EM2880_BOARD_EMPIRE_DUAL_TV: 582 case EM2880_BOARD_EMPIRE_DUAL_TV:
539 dvb->frontend = dvb_attach(zl10353_attach, 583 dvb->fe[0] = dvb_attach(zl10353_attach,
540 &em28xx_zl10353_xc3028_no_i2c_gate, 584 &em28xx_zl10353_xc3028_no_i2c_gate,
541 &dev->i2c_adap); 585 &dev->i2c_adap);
542 if (attach_xc3028(0x61, dev) < 0) { 586 if (attach_xc3028(0x61, dev) < 0) {
@@ -549,13 +593,13 @@ static int dvb_init(struct em28xx *dev)
549 case EM2881_BOARD_PINNACLE_HYBRID_PRO: 593 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
550 case EM2882_BOARD_DIKOM_DK300: 594 case EM2882_BOARD_DIKOM_DK300:
551 case EM2882_BOARD_KWORLD_VS_DVBT: 595 case EM2882_BOARD_KWORLD_VS_DVBT:
552 dvb->frontend = dvb_attach(zl10353_attach, 596 dvb->fe[0] = dvb_attach(zl10353_attach,
553 &em28xx_zl10353_xc3028_no_i2c_gate, 597 &em28xx_zl10353_xc3028_no_i2c_gate,
554 &dev->i2c_adap); 598 &dev->i2c_adap);
555 if (dvb->frontend == NULL) { 599 if (dvb->fe[0] == NULL) {
556 /* This board could have either a zl10353 or a mt352. 600 /* This board could have either a zl10353 or a mt352.
557 If the chip id isn't for zl10353, try mt352 */ 601 If the chip id isn't for zl10353, try mt352 */
558 dvb->frontend = dvb_attach(mt352_attach, 602 dvb->fe[0] = dvb_attach(mt352_attach,
559 &terratec_xs_mt352_cfg, 603 &terratec_xs_mt352_cfg,
560 &dev->i2c_adap); 604 &dev->i2c_adap);
561 } 605 }
@@ -567,7 +611,7 @@ static int dvb_init(struct em28xx *dev)
567 break; 611 break;
568 case EM2883_BOARD_KWORLD_HYBRID_330U: 612 case EM2883_BOARD_KWORLD_HYBRID_330U:
569 case EM2882_BOARD_EVGA_INDTUBE: 613 case EM2882_BOARD_EVGA_INDTUBE:
570 dvb->frontend = dvb_attach(s5h1409_attach, 614 dvb->fe[0] = dvb_attach(s5h1409_attach,
571 &em28xx_s5h1409_with_xc3028, 615 &em28xx_s5h1409_with_xc3028,
572 &dev->i2c_adap); 616 &dev->i2c_adap);
573 if (attach_xc3028(0x61, dev) < 0) { 617 if (attach_xc3028(0x61, dev) < 0) {
@@ -576,11 +620,11 @@ static int dvb_init(struct em28xx *dev)
576 } 620 }
577 break; 621 break;
578 case EM2882_BOARD_KWORLD_ATSC_315U: 622 case EM2882_BOARD_KWORLD_ATSC_315U:
579 dvb->frontend = dvb_attach(lgdt330x_attach, 623 dvb->fe[0] = dvb_attach(lgdt330x_attach,
580 &em2880_lgdt3303_dev, 624 &em2880_lgdt3303_dev,
581 &dev->i2c_adap); 625 &dev->i2c_adap);
582 if (dvb->frontend != NULL) { 626 if (dvb->fe[0] != NULL) {
583 if (!dvb_attach(simple_tuner_attach, dvb->frontend, 627 if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
584 &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { 628 &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
585 result = -EINVAL; 629 result = -EINVAL;
586 goto out_free; 630 goto out_free;
@@ -588,25 +632,21 @@ static int dvb_init(struct em28xx *dev)
588 } 632 }
589 break; 633 break;
590 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 634 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
591#ifdef EM28XX_DRX397XD_SUPPORT 635 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
592 /* We don't have the config structure properly populated, so 636 dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL,
593 this is commented out for now */ 637 &dev->i2c_adap, &dev->udev->dev);
594 dvb->frontend = dvb_attach(drx397xD_attach,
595 &em28xx_drx397xD_with_xc3028,
596 &dev->i2c_adap);
597 if (attach_xc3028(0x61, dev) < 0) { 638 if (attach_xc3028(0x61, dev) < 0) {
598 result = -EINVAL; 639 result = -EINVAL;
599 goto out_free; 640 goto out_free;
600 } 641 }
601 break; 642 break;
602#endif
603 case EM2870_BOARD_REDDO_DVB_C_USB_BOX: 643 case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
604 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ 644 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
605 dvb->frontend = dvb_attach(tda10023_attach, 645 dvb->fe[0] = dvb_attach(tda10023_attach,
606 &em28xx_tda10023_config, 646 &em28xx_tda10023_config,
607 &dev->i2c_adap, 0x48); 647 &dev->i2c_adap, 0x48);
608 if (dvb->frontend) { 648 if (dvb->fe[0]) {
609 if (!dvb_attach(simple_tuner_attach, dvb->frontend, 649 if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
610 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { 650 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
611 result = -EINVAL; 651 result = -EINVAL;
612 goto out_free; 652 goto out_free;
@@ -614,25 +654,53 @@ static int dvb_init(struct em28xx *dev)
614 } 654 }
615 break; 655 break;
616 case EM2870_BOARD_KWORLD_A340: 656 case EM2870_BOARD_KWORLD_A340:
617 dvb->frontend = dvb_attach(lgdt3305_attach, 657 dvb->fe[0] = dvb_attach(lgdt3305_attach,
618 &em2870_lgdt3304_dev, 658 &em2870_lgdt3304_dev,
619 &dev->i2c_adap); 659 &dev->i2c_adap);
620 if (dvb->frontend != NULL) 660 if (dvb->fe[0] != NULL)
621 dvb_attach(tda18271_attach, dvb->frontend, 0x60, 661 dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
622 &dev->i2c_adap, &kworld_a340_config); 662 &dev->i2c_adap, &kworld_a340_config);
623 break; 663 break;
664 case EM28174_BOARD_PCTV_290E:
665 /* MFE
666 * FE 0 = DVB-T/T2 + FE 1 = DVB-C, both sharing same tuner. */
667 /* FE 0 */
668 dvb->fe[0] = dvb_attach(cxd2820r_attach,
669 &em28xx_cxd2820r_config, &dev->i2c_adap, NULL);
670 if (dvb->fe[0]) {
671 struct i2c_adapter *i2c_tuner;
672 i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]);
673 /* FE 0 attach tuner */
674 if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
675 i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
676 dvb_frontend_detach(dvb->fe[0]);
677 result = -EINVAL;
678 goto out_free;
679 }
680 /* FE 1. This dvb_attach() cannot fail. */
681 dvb->fe[1] = dvb_attach(cxd2820r_attach, NULL, NULL,
682 dvb->fe[0]);
683 dvb->fe[1]->id = 1;
684 /* FE 1 attach tuner */
685 if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60,
686 i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
687 dvb_frontend_detach(dvb->fe[1]);
688 /* leave FE 0 still active */
689 }
690 }
691 break;
624 default: 692 default:
625 em28xx_errdev("/2: The frontend of your DVB/ATSC card" 693 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
626 " isn't supported yet\n"); 694 " isn't supported yet\n");
627 break; 695 break;
628 } 696 }
629 if (NULL == dvb->frontend) { 697 if (NULL == dvb->fe[0]) {
630 em28xx_errdev("/2: frontend initialization failed\n"); 698 em28xx_errdev("/2: frontend initialization failed\n");
631 result = -EINVAL; 699 result = -EINVAL;
632 goto out_free; 700 goto out_free;
633 } 701 }
634 /* define general-purpose callback pointer */ 702 /* define general-purpose callback pointer */
635 dvb->frontend->callback = em28xx_tuner_callback; 703 dvb->fe[0]->callback = em28xx_tuner_callback;
636 704
637 /* register everything */ 705 /* register everything */
638 result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); 706 result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 71474d31e155..4739fc7e6eb3 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -332,7 +332,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
332 struct em28xx_eeprom *em_eeprom = (void *)eedata; 332 struct em28xx_eeprom *em_eeprom = (void *)eedata;
333 int i, err, size = len, block; 333 int i, err, size = len, block;
334 334
335 if (dev->chip_id == CHIP_ID_EM2874) { 335 if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
336 /* Empia switched to a 16-bit addressable eeprom in newer 336 /* Empia switched to a 16-bit addressable eeprom in newer
337 devices. While we could certainly write a routine to read 337 devices. While we could certainly write a routine to read
338 the eeprom, there is nothing of use in there that cannot be 338 the eeprom, there is nothing of use in there that cannot be
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 91e90559642b..e92a28ede434 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -201,6 +201,7 @@ enum em28xx_chip_id {
201 CHIP_ID_EM2870 = 35, 201 CHIP_ID_EM2870 = 35,
202 CHIP_ID_EM2883 = 36, 202 CHIP_ID_EM2883 = 36,
203 CHIP_ID_EM2874 = 65, 203 CHIP_ID_EM2874 = 65,
204 CHIP_ID_EM28174 = 113,
204}; 205};
205 206
206/* 207/*
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6f2795a3d4b7..3cca33122450 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -97,7 +97,7 @@
97#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53 97#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53
98#define EM2882_BOARD_KWORLD_VS_DVBT 54 98#define EM2882_BOARD_KWORLD_VS_DVBT 54
99#define EM2882_BOARD_TERRATEC_HYBRID_XS 55 99#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
100#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 100#define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E 56
101#define EM2883_BOARD_KWORLD_HYBRID_330U 57 101#define EM2883_BOARD_KWORLD_HYBRID_330U 57
102#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 102#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
103#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 103#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
@@ -118,6 +118,7 @@
118#define EM2882_BOARD_DIKOM_DK300 75 118#define EM2882_BOARD_DIKOM_DK300 75
119#define EM2870_BOARD_KWORLD_A340 76 119#define EM2870_BOARD_KWORLD_A340 76
120#define EM2874_LEADERSHIP_ISDBT 77 120#define EM2874_LEADERSHIP_ISDBT 77
121#define EM28174_BOARD_PCTV_290E 78
121 122
122 123
123/* Limits minimum and default number of buffers */ 124/* Limits minimum and default number of buffers */
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
index 031af1610154..908d7012c3f2 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/video/fsl-viu.c
@@ -766,7 +766,7 @@ inline void viu_activate_overlay(struct viu_reg *viu_reg)
766 out_be32(&vr->picture_count, reg_val.picture_count); 766 out_be32(&vr->picture_count, reg_val.picture_count);
767} 767}
768 768
769static int viu_start_preview(struct viu_dev *dev, struct viu_fh *fh) 769static int viu_setup_preview(struct viu_dev *dev, struct viu_fh *fh)
770{ 770{
771 int bpp; 771 int bpp;
772 772
@@ -805,11 +805,6 @@ static int viu_start_preview(struct viu_dev *dev, struct viu_fh *fh)
805 /* setup the base address of the overlay buffer */ 805 /* setup the base address of the overlay buffer */
806 reg_val.field_base_addr = (u32)dev->ovbuf.base; 806 reg_val.field_base_addr = (u32)dev->ovbuf.base;
807 807
808 dev->ovenable = 1;
809 viu_activate_overlay(dev->vr);
810
811 /* start dma */
812 viu_start_dma(dev);
813 return 0; 808 return 0;
814} 809}
815 810
@@ -825,13 +820,11 @@ static int vidioc_s_fmt_overlay(struct file *file, void *priv,
825 if (err) 820 if (err)
826 return err; 821 return err;
827 822
828 mutex_lock(&dev->lock);
829 fh->win = f->fmt.win; 823 fh->win = f->fmt.win;
830 824
831 spin_lock_irqsave(&dev->slock, flags); 825 spin_lock_irqsave(&dev->slock, flags);
832 viu_start_preview(dev, fh); 826 viu_setup_preview(dev, fh);
833 spin_unlock_irqrestore(&dev->slock, flags); 827 spin_unlock_irqrestore(&dev->slock, flags);
834 mutex_unlock(&dev->lock);
835 return 0; 828 return 0;
836} 829}
837 830
@@ -841,6 +834,28 @@ static int vidioc_try_fmt_overlay(struct file *file, void *priv,
841 return 0; 834 return 0;
842} 835}
843 836
837static int vidioc_overlay(struct file *file, void *priv, unsigned int on)
838{
839 struct viu_fh *fh = priv;
840 struct viu_dev *dev = (struct viu_dev *)fh->dev;
841 unsigned long flags;
842
843 if (on) {
844 spin_lock_irqsave(&dev->slock, flags);
845 viu_activate_overlay(dev->vr);
846 dev->ovenable = 1;
847
848 /* start dma */
849 viu_start_dma(dev);
850 spin_unlock_irqrestore(&dev->slock, flags);
851 } else {
852 viu_stop_dma(dev);
853 dev->ovenable = 0;
854 }
855
856 return 0;
857}
858
844int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg) 859int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
845{ 860{
846 struct viu_fh *fh = priv; 861 struct viu_fh *fh = priv;
@@ -911,12 +926,16 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
911static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) 926static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
912{ 927{
913 struct viu_fh *fh = priv; 928 struct viu_fh *fh = priv;
929 struct viu_dev *dev = fh->dev;
914 930
915 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 931 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
916 return -EINVAL; 932 return -EINVAL;
917 if (fh->type != i) 933 if (fh->type != i)
918 return -EINVAL; 934 return -EINVAL;
919 935
936 if (dev->ovenable)
937 dev->ovenable = 0;
938
920 viu_start_dma(fh->dev); 939 viu_start_dma(fh->dev);
921 940
922 return videobuf_streamon(&fh->vb_vidq); 941 return videobuf_streamon(&fh->vb_vidq);
@@ -1311,7 +1330,8 @@ static int viu_open(struct file *file)
1311 videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops, 1330 videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops,
1312 dev->dev, &fh->vbq_lock, 1331 dev->dev, &fh->vbq_lock,
1313 fh->type, V4L2_FIELD_INTERLACED, 1332 fh->type, V4L2_FIELD_INTERLACED,
1314 sizeof(struct viu_buf), fh, NULL); 1333 sizeof(struct viu_buf), fh,
1334 &fh->dev->lock);
1315 return 0; 1335 return 0;
1316} 1336}
1317 1337
@@ -1401,7 +1421,7 @@ static struct v4l2_file_operations viu_fops = {
1401 .release = viu_release, 1421 .release = viu_release,
1402 .read = viu_read, 1422 .read = viu_read,
1403 .poll = viu_poll, 1423 .poll = viu_poll,
1404 .ioctl = video_ioctl2, /* V4L2 ioctl handler */ 1424 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
1405 .mmap = viu_mmap, 1425 .mmap = viu_mmap,
1406}; 1426};
1407 1427
@@ -1415,6 +1435,7 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = {
1415 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay, 1435 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay,
1416 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay, 1436 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay,
1417 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay, 1437 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay,
1438 .vidioc_overlay = vidioc_overlay,
1418 .vidioc_g_fbuf = vidioc_g_fbuf, 1439 .vidioc_g_fbuf = vidioc_g_fbuf,
1419 .vidioc_s_fbuf = vidioc_s_fbuf, 1440 .vidioc_s_fbuf = vidioc_s_fbuf,
1420 .vidioc_reqbufs = vidioc_reqbufs, 1441 .vidioc_reqbufs = vidioc_reqbufs,
@@ -1498,9 +1519,6 @@ static int __devinit viu_of_probe(struct platform_device *op)
1498 INIT_LIST_HEAD(&viu_dev->vidq.active); 1519 INIT_LIST_HEAD(&viu_dev->vidq.active);
1499 INIT_LIST_HEAD(&viu_dev->vidq.queued); 1520 INIT_LIST_HEAD(&viu_dev->vidq.queued);
1500 1521
1501 /* initialize locks */
1502 mutex_init(&viu_dev->lock);
1503
1504 snprintf(viu_dev->v4l2_dev.name, 1522 snprintf(viu_dev->v4l2_dev.name,
1505 sizeof(viu_dev->v4l2_dev.name), "%s", "VIU"); 1523 sizeof(viu_dev->v4l2_dev.name), "%s", "VIU");
1506 ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev); 1524 ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev);
@@ -1531,8 +1549,15 @@ static int __devinit viu_of_probe(struct platform_device *op)
1531 1549
1532 viu_dev->vdev = vdev; 1550 viu_dev->vdev = vdev;
1533 1551
1552 /* initialize locks */
1553 mutex_init(&viu_dev->lock);
1554 viu_dev->vdev->lock = &viu_dev->lock;
1555 spin_lock_init(&viu_dev->slock);
1556
1534 video_set_drvdata(viu_dev->vdev, viu_dev); 1557 video_set_drvdata(viu_dev->vdev, viu_dev);
1535 1558
1559 mutex_lock(&viu_dev->lock);
1560
1536 ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1); 1561 ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);
1537 if (ret < 0) { 1562 if (ret < 0) {
1538 video_device_release(viu_dev->vdev); 1563 video_device_release(viu_dev->vdev);
@@ -1559,6 +1584,8 @@ static int __devinit viu_of_probe(struct platform_device *op)
1559 goto err_irq; 1584 goto err_irq;
1560 } 1585 }
1561 1586
1587 mutex_unlock(&viu_dev->lock);
1588
1562 dev_info(&op->dev, "Freescale VIU Video Capture Board\n"); 1589 dev_info(&op->dev, "Freescale VIU Video Capture Board\n");
1563 return ret; 1590 return ret;
1564 1591
@@ -1568,6 +1595,7 @@ err_irq:
1568err_clk: 1595err_clk:
1569 video_unregister_device(viu_dev->vdev); 1596 video_unregister_device(viu_dev->vdev);
1570err_vdev: 1597err_vdev:
1598 mutex_unlock(&viu_dev->lock);
1571 i2c_put_adapter(ad); 1599 i2c_put_adapter(ad);
1572 v4l2_device_unregister(&viu_dev->v4l2_dev); 1600 v4l2_device_unregister(&viu_dev->v4l2_dev);
1573err: 1601err:
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index eb04e8b59989..34ae2c299799 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -77,6 +77,15 @@ config USB_GSPCA_JEILINJ
77 To compile this driver as a module, choose M here: the 77 To compile this driver as a module, choose M here: the
78 module will be called gspca_jeilinj. 78 module will be called gspca_jeilinj.
79 79
80config USB_GSPCA_KINECT
81 tristate "Kinect sensor device USB Camera Driver"
82 depends on VIDEO_V4L2 && USB_GSPCA
83 help
84 Say Y here if you want support for the Microsoft Kinect sensor device.
85
86 To compile this driver as a module, choose M here: the
87 module will be called gspca_kinect.
88
80config USB_GSPCA_KONICA 89config USB_GSPCA_KONICA
81 tristate "Konica USB Camera V4L2 driver" 90 tristate "Konica USB Camera V4L2 driver"
82 depends on VIDEO_V4L2 && USB_GSPCA 91 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 855fbc8c9c47..802fbe1bff4a 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o
5obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o 5obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
6obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 6obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
7obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o 7obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
8obj-$(CONFIG_USB_GSPCA_KINECT) += gspca_kinect.o
8obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o 9obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o
9obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 10obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
10obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 11obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
@@ -46,6 +47,7 @@ gspca_cpia1-objs := cpia1.o
46gspca_etoms-objs := etoms.o 47gspca_etoms-objs := etoms.o
47gspca_finepix-objs := finepix.o 48gspca_finepix-objs := finepix.o
48gspca_jeilinj-objs := jeilinj.o 49gspca_jeilinj-objs := jeilinj.o
50gspca_kinect-objs := kinect.o
49gspca_konica-objs := konica.o 51gspca_konica-objs := konica.o
50gspca_mars-objs := mars.o 52gspca_mars-objs := mars.o
51gspca_mr97310a-objs := mr97310a.o 53gspca_mr97310a-objs := mr97310a.o
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 9ddbac680663..f2a9451eea19 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1262,7 +1262,7 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1262static void monitor_exposure(struct gspca_dev *gspca_dev) 1262static void monitor_exposure(struct gspca_dev *gspca_dev)
1263{ 1263{
1264 struct sd *sd = (struct sd *) gspca_dev; 1264 struct sd *sd = (struct sd *) gspca_dev;
1265 u8 exp_acc, bcomp, gain, coarseL, cmd[8]; 1265 u8 exp_acc, bcomp, cmd[8];
1266 int ret, light_exp, dark_exp, very_dark_exp; 1266 int ret, light_exp, dark_exp, very_dark_exp;
1267 int old_exposure, new_exposure, framerate; 1267 int old_exposure, new_exposure, framerate;
1268 int setfps = 0, setexp = 0, setflicker = 0; 1268 int setfps = 0, setexp = 0, setflicker = 0;
@@ -1284,8 +1284,6 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
1284 } 1284 }
1285 exp_acc = gspca_dev->usb_buf[0]; 1285 exp_acc = gspca_dev->usb_buf[0];
1286 bcomp = gspca_dev->usb_buf[1]; 1286 bcomp = gspca_dev->usb_buf[1];
1287 gain = gspca_dev->usb_buf[2];
1288 coarseL = gspca_dev->usb_buf[3];
1289 1287
1290 light_exp = sd->params.colourParams.brightness + 1288 light_exp = sd->params.colourParams.brightness +
1291 TC - 50 + EXP_ACC_LIGHT; 1289 TC - 50 + EXP_ACC_LIGHT;
@@ -1772,9 +1770,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1772/* this function is called at probe and resume time */ 1770/* this function is called at probe and resume time */
1773static int sd_init(struct gspca_dev *gspca_dev) 1771static int sd_init(struct gspca_dev *gspca_dev)
1774{ 1772{
1775#ifdef GSPCA_DEBUG
1776 struct sd *sd = (struct sd *) gspca_dev; 1773 struct sd *sd = (struct sd *) gspca_dev;
1777#endif
1778 int ret; 1774 int ret;
1779 1775
1780 /* Start / Stop the camera to make sure we are talking to 1776 /* Start / Stop the camera to make sure we are talking to
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 99083038cec3..e8e071aa212f 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -499,21 +499,8 @@ MODULE_DEVICE_TABLE(usb, device_table);
499static int sd_probe(struct usb_interface *intf, 499static int sd_probe(struct usb_interface *intf,
500 const struct usb_device_id *id) 500 const struct usb_device_id *id)
501{ 501{
502 struct gspca_dev *gspca_dev; 502 return gspca_dev_probe(intf, id,
503 s32 ret;
504
505 ret = gspca_dev_probe(intf, id,
506 &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE); 503 &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
507
508 if (ret >= 0) {
509 gspca_dev = usb_get_intfdata(intf);
510
511 PDEBUG(D_PROBE,
512 "Camera is now controlling video device %s",
513 video_device_node_name(&gspca_dev->vdev));
514 }
515
516 return ret;
517} 504}
518 505
519static void sd_disconnect(struct usb_interface *intf) 506static void sd_disconnect(struct usb_interface *intf)
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index e526aa3dedaf..08ce9948d99b 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
55MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 55MODULE_DESCRIPTION("GSPCA USB Camera Driver");
56MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
57 57
58#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 12, 0) 58#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 13, 0)
59 59
60#ifdef GSPCA_DEBUG 60#ifdef GSPCA_DEBUG
61int gspca_debug = D_ERR | D_PROBE; 61int gspca_debug = D_ERR | D_PROBE;
@@ -2495,6 +2495,6 @@ module_exit(gspca_exit);
2495module_param_named(debug, gspca_debug, int, 0644); 2495module_param_named(debug, gspca_debug, int, 0644);
2496MODULE_PARM_DESC(debug, 2496MODULE_PARM_DESC(debug,
2497 "Debug (bit) 0x01:error 0x02:probe 0x04:config" 2497 "Debug (bit) 0x01:error 0x02:probe 0x04:config"
2498 " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" 2498 " 0x08:stream 0x10:frame 0x20:packet"
2499 " 0x0100: v4l2"); 2499 " 0x0100: v4l2");
2500#endif 2500#endif
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 41755226d389..49e2fcbe81fb 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -9,7 +9,7 @@
9#include <linux/mutex.h> 9#include <linux/mutex.h>
10 10
11/* compilation option */ 11/* compilation option */
12#define GSPCA_DEBUG 1 12/*#define GSPCA_DEBUG 1*/
13 13
14#ifdef GSPCA_DEBUG 14#ifdef GSPCA_DEBUG
15/* GSPCA our debug messages */ 15/* GSPCA our debug messages */
@@ -25,8 +25,8 @@ extern int gspca_debug;
25#define D_STREAM 0x08 25#define D_STREAM 0x08
26#define D_FRAM 0x10 26#define D_FRAM 0x10
27#define D_PACK 0x20 27#define D_PACK 0x20
28#define D_USBI 0x40 28#define D_USBI 0x00
29#define D_USBO 0x80 29#define D_USBO 0x00
30#define D_V4L2 0x0100 30#define D_V4L2 0x0100
31#else 31#else
32#define PDEBUG(level, fmt, args...) 32#define PDEBUG(level, fmt, args...)
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index 36dae38b1e38..1bd9c4b542dd 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -6,6 +6,9 @@
6 * 6 *
7 * Copyright (C) 2009 Theodore Kilgore 7 * Copyright (C) 2009 Theodore Kilgore
8 * 8 *
9 * Sportscam DV15 support and control settings are
10 * Copyright (C) 2011 Patrice Chotard
11 *
9 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 14 * the Free Software Foundation; either version 2 of the License, or
@@ -23,7 +26,6 @@
23 26
24#define MODULE_NAME "jeilinj" 27#define MODULE_NAME "jeilinj"
25 28
26#include <linux/workqueue.h>
27#include <linux/slab.h> 29#include <linux/slab.h>
28#include "gspca.h" 30#include "gspca.h"
29#include "jpeg.h" 31#include "jpeg.h"
@@ -34,29 +36,51 @@ MODULE_LICENSE("GPL");
34 36
35/* Default timeouts, in ms */ 37/* Default timeouts, in ms */
36#define JEILINJ_CMD_TIMEOUT 500 38#define JEILINJ_CMD_TIMEOUT 500
39#define JEILINJ_CMD_DELAY 160
37#define JEILINJ_DATA_TIMEOUT 1000 40#define JEILINJ_DATA_TIMEOUT 1000
38 41
39/* Maximum transfer size to use. */ 42/* Maximum transfer size to use. */
40#define JEILINJ_MAX_TRANSFER 0x200 43#define JEILINJ_MAX_TRANSFER 0x200
41
42#define FRAME_HEADER_LEN 0x10 44#define FRAME_HEADER_LEN 0x10
45#define FRAME_START 0xFFFFFFFF
46
47enum {
48 SAKAR_57379,
49 SPORTSCAM_DV15,
50};
51
52#define CAMQUALITY_MIN 0 /* highest cam quality */
53#define CAMQUALITY_MAX 97 /* lowest cam quality */
54
55enum e_ctrl {
56 LIGHTFREQ,
57 AUTOGAIN,
58 RED,
59 GREEN,
60 BLUE,
61 NCTRLS /* number of controls */
62};
43 63
44/* Structure to hold all of our device specific stuff */ 64/* Structure to hold all of our device specific stuff */
45struct sd { 65struct sd {
46 struct gspca_dev gspca_dev; /* !! must be the first item */ 66 struct gspca_dev gspca_dev; /* !! must be the first item */
67 struct gspca_ctrl ctrls[NCTRLS];
68 int blocks_left;
47 const struct v4l2_pix_format *cap_mode; 69 const struct v4l2_pix_format *cap_mode;
48 /* Driver stuff */ 70 /* Driver stuff */
49 struct work_struct work_struct; 71 u8 type;
50 struct workqueue_struct *work_thread;
51 u8 quality; /* image quality */ 72 u8 quality; /* image quality */
52 u8 jpegqual; /* webcam quality */ 73#define QUALITY_MIN 35
74#define QUALITY_MAX 85
75#define QUALITY_DEF 85
53 u8 jpeg_hdr[JPEG_HDR_SZ]; 76 u8 jpeg_hdr[JPEG_HDR_SZ];
54}; 77};
55 78
56 struct jlj_command { 79struct jlj_command {
57 unsigned char instruction[2]; 80 unsigned char instruction[2];
58 unsigned char ack_wanted; 81 unsigned char ack_wanted;
59 }; 82 unsigned char delay;
83};
60 84
61/* AFAICT these cameras will only do 320x240. */ 85/* AFAICT these cameras will only do 320x240. */
62static struct v4l2_pix_format jlj_mode[] = { 86static struct v4l2_pix_format jlj_mode[] = {
@@ -64,6 +88,11 @@ static struct v4l2_pix_format jlj_mode[] = {
64 .bytesperline = 320, 88 .bytesperline = 320,
65 .sizeimage = 320 * 240, 89 .sizeimage = 320 * 240,
66 .colorspace = V4L2_COLORSPACE_JPEG, 90 .colorspace = V4L2_COLORSPACE_JPEG,
91 .priv = 0},
92 { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
93 .bytesperline = 640,
94 .sizeimage = 640 * 480,
95 .colorspace = V4L2_COLORSPACE_JPEG,
67 .priv = 0} 96 .priv = 0}
68}; 97};
69 98
@@ -73,178 +102,295 @@ static struct v4l2_pix_format jlj_mode[] = {
73 */ 102 */
74 103
75/* All commands are two bytes only */ 104/* All commands are two bytes only */
76static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command) 105static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
77{ 106{
78 int retval; 107 int retval;
79 108
109 if (gspca_dev->usb_err < 0)
110 return;
80 memcpy(gspca_dev->usb_buf, command, 2); 111 memcpy(gspca_dev->usb_buf, command, 2);
81 retval = usb_bulk_msg(gspca_dev->dev, 112 retval = usb_bulk_msg(gspca_dev->dev,
82 usb_sndbulkpipe(gspca_dev->dev, 3), 113 usb_sndbulkpipe(gspca_dev->dev, 3),
83 gspca_dev->usb_buf, 2, NULL, 500); 114 gspca_dev->usb_buf, 2, NULL, 500);
84 if (retval < 0) 115 if (retval < 0) {
85 err("command write [%02x] error %d", 116 err("command write [%02x] error %d",
86 gspca_dev->usb_buf[0], retval); 117 gspca_dev->usb_buf[0], retval);
87 return retval; 118 gspca_dev->usb_err = retval;
119 }
88} 120}
89 121
90/* Responses are one byte only */ 122/* Responses are one byte only */
91static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response) 123static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
92{ 124{
93 int retval; 125 int retval;
94 126
127 if (gspca_dev->usb_err < 0)
128 return;
95 retval = usb_bulk_msg(gspca_dev->dev, 129 retval = usb_bulk_msg(gspca_dev->dev,
96 usb_rcvbulkpipe(gspca_dev->dev, 0x84), 130 usb_rcvbulkpipe(gspca_dev->dev, 0x84),
97 gspca_dev->usb_buf, 1, NULL, 500); 131 gspca_dev->usb_buf, 1, NULL, 500);
98 response = gspca_dev->usb_buf[0]; 132 response = gspca_dev->usb_buf[0];
99 if (retval < 0) 133 if (retval < 0) {
100 err("read command [%02x] error %d", 134 err("read command [%02x] error %d",
101 gspca_dev->usb_buf[0], retval); 135 gspca_dev->usb_buf[0], retval);
102 return retval; 136 gspca_dev->usb_err = retval;
137 }
103} 138}
104 139
105static int jlj_start(struct gspca_dev *gspca_dev) 140static void setfreq(struct gspca_dev *gspca_dev)
106{ 141{
107 int i; 142 struct sd *sd = (struct sd *) gspca_dev;
108 int retval = -1; 143 u8 freq_commands[][2] = {
109 u8 response = 0xff; 144 {0x71, 0x80},
110 struct jlj_command start_commands[] = { 145 {0x70, 0x07}
111 {{0x71, 0x81}, 0},
112 {{0x70, 0x05}, 0},
113 {{0x95, 0x70}, 1},
114 {{0x71, 0x81}, 0},
115 {{0x70, 0x04}, 0},
116 {{0x95, 0x70}, 1},
117 {{0x71, 0x00}, 0},
118 {{0x70, 0x08}, 0},
119 {{0x95, 0x70}, 1},
120 {{0x94, 0x02}, 0},
121 {{0xde, 0x24}, 0},
122 {{0x94, 0x02}, 0},
123 {{0xdd, 0xf0}, 0},
124 {{0x94, 0x02}, 0},
125 {{0xe3, 0x2c}, 0},
126 {{0x94, 0x02}, 0},
127 {{0xe4, 0x00}, 0},
128 {{0x94, 0x02}, 0},
129 {{0xe5, 0x00}, 0},
130 {{0x94, 0x02}, 0},
131 {{0xe6, 0x2c}, 0},
132 {{0x94, 0x03}, 0},
133 {{0xaa, 0x00}, 0},
134 {{0x71, 0x1e}, 0},
135 {{0x70, 0x06}, 0},
136 {{0x71, 0x80}, 0},
137 {{0x70, 0x07}, 0}
138 }; 146 };
139 for (i = 0; i < ARRAY_SIZE(start_commands); i++) { 147
140 retval = jlj_write2(gspca_dev, start_commands[i].instruction); 148 freq_commands[0][1] |= (sd->ctrls[LIGHTFREQ].val >> 1);
141 if (retval < 0) 149
142 return retval; 150 jlj_write2(gspca_dev, freq_commands[0]);
143 if (start_commands[i].ack_wanted) 151 jlj_write2(gspca_dev, freq_commands[1]);
144 retval = jlj_read1(gspca_dev, response);
145 if (retval < 0)
146 return retval;
147 }
148 PDEBUG(D_ERR, "jlj_start retval is %d", retval);
149 return retval;
150} 152}
151 153
152static int jlj_stop(struct gspca_dev *gspca_dev) 154static void setcamquality(struct gspca_dev *gspca_dev)
155{
156 struct sd *sd = (struct sd *) gspca_dev;
157 u8 quality_commands[][2] = {
158 {0x71, 0x1E},
159 {0x70, 0x06}
160 };
161 u8 camquality;
162
163 /* adapt camera quality from jpeg quality */
164 camquality = ((QUALITY_MAX - sd->quality) * CAMQUALITY_MAX)
165 / (QUALITY_MAX - QUALITY_MIN);
166 quality_commands[0][1] += camquality;
167
168 jlj_write2(gspca_dev, quality_commands[0]);
169 jlj_write2(gspca_dev, quality_commands[1]);
170}
171
172static void setautogain(struct gspca_dev *gspca_dev)
173{
174 struct sd *sd = (struct sd *) gspca_dev;
175 u8 autogain_commands[][2] = {
176 {0x94, 0x02},
177 {0xcf, 0x00}
178 };
179
180 autogain_commands[1][1] = (sd->ctrls[AUTOGAIN].val << 4);
181
182 jlj_write2(gspca_dev, autogain_commands[0]);
183 jlj_write2(gspca_dev, autogain_commands[1]);
184}
185
186static void setred(struct gspca_dev *gspca_dev)
187{
188 struct sd *sd = (struct sd *) gspca_dev;
189 u8 setred_commands[][2] = {
190 {0x94, 0x02},
191 {0xe6, 0x00}
192 };
193
194 setred_commands[1][1] = sd->ctrls[RED].val;
195
196 jlj_write2(gspca_dev, setred_commands[0]);
197 jlj_write2(gspca_dev, setred_commands[1]);
198}
199
200static void setgreen(struct gspca_dev *gspca_dev)
201{
202 struct sd *sd = (struct sd *) gspca_dev;
203 u8 setgreen_commands[][2] = {
204 {0x94, 0x02},
205 {0xe7, 0x00}
206 };
207
208 setgreen_commands[1][1] = sd->ctrls[GREEN].val;
209
210 jlj_write2(gspca_dev, setgreen_commands[0]);
211 jlj_write2(gspca_dev, setgreen_commands[1]);
212}
213
214static void setblue(struct gspca_dev *gspca_dev)
215{
216 struct sd *sd = (struct sd *) gspca_dev;
217 u8 setblue_commands[][2] = {
218 {0x94, 0x02},
219 {0xe9, 0x00}
220 };
221
222 setblue_commands[1][1] = sd->ctrls[BLUE].val;
223
224 jlj_write2(gspca_dev, setblue_commands[0]);
225 jlj_write2(gspca_dev, setblue_commands[1]);
226}
227
228static const struct ctrl sd_ctrls[NCTRLS] = {
229[LIGHTFREQ] = {
230 {
231 .id = V4L2_CID_POWER_LINE_FREQUENCY,
232 .type = V4L2_CTRL_TYPE_MENU,
233 .name = "Light frequency filter",
234 .minimum = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, /* 1 */
235 .maximum = V4L2_CID_POWER_LINE_FREQUENCY_60HZ, /* 2 */
236 .step = 1,
237 .default_value = V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
238 },
239 .set_control = setfreq
240 },
241[AUTOGAIN] = {
242 {
243 .id = V4L2_CID_AUTOGAIN,
244 .type = V4L2_CTRL_TYPE_INTEGER,
245 .name = "Automatic Gain (and Exposure)",
246 .minimum = 0,
247 .maximum = 3,
248 .step = 1,
249#define AUTOGAIN_DEF 0
250 .default_value = AUTOGAIN_DEF,
251 },
252 .set_control = setautogain
253 },
254[RED] = {
255 {
256 .id = V4L2_CID_RED_BALANCE,
257 .type = V4L2_CTRL_TYPE_INTEGER,
258 .name = "red balance",
259 .minimum = 0,
260 .maximum = 3,
261 .step = 1,
262#define RED_BALANCE_DEF 2
263 .default_value = RED_BALANCE_DEF,
264 },
265 .set_control = setred
266 },
267
268[GREEN] = {
269 {
270 .id = V4L2_CID_GAIN,
271 .type = V4L2_CTRL_TYPE_INTEGER,
272 .name = "green balance",
273 .minimum = 0,
274 .maximum = 3,
275 .step = 1,
276#define GREEN_BALANCE_DEF 2
277 .default_value = GREEN_BALANCE_DEF,
278 },
279 .set_control = setgreen
280 },
281[BLUE] = {
282 {
283 .id = V4L2_CID_BLUE_BALANCE,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "blue balance",
286 .minimum = 0,
287 .maximum = 3,
288 .step = 1,
289#define BLUE_BALANCE_DEF 2
290 .default_value = BLUE_BALANCE_DEF,
291 },
292 .set_control = setblue
293 },
294};
295
296static int jlj_start(struct gspca_dev *gspca_dev)
153{ 297{
154 int i; 298 int i;
155 int retval; 299 int start_commands_size;
156 struct jlj_command stop_commands[] = { 300 u8 response = 0xff;
157 {{0x71, 0x00}, 0}, 301 struct sd *sd = (struct sd *) gspca_dev;
158 {{0x70, 0x09}, 0}, 302 struct jlj_command start_commands[] = {
159 {{0x71, 0x80}, 0}, 303 {{0x71, 0x81}, 0, 0},
160 {{0x70, 0x05}, 0} 304 {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
305 {{0x95, 0x70}, 1, 0},
306 {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
307 {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
308 {{0x95, 0x70}, 1, 0},
309 {{0x71, 0x00}, 0, 0}, /* start streaming ??*/
310 {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
311 {{0x95, 0x70}, 1, 0},
312#define SPORTSCAM_DV15_CMD_SIZE 9
313 {{0x94, 0x02}, 0, 0},
314 {{0xde, 0x24}, 0, 0},
315 {{0x94, 0x02}, 0, 0},
316 {{0xdd, 0xf0}, 0, 0},
317 {{0x94, 0x02}, 0, 0},
318 {{0xe3, 0x2c}, 0, 0},
319 {{0x94, 0x02}, 0, 0},
320 {{0xe4, 0x00}, 0, 0},
321 {{0x94, 0x02}, 0, 0},
322 {{0xe5, 0x00}, 0, 0},
323 {{0x94, 0x02}, 0, 0},
324 {{0xe6, 0x2c}, 0, 0},
325 {{0x94, 0x03}, 0, 0},
326 {{0xaa, 0x00}, 0, 0}
161 }; 327 };
162 for (i = 0; i < ARRAY_SIZE(stop_commands); i++) { 328
163 retval = jlj_write2(gspca_dev, stop_commands[i].instruction); 329 sd->blocks_left = 0;
164 if (retval < 0) 330 /* Under Windows, USB spy shows that only the 9 first start
165 return retval; 331 * commands are used for SPORTSCAM_DV15 webcam
332 */
333 if (sd->type == SPORTSCAM_DV15)
334 start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
335 else
336 start_commands_size = ARRAY_SIZE(start_commands);
337
338 for (i = 0; i < start_commands_size; i++) {
339 jlj_write2(gspca_dev, start_commands[i].instruction);
340 if (start_commands[i].delay)
341 msleep(start_commands[i].delay);
342 if (start_commands[i].ack_wanted)
343 jlj_read1(gspca_dev, response);
166 } 344 }
167 return retval; 345 setcamquality(gspca_dev);
346 msleep(2);
347 setfreq(gspca_dev);
348 if (gspca_dev->usb_err < 0)
349 PDEBUG(D_ERR, "Start streaming command failed");
350 return gspca_dev->usb_err;
168} 351}
169 352
170/* This function is called as a workqueue function and runs whenever the camera 353static void sd_pkt_scan(struct gspca_dev *gspca_dev,
171 * is streaming data. Because it is a workqueue function it is allowed to sleep 354 u8 *data, int len)
172 * so we can use synchronous USB calls. To avoid possible collisions with other
173 * threads attempting to use the camera's USB interface the gspca usb_lock is
174 * used when performing the one USB control operation inside the workqueue,
175 * which tells the camera to close the stream. In practice the only thing
176 * which needs to be protected against is the usb_set_interface call that
177 * gspca makes during stream_off. Otherwise the camera doesn't provide any
178 * controls that the user could try to change.
179 */
180
181static void jlj_dostream(struct work_struct *work)
182{ 355{
183 struct sd *dev = container_of(work, struct sd, work_struct); 356 struct sd *sd = (struct sd *) gspca_dev;
184 struct gspca_dev *gspca_dev = &dev->gspca_dev;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int act_len;
187 int packet_type; 357 int packet_type;
188 int ret; 358 u32 header_marker;
189 u8 *buffer;
190 359
191 buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); 360 PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
192 if (!buffer) { 361 len, JEILINJ_MAX_TRANSFER);
193 err("Couldn't allocate USB buffer"); 362 if (len != JEILINJ_MAX_TRANSFER) {
194 goto quit_stream; 363 PDEBUG(D_PACK, "bad length");
364 goto discard;
195 } 365 }
196 while (gspca_dev->present && gspca_dev->streaming) { 366 /* check if it's start of frame */
197 /* 367 header_marker = ((u32 *)data)[0];
198 * Now request data block 0. Line 0 reports the size 368 if (header_marker == FRAME_START) {
199 * to download, in blocks of size 0x200, and also tells the 369 sd->blocks_left = data[0x0a] - 1;
200 * "actual" data size, in bytes, which seems best to ignore. 370 PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
201 */
202 ret = usb_bulk_msg(gspca_dev->dev,
203 usb_rcvbulkpipe(gspca_dev->dev, 0x82),
204 buffer, JEILINJ_MAX_TRANSFER, &act_len,
205 JEILINJ_DATA_TIMEOUT);
206 PDEBUG(D_STREAM,
207 "Got %d bytes out of %d for Block 0",
208 act_len, JEILINJ_MAX_TRANSFER);
209 if (ret < 0 || act_len < FRAME_HEADER_LEN)
210 goto quit_stream;
211 blocks_left = buffer[0x0a] - 1;
212 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
213
214 /* Start a new frame, and add the JPEG header, first thing */ 371 /* Start a new frame, and add the JPEG header, first thing */
215 gspca_frame_add(gspca_dev, FIRST_PACKET, 372 gspca_frame_add(gspca_dev, FIRST_PACKET,
216 dev->jpeg_hdr, JPEG_HDR_SZ); 373 sd->jpeg_hdr, JPEG_HDR_SZ);
217 /* Toss line 0 of data block 0, keep the rest. */ 374 /* Toss line 0 of data block 0, keep the rest. */
218 gspca_frame_add(gspca_dev, INTER_PACKET, 375 gspca_frame_add(gspca_dev, INTER_PACKET,
219 buffer + FRAME_HEADER_LEN, 376 data + FRAME_HEADER_LEN,
220 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN); 377 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
221 378 } else if (sd->blocks_left > 0) {
222 while (blocks_left > 0) { 379 PDEBUG(D_STREAM, "%d blocks remaining for frame",
223 if (!gspca_dev->present) 380 sd->blocks_left);
224 goto quit_stream; 381 sd->blocks_left -= 1;
225 ret = usb_bulk_msg(gspca_dev->dev, 382 if (sd->blocks_left == 0)
226 usb_rcvbulkpipe(gspca_dev->dev, 0x82), 383 packet_type = LAST_PACKET;
227 buffer, JEILINJ_MAX_TRANSFER, &act_len, 384 else
228 JEILINJ_DATA_TIMEOUT); 385 packet_type = INTER_PACKET;
229 if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER) 386 gspca_frame_add(gspca_dev, packet_type,
230 goto quit_stream; 387 data, JEILINJ_MAX_TRANSFER);
231 PDEBUG(D_STREAM, 388 } else
232 "%d blocks remaining for frame", blocks_left); 389 goto discard;
233 blocks_left -= 1; 390 return;
234 if (blocks_left == 0) 391discard:
235 packet_type = LAST_PACKET; 392 /* Discard data until a new frame starts. */
236 else 393 gspca_dev->last_packet_type = DISCARD_PACKET;
237 packet_type = INTER_PACKET;
238 gspca_frame_add(gspca_dev, packet_type,
239 buffer, JEILINJ_MAX_TRANSFER);
240 }
241 }
242quit_stream:
243 mutex_lock(&gspca_dev->usb_lock);
244 if (gspca_dev->present)
245 jlj_stop(gspca_dev);
246 mutex_unlock(&gspca_dev->usb_lock);
247 kfree(buffer);
248} 394}
249 395
250/* This function is called at probe time just before sd_init */ 396/* This function is called at probe time just before sd_init */
@@ -254,78 +400,169 @@ static int sd_config(struct gspca_dev *gspca_dev,
254 struct cam *cam = &gspca_dev->cam; 400 struct cam *cam = &gspca_dev->cam;
255 struct sd *dev = (struct sd *) gspca_dev; 401 struct sd *dev = (struct sd *) gspca_dev;
256 402
257 dev->quality = 85; 403 dev->type = id->driver_info;
258 dev->jpegqual = 85; 404 gspca_dev->cam.ctrls = dev->ctrls;
405 dev->quality = QUALITY_DEF;
406 dev->ctrls[LIGHTFREQ].def = V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
407 dev->ctrls[RED].def = RED_BALANCE_DEF;
408 dev->ctrls[GREEN].def = GREEN_BALANCE_DEF;
409 dev->ctrls[BLUE].def = BLUE_BALANCE_DEF;
259 PDEBUG(D_PROBE, 410 PDEBUG(D_PROBE,
260 "JEILINJ camera detected" 411 "JEILINJ camera detected"
261 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 412 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
262 cam->cam_mode = jlj_mode; 413 cam->cam_mode = jlj_mode;
263 cam->nmodes = 1; 414 cam->nmodes = ARRAY_SIZE(jlj_mode);
264 cam->bulk = 1; 415 cam->bulk = 1;
265 /* We don't use the buffer gspca allocates so make it small. */ 416 cam->bulk_nurbs = 1;
266 cam->bulk_size = 32; 417 cam->bulk_size = JEILINJ_MAX_TRANSFER;
267 INIT_WORK(&dev->work_struct, jlj_dostream);
268 return 0; 418 return 0;
269} 419}
270 420
271/* called on streamoff with alt==0 and on disconnect */ 421static void sd_stopN(struct gspca_dev *gspca_dev)
272/* the usb_lock is held at entry - restore on exit */
273static void sd_stop0(struct gspca_dev *gspca_dev)
274{ 422{
275 struct sd *dev = (struct sd *) gspca_dev; 423 int i;
424 u8 *buf;
425 u8 stop_commands[][2] = {
426 {0x71, 0x00},
427 {0x70, 0x09},
428 {0x71, 0x80},
429 {0x70, 0x05}
430 };
431
432 for (;;) {
433 /* get the image remaining blocks */
434 usb_bulk_msg(gspca_dev->dev,
435 gspca_dev->urb[0]->pipe,
436 gspca_dev->urb[0]->transfer_buffer,
437 JEILINJ_MAX_TRANSFER, NULL,
438 JEILINJ_DATA_TIMEOUT);
439
440 /* search for 0xff 0xd9 (EOF for JPEG) */
441 i = 0;
442 buf = gspca_dev->urb[0]->transfer_buffer;
443 while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
444 ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
445 i++;
276 446
277 /* wait for the work queue to terminate */ 447 if (i != (JEILINJ_MAX_TRANSFER - 1))
278 mutex_unlock(&gspca_dev->usb_lock); 448 /* last remaining block found */
279 /* This waits for jlj_dostream to finish */ 449 break;
280 destroy_workqueue(dev->work_thread); 450 }
281 dev->work_thread = NULL; 451
282 mutex_lock(&gspca_dev->usb_lock); 452 for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
453 jlj_write2(gspca_dev, stop_commands[i]);
283} 454}
284 455
285/* this function is called at probe and resume time */ 456/* this function is called at probe and resume time */
286static int sd_init(struct gspca_dev *gspca_dev) 457static int sd_init(struct gspca_dev *gspca_dev)
287{ 458{
288 return 0; 459 return gspca_dev->usb_err;
289} 460}
290 461
291/* Set up for getting frames. */ 462/* Set up for getting frames. */
292static int sd_start(struct gspca_dev *gspca_dev) 463static int sd_start(struct gspca_dev *gspca_dev)
293{ 464{
294 struct sd *dev = (struct sd *) gspca_dev; 465 struct sd *dev = (struct sd *) gspca_dev;
295 int ret;
296 466
297 /* create the JPEG header */ 467 /* create the JPEG header */
298 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width, 468 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
299 0x21); /* JPEG 422 */ 469 0x21); /* JPEG 422 */
300 jpeg_set_qual(dev->jpeg_hdr, dev->quality); 470 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
301 PDEBUG(D_STREAM, "Start streaming at 320x240"); 471 PDEBUG(D_STREAM, "Start streaming at %dx%d",
302 ret = jlj_start(gspca_dev); 472 gspca_dev->height, gspca_dev->width);
303 if (ret < 0) { 473 jlj_start(gspca_dev);
304 PDEBUG(D_ERR, "Start streaming command failed"); 474 return gspca_dev->usb_err;
305 return ret;
306 }
307 /* Start the workqueue function to do the streaming */
308 dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
309 queue_work(dev->work_thread, &dev->work_struct);
310
311 return 0;
312} 475}
313 476
314/* Table of supported USB devices */ 477/* Table of supported USB devices */
315static const struct usb_device_id device_table[] = { 478static const struct usb_device_id device_table[] = {
316 {USB_DEVICE(0x0979, 0x0280)}, 479 {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
480 {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
317 {} 481 {}
318}; 482};
319 483
320MODULE_DEVICE_TABLE(usb, device_table); 484MODULE_DEVICE_TABLE(usb, device_table);
321 485
486static int sd_querymenu(struct gspca_dev *gspca_dev,
487 struct v4l2_querymenu *menu)
488{
489 switch (menu->id) {
490 case V4L2_CID_POWER_LINE_FREQUENCY:
491 switch (menu->index) {
492 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
493 strcpy((char *) menu->name, "disable");
494 return 0;
495 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
496 strcpy((char *) menu->name, "50 Hz");
497 return 0;
498 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
499 strcpy((char *) menu->name, "60 Hz");
500 return 0;
501 }
502 break;
503 }
504 return -EINVAL;
505}
506
507static int sd_set_jcomp(struct gspca_dev *gspca_dev,
508 struct v4l2_jpegcompression *jcomp)
509{
510 struct sd *sd = (struct sd *) gspca_dev;
511
512 if (jcomp->quality < QUALITY_MIN)
513 sd->quality = QUALITY_MIN;
514 else if (jcomp->quality > QUALITY_MAX)
515 sd->quality = QUALITY_MAX;
516 else
517 sd->quality = jcomp->quality;
518 if (gspca_dev->streaming) {
519 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
520 setcamquality(gspca_dev);
521 }
522 return 0;
523}
524
525static int sd_get_jcomp(struct gspca_dev *gspca_dev,
526 struct v4l2_jpegcompression *jcomp)
527{
528 struct sd *sd = (struct sd *) gspca_dev;
529
530 memset(jcomp, 0, sizeof *jcomp);
531 jcomp->quality = sd->quality;
532 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
533 | V4L2_JPEG_MARKER_DQT;
534 return 0;
535}
536
537
322/* sub-driver description */ 538/* sub-driver description */
323static const struct sd_desc sd_desc = { 539static const struct sd_desc sd_desc_sakar_57379 = {
324 .name = MODULE_NAME, 540 .name = MODULE_NAME,
325 .config = sd_config, 541 .config = sd_config,
326 .init = sd_init, 542 .init = sd_init,
327 .start = sd_start, 543 .start = sd_start,
328 .stop0 = sd_stop0, 544 .stopN = sd_stopN,
545 .pkt_scan = sd_pkt_scan,
546};
547
548/* sub-driver description */
549static const struct sd_desc sd_desc_sportscam_dv15 = {
550 .name = MODULE_NAME,
551 .config = sd_config,
552 .init = sd_init,
553 .start = sd_start,
554 .stopN = sd_stopN,
555 .pkt_scan = sd_pkt_scan,
556 .ctrls = sd_ctrls,
557 .nctrls = ARRAY_SIZE(sd_ctrls),
558 .querymenu = sd_querymenu,
559 .get_jcomp = sd_get_jcomp,
560 .set_jcomp = sd_set_jcomp,
561};
562
563static const struct sd_desc *sd_desc[2] = {
564 &sd_desc_sakar_57379,
565 &sd_desc_sportscam_dv15
329}; 566};
330 567
331/* -- device connect -- */ 568/* -- device connect -- */
@@ -333,7 +570,7 @@ static int sd_probe(struct usb_interface *intf,
333 const struct usb_device_id *id) 570 const struct usb_device_id *id)
334{ 571{
335 return gspca_dev_probe(intf, id, 572 return gspca_dev_probe(intf, id,
336 &sd_desc, 573 sd_desc[id->driver_info],
337 sizeof(struct sd), 574 sizeof(struct sd),
338 THIS_MODULE); 575 THIS_MODULE);
339} 576}
diff --git a/drivers/media/video/gspca/kinect.c b/drivers/media/video/gspca/kinect.c
new file mode 100644
index 000000000000..66671a4092e4
--- /dev/null
+++ b/drivers/media/video/gspca/kinect.c
@@ -0,0 +1,429 @@
1/*
2 * kinect sensor device camera, gspca driver
3 *
4 * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
5 *
6 * Based on the OpenKinect project and libfreenect
7 * http://openkinect.org/wiki/Init_Analysis
8 *
9 * Special thanks to Steven Toth and kernellabs.com for sponsoring a Kinect
10 * sensor device which I tested the driver on.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#define MODULE_NAME "kinect"
28
29#include "gspca.h"
30
31#define CTRL_TIMEOUT 500
32
33MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
34MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver");
35MODULE_LICENSE("GPL");
36
37#ifdef DEBUG
38int gspca_debug = D_ERR | D_PROBE | D_CONF | D_STREAM | D_FRAM | D_PACK |
39 D_USBI | D_USBO | D_V4L2;
40#endif
41
42struct pkt_hdr {
43 uint8_t magic[2];
44 uint8_t pad;
45 uint8_t flag;
46 uint8_t unk1;
47 uint8_t seq;
48 uint8_t unk2;
49 uint8_t unk3;
50 uint32_t timestamp;
51};
52
53struct cam_hdr {
54 uint8_t magic[2];
55 uint16_t len;
56 uint16_t cmd;
57 uint16_t tag;
58};
59
60/* specific webcam descriptor */
61struct sd {
62 struct gspca_dev gspca_dev; /* !! must be the first item */
63 uint16_t cam_tag; /* a sequence number for packets */
64 uint8_t stream_flag; /* to identify different stream types */
65 uint8_t obuf[0x400]; /* output buffer for control commands */
66 uint8_t ibuf[0x200]; /* input buffer for control commands */
67};
68
69/* V4L2 controls supported by the driver */
70/* controls prototypes here */
71
72static const struct ctrl sd_ctrls[] = {
73};
74
75#define MODE_640x480 0x0001
76#define MODE_640x488 0x0002
77#define MODE_1280x1024 0x0004
78
79#define FORMAT_BAYER 0x0010
80#define FORMAT_UYVY 0x0020
81#define FORMAT_Y10B 0x0040
82
83#define FPS_HIGH 0x0100
84
85static const struct v4l2_pix_format video_camera_mode[] = {
86 {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
87 .bytesperline = 640,
88 .sizeimage = 640 * 480,
89 .colorspace = V4L2_COLORSPACE_SRGB,
90 .priv = MODE_640x480 | FORMAT_BAYER | FPS_HIGH},
91 {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
92 .bytesperline = 640 * 2,
93 .sizeimage = 640 * 480 * 2,
94 .colorspace = V4L2_COLORSPACE_SRGB,
95 .priv = MODE_640x480 | FORMAT_UYVY},
96 {1280, 1024, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
97 .bytesperline = 1280,
98 .sizeimage = 1280 * 1024,
99 .colorspace = V4L2_COLORSPACE_SRGB,
100 .priv = MODE_1280x1024 | FORMAT_BAYER},
101 {640, 488, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
102 .bytesperline = 640 * 10 / 8,
103 .sizeimage = 640 * 488 * 10 / 8,
104 .colorspace = V4L2_COLORSPACE_SRGB,
105 .priv = MODE_640x488 | FORMAT_Y10B | FPS_HIGH},
106 {1280, 1024, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
107 .bytesperline = 1280 * 10 / 8,
108 .sizeimage = 1280 * 1024 * 10 / 8,
109 .colorspace = V4L2_COLORSPACE_SRGB,
110 .priv = MODE_1280x1024 | FORMAT_Y10B},
111};
112
113static int kinect_write(struct usb_device *udev, uint8_t *data,
114 uint16_t wLength)
115{
116 return usb_control_msg(udev,
117 usb_sndctrlpipe(udev, 0),
118 0x00,
119 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
120 0, 0, data, wLength, CTRL_TIMEOUT);
121}
122
123static int kinect_read(struct usb_device *udev, uint8_t *data, uint16_t wLength)
124{
125 return usb_control_msg(udev,
126 usb_rcvctrlpipe(udev, 0),
127 0x00,
128 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
129 0, 0, data, wLength, CTRL_TIMEOUT);
130}
131
132static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
133 unsigned int cmd_len, void *replybuf, unsigned int reply_len)
134{
135 struct sd *sd = (struct sd *) gspca_dev;
136 struct usb_device *udev = gspca_dev->dev;
137 int res, actual_len;
138 uint8_t *obuf = sd->obuf;
139 uint8_t *ibuf = sd->ibuf;
140 struct cam_hdr *chdr = (void *)obuf;
141 struct cam_hdr *rhdr = (void *)ibuf;
142
143 if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) {
144 err("send_cmd: Invalid command length (0x%x)", cmd_len);
145 return -1;
146 }
147
148 chdr->magic[0] = 0x47;
149 chdr->magic[1] = 0x4d;
150 chdr->cmd = cpu_to_le16(cmd);
151 chdr->tag = cpu_to_le16(sd->cam_tag);
152 chdr->len = cpu_to_le16(cmd_len / 2);
153
154 memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
155
156 res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
157 PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd,
158 sd->cam_tag, cmd_len, res);
159 if (res < 0) {
160 err("send_cmd: Output control transfer failed (%d)", res);
161 return res;
162 }
163
164 do {
165 actual_len = kinect_read(udev, ibuf, 0x200);
166 } while (actual_len == 0);
167 PDEBUG(D_USBO, "Control reply: %d", res);
168 if (actual_len < sizeof(*rhdr)) {
169 err("send_cmd: Input control transfer failed (%d)", res);
170 return res;
171 }
172 actual_len -= sizeof(*rhdr);
173
174 if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
175 err("send_cmd: Bad magic %02x %02x", rhdr->magic[0],
176 rhdr->magic[1]);
177 return -1;
178 }
179 if (rhdr->cmd != chdr->cmd) {
180 err("send_cmd: Bad cmd %02x != %02x", rhdr->cmd, chdr->cmd);
181 return -1;
182 }
183 if (rhdr->tag != chdr->tag) {
184 err("send_cmd: Bad tag %04x != %04x", rhdr->tag, chdr->tag);
185 return -1;
186 }
187 if (cpu_to_le16(rhdr->len) != (actual_len/2)) {
188 err("send_cmd: Bad len %04x != %04x",
189 cpu_to_le16(rhdr->len), (int)(actual_len/2));
190 return -1;
191 }
192
193 if (actual_len > reply_len) {
194 warn("send_cmd: Data buffer is %d bytes long, but got %d bytes",
195 reply_len, actual_len);
196 memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len);
197 } else {
198 memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len);
199 }
200
201 sd->cam_tag++;
202
203 return actual_len;
204}
205
206static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
207 uint16_t data)
208{
209 uint16_t reply[2];
210 uint16_t cmd[2];
211 int res;
212
213 cmd[0] = cpu_to_le16(reg);
214 cmd[1] = cpu_to_le16(data);
215
216 PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data);
217 res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
218 if (res < 0)
219 return res;
220 if (res != 2) {
221 warn("send_cmd returned %d [%04x %04x], 0000 expected",
222 res, reply[0], reply[1]);
223 }
224 return 0;
225}
226
227/* this function is called at probe time */
228static int sd_config(struct gspca_dev *gspca_dev,
229 const struct usb_device_id *id)
230{
231 struct sd *sd = (struct sd *) gspca_dev;
232 struct cam *cam;
233
234 sd->cam_tag = 0;
235
236 /* Only video stream is supported for now,
237 * which has stream flag = 0x80 */
238 sd->stream_flag = 0x80;
239
240 cam = &gspca_dev->cam;
241
242 cam->cam_mode = video_camera_mode;
243 cam->nmodes = ARRAY_SIZE(video_camera_mode);
244
245#if 0
246 /* Setting those values is not needed for video stream */
247 cam->npkt = 15;
248 gspca_dev->pkt_size = 960 * 2;
249#endif
250
251 return 0;
252}
253
254/* this function is called at probe and resume time */
255static int sd_init(struct gspca_dev *gspca_dev)
256{
257 PDEBUG(D_PROBE, "Kinect Camera device.");
258
259 return 0;
260}
261
262static int sd_start(struct gspca_dev *gspca_dev)
263{
264 int mode;
265 uint8_t fmt_reg, fmt_val;
266 uint8_t res_reg, res_val;
267 uint8_t fps_reg, fps_val;
268 uint8_t mode_val;
269
270 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
271
272 if (mode & FORMAT_Y10B) {
273 fmt_reg = 0x19;
274 res_reg = 0x1a;
275 fps_reg = 0x1b;
276 mode_val = 0x03;
277 } else {
278 fmt_reg = 0x0c;
279 res_reg = 0x0d;
280 fps_reg = 0x0e;
281 mode_val = 0x01;
282 }
283
284 /* format */
285 if (mode & FORMAT_UYVY)
286 fmt_val = 0x05;
287 else
288 fmt_val = 0x00;
289
290 if (mode & MODE_1280x1024)
291 res_val = 0x02;
292 else
293 res_val = 0x01;
294
295 if (mode & FPS_HIGH)
296 fps_val = 0x1e;
297 else
298 fps_val = 0x0f;
299
300
301 /* turn off IR-reset function */
302 write_register(gspca_dev, 0x105, 0x00);
303
304 /* Reset video stream */
305 write_register(gspca_dev, 0x05, 0x00);
306
307 /* Due to some ridiculous condition in the firmware, we have to start
308 * and stop the depth stream before the camera will hand us 1280x1024
309 * IR. This is a stupid workaround, but we've yet to find a better
310 * solution.
311 *
312 * Thanks to Drew Fisher for figuring this out.
313 */
314 if (mode & (FORMAT_Y10B | MODE_1280x1024)) {
315 write_register(gspca_dev, 0x13, 0x01);
316 write_register(gspca_dev, 0x14, 0x1e);
317 write_register(gspca_dev, 0x06, 0x02);
318 write_register(gspca_dev, 0x06, 0x00);
319 }
320
321 write_register(gspca_dev, fmt_reg, fmt_val);
322 write_register(gspca_dev, res_reg, res_val);
323 write_register(gspca_dev, fps_reg, fps_val);
324
325 /* Start video stream */
326 write_register(gspca_dev, 0x05, mode_val);
327
328 /* disable Hflip */
329 write_register(gspca_dev, 0x47, 0x00);
330
331 return 0;
332}
333
334static void sd_stopN(struct gspca_dev *gspca_dev)
335{
336 /* reset video stream */
337 write_register(gspca_dev, 0x05, 0x00);
338}
339
340static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
341{
342 struct sd *sd = (struct sd *) gspca_dev;
343
344 struct pkt_hdr *hdr = (void *)__data;
345 uint8_t *data = __data + sizeof(*hdr);
346 int datalen = len - sizeof(*hdr);
347
348 uint8_t sof = sd->stream_flag | 1;
349 uint8_t mof = sd->stream_flag | 2;
350 uint8_t eof = sd->stream_flag | 5;
351
352 if (len < 12)
353 return;
354
355 if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
356 warn("[Stream %02x] Invalid magic %02x%02x", sd->stream_flag,
357 hdr->magic[0], hdr->magic[1]);
358 return;
359 }
360
361 if (hdr->flag == sof)
362 gspca_frame_add(gspca_dev, FIRST_PACKET, data, datalen);
363
364 else if (hdr->flag == mof)
365 gspca_frame_add(gspca_dev, INTER_PACKET, data, datalen);
366
367 else if (hdr->flag == eof)
368 gspca_frame_add(gspca_dev, LAST_PACKET, data, datalen);
369
370 else
371 warn("Packet type not recognized...");
372}
373
374/* sub-driver description */
375static const struct sd_desc sd_desc = {
376 .name = MODULE_NAME,
377 .ctrls = sd_ctrls,
378 .nctrls = ARRAY_SIZE(sd_ctrls),
379 .config = sd_config,
380 .init = sd_init,
381 .start = sd_start,
382 .stopN = sd_stopN,
383 .pkt_scan = sd_pkt_scan,
384 /*
385 .querymenu = sd_querymenu,
386 .get_streamparm = sd_get_streamparm,
387 .set_streamparm = sd_set_streamparm,
388 */
389};
390
391/* -- module initialisation -- */
392static const struct usb_device_id device_table[] = {
393 {USB_DEVICE(0x045e, 0x02ae)},
394 {}
395};
396
397MODULE_DEVICE_TABLE(usb, device_table);
398
399/* -- device connect -- */
400static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
401{
402 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
403 THIS_MODULE);
404}
405
406static struct usb_driver sd_driver = {
407 .name = MODULE_NAME,
408 .id_table = device_table,
409 .probe = sd_probe,
410 .disconnect = gspca_disconnect,
411#ifdef CONFIG_PM
412 .suspend = gspca_suspend,
413 .resume = gspca_resume,
414#endif
415};
416
417/* -- module insert / remove -- */
418static int __init sd_mod_init(void)
419{
420 return usb_register(&sd_driver);
421}
422
423static void __exit sd_mod_exit(void)
424{
425 usb_deregister(&sd_driver);
426}
427
428module_init(sd_mod_init);
429module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 41dce49fb43d..9d0b46027b93 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1375,7 +1375,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1375{ 1375{
1376 struct sd *sd = (struct sd *) gspca_dev; 1376 struct sd *sd = (struct sd *) gspca_dev;
1377 struct cam *cam; 1377 struct cam *cam;
1378 int data1, data2;
1379 const u16 (*init_data)[2]; 1378 const u16 (*init_data)[2];
1380 static const u16 (*(init_data_tb[]))[2] = { 1379 static const u16 (*(init_data_tb[]))[2] = {
1381 spca508_vista_init_data, /* CreativeVista 0 */ 1380 spca508_vista_init_data, /* CreativeVista 0 */
@@ -1386,6 +1385,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
1386 spca508_init_data, /* ViewQuestVQ110 5 */ 1385 spca508_init_data, /* ViewQuestVQ110 5 */
1387 }; 1386 };
1388 1387
1388#ifdef GSPCA_DEBUG
1389 int data1, data2;
1390
1389 /* Read from global register the USB product and vendor IDs, just to 1391 /* Read from global register the USB product and vendor IDs, just to
1390 * prove that we can communicate with the device. This works, which 1392 * prove that we can communicate with the device. This works, which
1391 * confirms at we are communicating properly and that the device 1393 * confirms at we are communicating properly and that the device
@@ -1400,6 +1402,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1400 1402
1401 data1 = reg_read(gspca_dev, 0x8621); 1403 data1 = reg_read(gspca_dev, 0x8621);
1402 PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); 1404 PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
1405#endif
1403 1406
1404 cam = &gspca_dev->cam; 1407 cam = &gspca_dev->cam;
1405 cam->cam_mode = sif_mode; 1408 cam->cam_mode = sif_mode;
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 87be52b5e1e3..763747700f10 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -436,17 +436,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
436static int sd_querymenu(struct gspca_dev *gspca_dev, 436static int sd_querymenu(struct gspca_dev *gspca_dev,
437 struct v4l2_querymenu *menu) 437 struct v4l2_querymenu *menu)
438{ 438{
439 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
440
439 switch (menu->id) { 441 switch (menu->id) {
440 case V4L2_CID_POWER_LINE_FREQUENCY: 442 case V4L2_CID_POWER_LINE_FREQUENCY:
441 switch (menu->index) { 443 if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
442 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ 444 break;
443 strcpy((char *) menu->name, "50 Hz"); 445 strcpy((char *) menu->name, freq_nm[menu->index]);
444 return 0; 446 return 0;
445 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
446 strcpy((char *) menu->name, "60 Hz");
447 return 0;
448 }
449 break;
450 } 447 }
451 return -EINVAL; 448 return -EINVAL;
452} 449}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index ac47b4c94388..75a5b9c2f15f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -217,6 +217,8 @@ static int pb0100_start(struct sd *sd)
217 217
218 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); 218 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
219 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); 219 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
220 if (!alt)
221 return -ENODEV;
220 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); 222 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
221 223
222 /* If we don't have enough bandwidth use a lower framerate */ 224 /* If we don't have enough bandwidth use a lower framerate */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 543542af2720..b089c0d3ee9f 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -396,57 +396,6 @@ static void reg_w_riv(struct gspca_dev *gspca_dev,
396 req, index, value); 396 req, index, value);
397} 397}
398 398
399/* read 1 byte */
400static u8 reg_r_1(struct gspca_dev *gspca_dev,
401 u16 value) /* wValue */
402{
403 int ret;
404
405 if (gspca_dev->usb_err < 0)
406 return 0;
407 ret = usb_control_msg(gspca_dev->dev,
408 usb_rcvctrlpipe(gspca_dev->dev, 0),
409 0x20, /* request */
410 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
411 value,
412 0, /* index */
413 gspca_dev->usb_buf, 1,
414 500); /* timeout */
415 if (ret < 0) {
416 err("reg_r_1 err %d", ret);
417 gspca_dev->usb_err = ret;
418 return 0;
419 }
420 return gspca_dev->usb_buf[0];
421}
422
423/* read 1 or 2 bytes */
424static u16 reg_r_12(struct gspca_dev *gspca_dev,
425 u8 req, /* bRequest */
426 u16 index, /* wIndex */
427 u16 length) /* wLength (1 or 2 only) */
428{
429 int ret;
430
431 if (gspca_dev->usb_err < 0)
432 return 0;
433 gspca_dev->usb_buf[1] = 0;
434 ret = usb_control_msg(gspca_dev->dev,
435 usb_rcvctrlpipe(gspca_dev->dev, 0),
436 req,
437 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
438 0, /* value */
439 index,
440 gspca_dev->usb_buf, length,
441 500);
442 if (ret < 0) {
443 err("reg_r_12 err %d", ret);
444 gspca_dev->usb_err = ret;
445 return 0;
446 }
447 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
448}
449
450static void write_vector(struct gspca_dev *gspca_dev, 399static void write_vector(struct gspca_dev *gspca_dev,
451 const struct cmd *data, int ncmds) 400 const struct cmd *data, int ncmds)
452{ 401{
@@ -473,44 +422,46 @@ static void setup_qtable(struct gspca_dev *gspca_dev,
473static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, 422static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
474 u8 req, u16 idx, u16 val) 423 u8 req, u16 idx, u16 val)
475{ 424{
476 u16 notdone;
477
478 reg_w_riv(gspca_dev, req, idx, val); 425 reg_w_riv(gspca_dev, req, idx, val);
479 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 426 reg_r(gspca_dev, 0x01, 0x0001, 1);
427 PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
480 reg_w_riv(gspca_dev, req, idx, val); 428 reg_w_riv(gspca_dev, req, idx, val);
481 429
482 PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
483
484 msleep(200); 430 msleep(200);
485 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 431 reg_r(gspca_dev, 0x01, 0x0001, 1);
486 PDEBUG(D_FRAM, "after wait 0x%04x", notdone); 432 PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
487} 433}
488 434
435#ifdef GSPCA_DEBUG
489static void spca504_read_info(struct gspca_dev *gspca_dev) 436static void spca504_read_info(struct gspca_dev *gspca_dev)
490{ 437{
491 int i; 438 int i;
492 u8 info[6]; 439 u8 info[6];
493 440
494 for (i = 0; i < 6; i++) 441 for (i = 0; i < 6; i++) {
495 info[i] = reg_r_1(gspca_dev, i); 442 reg_r(gspca_dev, 0, i, 1);
443 info[i] = gspca_dev->usb_buf[0];
444 }
496 PDEBUG(D_STREAM, 445 PDEBUG(D_STREAM,
497 "Read info: %d %d %d %d %d %d." 446 "Read info: %d %d %d %d %d %d."
498 " Should be 1,0,2,2,0,0", 447 " Should be 1,0,2,2,0,0",
499 info[0], info[1], info[2], 448 info[0], info[1], info[2],
500 info[3], info[4], info[5]); 449 info[3], info[4], info[5]);
501} 450}
451#endif
502 452
503static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, 453static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
504 u8 req, 454 u8 req,
505 u16 idx, u16 val, u16 endcode, u8 count) 455 u16 idx, u16 val, u8 endcode, u8 count)
506{ 456{
507 u16 status; 457 u16 status;
508 458
509 reg_w_riv(gspca_dev, req, idx, val); 459 reg_w_riv(gspca_dev, req, idx, val);
510 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 460 reg_r(gspca_dev, 0x01, 0x0001, 1);
511 if (gspca_dev->usb_err < 0) 461 if (gspca_dev->usb_err < 0)
512 return; 462 return;
513 PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode); 463 PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
464 gspca_dev->usb_buf[0], endcode);
514 if (!count) 465 if (!count)
515 return; 466 return;
516 count = 200; 467 count = 200;
@@ -518,7 +469,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
518 msleep(10); 469 msleep(10);
519 /* gsmart mini2 write a each wait setting 1 ms is enough */ 470 /* gsmart mini2 write a each wait setting 1 ms is enough */
520/* reg_w_riv(gspca_dev, req, idx, val); */ 471/* reg_w_riv(gspca_dev, req, idx, val); */
521 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 472 reg_r(gspca_dev, 0x01, 0x0001, 1);
473 status = gspca_dev->usb_buf[0];
522 if (status == endcode) { 474 if (status == endcode) {
523 PDEBUG(D_FRAM, "status 0x%04x after wait %d", 475 PDEBUG(D_FRAM, "status 0x%04x after wait %d",
524 status, 200 - count); 476 status, 200 - count);
@@ -555,17 +507,19 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
555 } 507 }
556} 508}
557 509
510#ifdef GSPCA_DEBUG
558static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) 511static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
559{ 512{
560 u8 *data; 513 u8 *data;
561 514
562 data = gspca_dev->usb_buf; 515 data = gspca_dev->usb_buf;
563 reg_r(gspca_dev, 0x20, 0, 5); 516 reg_r(gspca_dev, 0x20, 0, 5);
564 PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", 517 PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
565 data[0], data[1], data[2], data[3], data[4]); 518 data[0], data[1], data[2], data[3], data[4]);
566 reg_r(gspca_dev, 0x23, 0, 64); 519 reg_r(gspca_dev, 0x23, 0, 64);
567 reg_r(gspca_dev, 0x23, 1, 64); 520 reg_r(gspca_dev, 0x23, 1, 64);
568} 521}
522#endif
569 523
570static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) 524static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
571{ 525{
@@ -578,7 +532,9 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
578 reg_w_riv(gspca_dev, 0x31, 0, 0); 532 reg_w_riv(gspca_dev, 0x31, 0, 0);
579 spca504B_WaitCmdStatus(gspca_dev); 533 spca504B_WaitCmdStatus(gspca_dev);
580 spca504B_PollingDataReady(gspca_dev); 534 spca504B_PollingDataReady(gspca_dev);
535#ifdef GSPCA_DEBUG
581 spca50x_GetFirmware(gspca_dev); 536 spca50x_GetFirmware(gspca_dev);
537#endif
582 reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ 538 reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
583 reg_r(gspca_dev, 0x24, 8, 1); 539 reg_r(gspca_dev, 0x24, 8, 1);
584 540
@@ -628,7 +584,8 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
628 cnt = 256; 584 cnt = 256;
629 while (--cnt > 0) { 585 while (--cnt > 0) {
630 /* With this we get the status, when return 0 it's all ok */ 586 /* With this we get the status, when return 0 it's all ok */
631 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0) 587 reg_r(gspca_dev, 0x06, 0x00, 1);
588 if (gspca_dev->usb_buf[0] == 0)
632 return; 589 return;
633 msleep(10); 590 msleep(10);
634 } 591 }
@@ -772,10 +729,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
772 /* fall thru */ 729 /* fall thru */
773 case BRIDGE_SPCA533: 730 case BRIDGE_SPCA533:
774 spca504B_PollingDataReady(gspca_dev); 731 spca504B_PollingDataReady(gspca_dev);
732#ifdef GSPCA_DEBUG
775 spca50x_GetFirmware(gspca_dev); 733 spca50x_GetFirmware(gspca_dev);
734#endif
776 break; 735 break;
777 case BRIDGE_SPCA536: 736 case BRIDGE_SPCA536:
737#ifdef GSPCA_DEBUG
778 spca50x_GetFirmware(gspca_dev); 738 spca50x_GetFirmware(gspca_dev);
739#endif
779 reg_r(gspca_dev, 0x00, 0x5002, 1); 740 reg_r(gspca_dev, 0x00, 0x5002, 1);
780 reg_w_1(gspca_dev, 0x24, 0, 0, 0); 741 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
781 reg_r(gspca_dev, 0x24, 0, 1); 742 reg_r(gspca_dev, 0x24, 0, 1);
@@ -801,7 +762,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
801/* case BRIDGE_SPCA504: */ 762/* case BRIDGE_SPCA504: */
802 PDEBUG(D_STREAM, "Opening SPCA504"); 763 PDEBUG(D_STREAM, "Opening SPCA504");
803 if (sd->subtype == AiptekMiniPenCam13) { 764 if (sd->subtype == AiptekMiniPenCam13) {
765#ifdef GSPCA_DEBUG
804 spca504_read_info(gspca_dev); 766 spca504_read_info(gspca_dev);
767#endif
805 768
806 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 769 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
807 spca504A_acknowledged_command(gspca_dev, 0x24, 770 spca504A_acknowledged_command(gspca_dev, 0x24,
@@ -873,7 +836,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
873 break; 836 break;
874 case BRIDGE_SPCA504: 837 case BRIDGE_SPCA504:
875 if (sd->subtype == AiptekMiniPenCam13) { 838 if (sd->subtype == AiptekMiniPenCam13) {
839#ifdef GSPCA_DEBUG
876 spca504_read_info(gspca_dev); 840 spca504_read_info(gspca_dev);
841#endif
877 842
878 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ 843 /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
879 spca504A_acknowledged_command(gspca_dev, 0x24, 844 spca504A_acknowledged_command(gspca_dev, 0x24,
@@ -885,7 +850,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
885 0, 0, 0x9d, 1); 850 0, 0, 0x9d, 1);
886 } else { 851 } else {
887 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 852 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
853#ifdef GSPCA_DEBUG
888 spca504_read_info(gspca_dev); 854 spca504_read_info(gspca_dev);
855#endif
889 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); 856 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
890 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); 857 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
891 } 858 }
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index a3eccd815766..7e762d551099 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -92,8 +92,6 @@ static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); 92static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); 93static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); 94static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_querymenu(struct gspca_dev *gspca_dev,
96 struct v4l2_querymenu *menu);
97 95
98static const struct ctrl sd_ctrls[] = { 96static const struct ctrl sd_ctrls[] = {
99 { 97 {
@@ -1379,17 +1377,14 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1379static int sd_querymenu(struct gspca_dev *gspca_dev, 1377static int sd_querymenu(struct gspca_dev *gspca_dev,
1380 struct v4l2_querymenu *menu) 1378 struct v4l2_querymenu *menu)
1381{ 1379{
1380 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
1381
1382 switch (menu->id) { 1382 switch (menu->id) {
1383 case V4L2_CID_POWER_LINE_FREQUENCY: 1383 case V4L2_CID_POWER_LINE_FREQUENCY:
1384 switch (menu->index) { 1384 if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
1385 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ 1385 break;
1386 strcpy((char *) menu->name, "50 Hz"); 1386 strcpy((char *) menu->name, freq_nm[menu->index]);
1387 return 0; 1387 return 0;
1388 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1389 strcpy((char *) menu->name, "60 Hz");
1390 return 0;
1391 }
1392 break;
1393 case V4L2_CID_EFFECTS: 1388 case V4L2_CID_EFFECTS:
1394 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { 1389 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1395 strncpy((char *) menu->name, 1390 strncpy((char *) menu->name,
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index fa164e861cde..61cdd56a74a9 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -3065,15 +3065,10 @@ static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
3065 {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ 3065 {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
3066 {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ 3066 {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
3067 {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ 3067 {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
3068 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3069 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3070 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
3071 {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
3072 {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
3073 {} 3068 {}
3074}; 3069};
3075 3070
3076static const struct usb_action mc501cb_50HZScale[] = { 3071static const struct usb_action mc501cb_50HZ[] = {
3077 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3072 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3078 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3073 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3079 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ 3074 {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
@@ -3082,15 +3077,10 @@ static const struct usb_action mc501cb_50HZScale[] = {
3082 {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */ 3077 {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */
3083 {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */ 3078 {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */
3084 {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */ 3079 {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */
3085 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3086 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3087 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
3088 {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */
3089 {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */
3090 {} 3080 {}
3091}; 3081};
3092 3082
3093static const struct usb_action mc501cb_50HZ[] = { 3083static const struct usb_action mc501cb_50HZScale[] = {
3094 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3084 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3095 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3085 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3096 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ 3086 {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
@@ -3099,15 +3089,10 @@ static const struct usb_action mc501cb_50HZ[] = {
3099 {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */ 3089 {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */
3100 {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */ 3090 {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */
3101 {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */ 3091 {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */
3102 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3103 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3104 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
3105 {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
3106 {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
3107 {} 3092 {}
3108}; 3093};
3109 3094
3110static const struct usb_action mc501cb_60HZScale[] = { 3095static const struct usb_action mc501cb_60HZ[] = {
3111 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3096 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3112 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3097 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3113 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3098 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3116,15 +3101,10 @@ static const struct usb_action mc501cb_60HZScale[] = {
3116 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ 3101 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
3117 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ 3102 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
3118 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ 3103 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
3119 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3120 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3121 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
3122 {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
3123 {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
3124 {} 3104 {}
3125}; 3105};
3126 3106
3127static const struct usb_action mc501cb_60HZ[] = { 3107static const struct usb_action mc501cb_60HZScale[] = {
3128 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3108 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3129 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3109 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3130 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3110 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -3133,15 +3113,10 @@ static const struct usb_action mc501cb_60HZ[] = {
3133 {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ 3113 {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
3134 {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ 3114 {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
3135 {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ 3115 {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
3136 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3137 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3138 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
3139 {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
3140 {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
3141 {} 3116 {}
3142}; 3117};
3143 3118
3144static const struct usb_action mc501cb_NoFlikerScale[] = { 3119static const struct usb_action mc501cb_NoFliker[] = {
3145 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3120 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3146 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3121 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3147 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ 3122 {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
@@ -3150,15 +3125,10 @@ static const struct usb_action mc501cb_NoFlikerScale[] = {
3150 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ 3125 {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
3151 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ 3126 {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
3152 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ 3127 {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
3153 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3154 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3155 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
3156 {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
3157 {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
3158 {} 3128 {}
3159}; 3129};
3160 3130
3161static const struct usb_action mc501cb_NoFliker[] = { 3131static const struct usb_action mc501cb_NoFlikerScale[] = {
3162 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ 3132 {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
3163 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ 3133 {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
3164 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ 3134 {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
@@ -6296,7 +6266,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6296{ 6266{
6297 struct sd *sd = (struct sd *) gspca_dev; 6267 struct sd *sd = (struct sd *) gspca_dev;
6298 int i; 6268 int i;
6299 u8 retbyte;
6300 u16 retword; 6269 u16 retword;
6301 6270
6302/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ 6271/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
@@ -6389,8 +6358,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6389 retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */ 6358 retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
6390 PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword); 6359 PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
6391 if (retword == 0x2030) { 6360 if (retword == 0x2030) {
6361#ifdef GSPCA_DEBUG
6362 u8 retbyte;
6363
6392 retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ 6364 retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
6393 PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); 6365 PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
6366#endif
6394 send_unknown(gspca_dev, SENSOR_PO2030); 6367 send_unknown(gspca_dev, SENSOR_PO2030);
6395 return retword; 6368 return retword;
6396 } 6369 }
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 39946420b301..a4e4dfdbc2f2 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -810,7 +810,6 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
810 const struct pci_device_id *pci_id) 810 const struct pci_device_id *pci_id)
811{ 811{
812 u16 cmd; 812 u16 cmd;
813 u8 card_rev;
814 unsigned char pci_latency; 813 unsigned char pci_latency;
815 814
816 IVTV_DEBUG_INFO("Enabling pci device\n"); 815 IVTV_DEBUG_INFO("Enabling pci device\n");
@@ -857,7 +856,6 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
857 } 856 }
858 IVTV_DEBUG_INFO("Bus Mastering Enabled.\n"); 857 IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
859 858
860 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
861 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); 859 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
862 860
863 if (pci_latency < 64 && ivtv_pci_latency) { 861 if (pci_latency < 64 && ivtv_pci_latency) {
@@ -874,7 +872,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
874 872
875 IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " 873 IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
876 "irq: %d, latency: %d, memory: 0x%lx\n", 874 "irq: %d, latency: %d, memory: 0x%lx\n",
877 pdev->device, card_rev, pdev->bus->number, 875 pdev->device, pdev->revision, pdev->bus->number,
878 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), 876 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
879 pdev->irq, pci_latency, (unsigned long)itv->base_addr); 877 pdev->irq, pci_latency, (unsigned long)itv->base_addr);
880 878
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 53fa2a7bf156..ebebed929627 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -315,10 +315,20 @@ static int mt9m111_setup_rect(struct i2c_client *client,
315static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) 315static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
316{ 316{
317 int ret; 317 int ret;
318 u16 mask = MT9M111_OUTFMT_PROCESSED_BAYER | MT9M111_OUTFMT_RGB |
319 MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_SWAP_RGB_EVEN |
320 MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_RGB555 |
321 MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr |
322 MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
318 323
319 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 324 ret = reg_read(OUTPUT_FORMAT_CTRL2_A);
325 if (ret >= 0)
326 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, (ret & ~mask) | outfmt);
320 if (!ret) 327 if (!ret)
321 ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); 328 ret = reg_read(OUTPUT_FORMAT_CTRL2_B);
329 if (ret >= 0)
330 ret = reg_write(OUTPUT_FORMAT_CTRL2_B, (ret & ~mask) | outfmt);
331
322 return ret; 332 return ret;
323} 333}
324 334
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index e313d8390092..fc76ed1c08e5 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -228,7 +228,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
228 228
229 flags = soc_camera_apply_sensor_flags(icl, flags); 229 flags = soc_camera_apply_sensor_flags(icl, flags);
230 230
231 if (flags & SOCAM_PCLK_SAMPLE_RISING) 231 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
232 pixclk |= 0x10; 232 pixclk |= 0x10;
233 233
234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH)) 234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
new file mode 100644
index 000000000000..1319c2c48aff
--- /dev/null
+++ b/drivers/media/video/mt9v032.c
@@ -0,0 +1,773 @@
1/*
2 * Driver for MT9V032 CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
5 *
6 * Based on the MT9M001 driver,
7 *
8 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/delay.h>
16#include <linux/i2c.h>
17#include <linux/log2.h>
18#include <linux/mutex.h>
19#include <linux/slab.h>
20#include <linux/videodev2.h>
21#include <linux/v4l2-mediabus.h>
22
23#include <media/mt9v032.h>
24#include <media/v4l2-ctrls.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-subdev.h>
27
28#define MT9V032_PIXEL_ARRAY_HEIGHT 492
29#define MT9V032_PIXEL_ARRAY_WIDTH 782
30
31#define MT9V032_CHIP_VERSION 0x00
32#define MT9V032_CHIP_ID_REV1 0x1311
33#define MT9V032_CHIP_ID_REV3 0x1313
34#define MT9V032_ROW_START 0x01
35#define MT9V032_ROW_START_MIN 4
36#define MT9V032_ROW_START_DEF 10
37#define MT9V032_ROW_START_MAX 482
38#define MT9V032_COLUMN_START 0x02
39#define MT9V032_COLUMN_START_MIN 1
40#define MT9V032_COLUMN_START_DEF 2
41#define MT9V032_COLUMN_START_MAX 752
42#define MT9V032_WINDOW_HEIGHT 0x03
43#define MT9V032_WINDOW_HEIGHT_MIN 1
44#define MT9V032_WINDOW_HEIGHT_DEF 480
45#define MT9V032_WINDOW_HEIGHT_MAX 480
46#define MT9V032_WINDOW_WIDTH 0x04
47#define MT9V032_WINDOW_WIDTH_MIN 1
48#define MT9V032_WINDOW_WIDTH_DEF 752
49#define MT9V032_WINDOW_WIDTH_MAX 752
50#define MT9V032_HORIZONTAL_BLANKING 0x05
51#define MT9V032_HORIZONTAL_BLANKING_MIN 43
52#define MT9V032_HORIZONTAL_BLANKING_MAX 1023
53#define MT9V032_VERTICAL_BLANKING 0x06
54#define MT9V032_VERTICAL_BLANKING_MIN 4
55#define MT9V032_VERTICAL_BLANKING_MAX 3000
56#define MT9V032_CHIP_CONTROL 0x07
57#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
58#define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
59#define MT9V032_CHIP_CONTROL_SEQUENTIAL (1 << 8)
60#define MT9V032_SHUTTER_WIDTH1 0x08
61#define MT9V032_SHUTTER_WIDTH2 0x09
62#define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a
63#define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b
64#define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1
65#define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480
66#define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767
67#define MT9V032_RESET 0x0c
68#define MT9V032_READ_MODE 0x0d
69#define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0)
70#define MT9V032_READ_MODE_ROW_BIN_SHIFT 0
71#define MT9V032_READ_MODE_COLUMN_BIN_MASK (3 << 2)
72#define MT9V032_READ_MODE_COLUMN_BIN_SHIFT 2
73#define MT9V032_READ_MODE_ROW_FLIP (1 << 4)
74#define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5)
75#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
76#define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
77#define MT9V032_PIXEL_OPERATION_MODE 0x0f
78#define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2)
79#define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6)
80#define MT9V032_ANALOG_GAIN 0x35
81#define MT9V032_ANALOG_GAIN_MIN 16
82#define MT9V032_ANALOG_GAIN_DEF 16
83#define MT9V032_ANALOG_GAIN_MAX 64
84#define MT9V032_MAX_ANALOG_GAIN 0x36
85#define MT9V032_MAX_ANALOG_GAIN_MAX 127
86#define MT9V032_FRAME_DARK_AVERAGE 0x42
87#define MT9V032_DARK_AVG_THRESH 0x46
88#define MT9V032_DARK_AVG_LOW_THRESH_MASK (255 << 0)
89#define MT9V032_DARK_AVG_LOW_THRESH_SHIFT 0
90#define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
91#define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8
92#define MT9V032_ROW_NOISE_CORR_CONTROL 0x70
93#define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5)
94#define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7)
95#define MT9V032_PIXEL_CLOCK 0x74
96#define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0)
97#define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1)
98#define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2)
99#define MT9V032_PIXEL_CLOCK_CONT_LINE (1 << 3)
100#define MT9V032_PIXEL_CLOCK_INV_PXL_CLK (1 << 4)
101#define MT9V032_TEST_PATTERN 0x7f
102#define MT9V032_TEST_PATTERN_DATA_MASK (1023 << 0)
103#define MT9V032_TEST_PATTERN_DATA_SHIFT 0
104#define MT9V032_TEST_PATTERN_USE_DATA (1 << 10)
105#define MT9V032_TEST_PATTERN_GRAY_MASK (3 << 11)
106#define MT9V032_TEST_PATTERN_GRAY_NONE (0 << 11)
107#define MT9V032_TEST_PATTERN_GRAY_VERTICAL (1 << 11)
108#define MT9V032_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11)
109#define MT9V032_TEST_PATTERN_GRAY_DIAGONAL (3 << 11)
110#define MT9V032_TEST_PATTERN_ENABLE (1 << 13)
111#define MT9V032_TEST_PATTERN_FLIP (1 << 14)
112#define MT9V032_AEC_AGC_ENABLE 0xaf
113#define MT9V032_AEC_ENABLE (1 << 0)
114#define MT9V032_AGC_ENABLE (1 << 1)
115#define MT9V032_THERMAL_INFO 0xc1
116
117struct mt9v032 {
118 struct v4l2_subdev subdev;
119 struct media_pad pad;
120
121 struct v4l2_mbus_framefmt format;
122 struct v4l2_rect crop;
123
124 struct v4l2_ctrl_handler ctrls;
125
126 struct mutex power_lock;
127 int power_count;
128
129 struct mt9v032_platform_data *pdata;
130 u16 chip_control;
131 u16 aec_agc;
132};
133
134static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
135{
136 return container_of(sd, struct mt9v032, subdev);
137}
138
139static int mt9v032_read(struct i2c_client *client, const u8 reg)
140{
141 s32 data = i2c_smbus_read_word_data(client, reg);
142 dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
143 swab16(data), reg);
144 return data < 0 ? data : swab16(data);
145}
146
147static int mt9v032_write(struct i2c_client *client, const u8 reg,
148 const u16 data)
149{
150 dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
151 data, reg);
152 return i2c_smbus_write_word_data(client, reg, swab16(data));
153}
154
155static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
156{
157 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
158 u16 value = (mt9v032->chip_control & ~clear) | set;
159 int ret;
160
161 ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
162 if (ret < 0)
163 return ret;
164
165 mt9v032->chip_control = value;
166 return 0;
167}
168
169static int
170mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
171{
172 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
173 u16 value = mt9v032->aec_agc;
174 int ret;
175
176 if (enable)
177 value |= which;
178 else
179 value &= ~which;
180
181 ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
182 if (ret < 0)
183 return ret;
184
185 mt9v032->aec_agc = value;
186 return 0;
187}
188
189static int mt9v032_power_on(struct mt9v032 *mt9v032)
190{
191 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
192 int ret;
193
194 if (mt9v032->pdata->set_clock) {
195 mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000);
196 udelay(1);
197 }
198
199 /* Reset the chip and stop data read out */
200 ret = mt9v032_write(client, MT9V032_RESET, 1);
201 if (ret < 0)
202 return ret;
203
204 ret = mt9v032_write(client, MT9V032_RESET, 0);
205 if (ret < 0)
206 return ret;
207
208 return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
209}
210
211static void mt9v032_power_off(struct mt9v032 *mt9v032)
212{
213 if (mt9v032->pdata->set_clock)
214 mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
215}
216
217static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
218{
219 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
220 int ret;
221
222 if (!on) {
223 mt9v032_power_off(mt9v032);
224 return 0;
225 }
226
227 ret = mt9v032_power_on(mt9v032);
228 if (ret < 0)
229 return ret;
230
231 /* Configure the pixel clock polarity */
232 if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
233 ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK,
234 MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
235 if (ret < 0)
236 return ret;
237 }
238
239 /* Disable the noise correction algorithm and restore the controls. */
240 ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
241 if (ret < 0)
242 return ret;
243
244 return v4l2_ctrl_handler_setup(&mt9v032->ctrls);
245}
246
247/* -----------------------------------------------------------------------------
248 * V4L2 subdev video operations
249 */
250
251static struct v4l2_mbus_framefmt *
252__mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
253 unsigned int pad, enum v4l2_subdev_format_whence which)
254{
255 switch (which) {
256 case V4L2_SUBDEV_FORMAT_TRY:
257 return v4l2_subdev_get_try_format(fh, pad);
258 case V4L2_SUBDEV_FORMAT_ACTIVE:
259 return &mt9v032->format;
260 default:
261 return NULL;
262 }
263}
264
265static struct v4l2_rect *
266__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
267 unsigned int pad, enum v4l2_subdev_format_whence which)
268{
269 switch (which) {
270 case V4L2_SUBDEV_FORMAT_TRY:
271 return v4l2_subdev_get_try_crop(fh, pad);
272 case V4L2_SUBDEV_FORMAT_ACTIVE:
273 return &mt9v032->crop;
274 default:
275 return NULL;
276 }
277}
278
279static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
280{
281 const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
282 | MT9V032_CHIP_CONTROL_DOUT_ENABLE
283 | MT9V032_CHIP_CONTROL_SEQUENTIAL;
284 struct i2c_client *client = v4l2_get_subdevdata(subdev);
285 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
286 struct v4l2_mbus_framefmt *format = &mt9v032->format;
287 struct v4l2_rect *crop = &mt9v032->crop;
288 unsigned int hratio;
289 unsigned int vratio;
290 int ret;
291
292 if (!enable)
293 return mt9v032_set_chip_control(mt9v032, mode, 0);
294
295 /* Configure the window size and row/column bin */
296 hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
297 vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
298
299 ret = mt9v032_write(client, MT9V032_READ_MODE,
300 (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT |
301 (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT);
302 if (ret < 0)
303 return ret;
304
305 ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
306 if (ret < 0)
307 return ret;
308
309 ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
310 if (ret < 0)
311 return ret;
312
313 ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
314 if (ret < 0)
315 return ret;
316
317 ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
318 if (ret < 0)
319 return ret;
320
321 ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
322 max(43, 660 - crop->width));
323 if (ret < 0)
324 return ret;
325
326 /* Switch to master "normal" mode */
327 return mt9v032_set_chip_control(mt9v032, 0, mode);
328}
329
330static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
331 struct v4l2_subdev_fh *fh,
332 struct v4l2_subdev_mbus_code_enum *code)
333{
334 if (code->index > 0)
335 return -EINVAL;
336
337 code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
338 return 0;
339}
340
341static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
342 struct v4l2_subdev_fh *fh,
343 struct v4l2_subdev_frame_size_enum *fse)
344{
345 if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
346 return -EINVAL;
347
348 fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index;
349 fse->max_width = fse->min_width;
350 fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index;
351 fse->max_height = fse->min_height;
352
353 return 0;
354}
355
356static int mt9v032_get_format(struct v4l2_subdev *subdev,
357 struct v4l2_subdev_fh *fh,
358 struct v4l2_subdev_format *format)
359{
360 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
361
362 format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad,
363 format->which);
364 return 0;
365}
366
367static int mt9v032_set_format(struct v4l2_subdev *subdev,
368 struct v4l2_subdev_fh *fh,
369 struct v4l2_subdev_format *format)
370{
371 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
372 struct v4l2_mbus_framefmt *__format;
373 struct v4l2_rect *__crop;
374 unsigned int width;
375 unsigned int height;
376 unsigned int hratio;
377 unsigned int vratio;
378
379 __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad,
380 format->which);
381
382 /* Clamp the width and height to avoid dividing by zero. */
383 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
384 max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN),
385 __crop->width);
386 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
387 max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN),
388 __crop->height);
389
390 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
391 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
392
393 __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
394 format->which);
395 __format->width = __crop->width / hratio;
396 __format->height = __crop->height / vratio;
397
398 format->format = *__format;
399
400 return 0;
401}
402
403static int mt9v032_get_crop(struct v4l2_subdev *subdev,
404 struct v4l2_subdev_fh *fh,
405 struct v4l2_subdev_crop *crop)
406{
407 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
408
409 crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad,
410 crop->which);
411 return 0;
412}
413
414static int mt9v032_set_crop(struct v4l2_subdev *subdev,
415 struct v4l2_subdev_fh *fh,
416 struct v4l2_subdev_crop *crop)
417{
418 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
419 struct v4l2_mbus_framefmt *__format;
420 struct v4l2_rect *__crop;
421 struct v4l2_rect rect;
422
423 /* Clamp the crop rectangle boundaries and align them to a multiple of 2
424 * pixels.
425 */
426 rect.left = clamp(ALIGN(crop->rect.left, 2),
427 MT9V032_COLUMN_START_MIN,
428 MT9V032_COLUMN_START_MAX);
429 rect.top = clamp(ALIGN(crop->rect.top, 2),
430 MT9V032_ROW_START_MIN,
431 MT9V032_ROW_START_MAX);
432 rect.width = clamp(ALIGN(crop->rect.width, 2),
433 MT9V032_WINDOW_WIDTH_MIN,
434 MT9V032_WINDOW_WIDTH_MAX);
435 rect.height = clamp(ALIGN(crop->rect.height, 2),
436 MT9V032_WINDOW_HEIGHT_MIN,
437 MT9V032_WINDOW_HEIGHT_MAX);
438
439 rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
440 rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
441
442 __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
443
444 if (rect.width != __crop->width || rect.height != __crop->height) {
445 /* Reset the output image size if the crop rectangle size has
446 * been modified.
447 */
448 __format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad,
449 crop->which);
450 __format->width = rect.width;
451 __format->height = rect.height;
452 }
453
454 *__crop = rect;
455 crop->rect = rect;
456
457 return 0;
458}
459
460/* -----------------------------------------------------------------------------
461 * V4L2 subdev control operations
462 */
463
464#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
465
466static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
467{
468 struct mt9v032 *mt9v032 =
469 container_of(ctrl->handler, struct mt9v032, ctrls);
470 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
471 u16 data;
472
473 switch (ctrl->id) {
474 case V4L2_CID_AUTOGAIN:
475 return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE,
476 ctrl->val);
477
478 case V4L2_CID_GAIN:
479 return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
480
481 case V4L2_CID_EXPOSURE_AUTO:
482 return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
483 ctrl->val);
484
485 case V4L2_CID_EXPOSURE:
486 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
487 ctrl->val);
488
489 case V4L2_CID_TEST_PATTERN:
490 switch (ctrl->val) {
491 case 0:
492 data = 0;
493 break;
494 case 1:
495 data = MT9V032_TEST_PATTERN_GRAY_VERTICAL
496 | MT9V032_TEST_PATTERN_ENABLE;
497 break;
498 case 2:
499 data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL
500 | MT9V032_TEST_PATTERN_ENABLE;
501 break;
502 case 3:
503 data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL
504 | MT9V032_TEST_PATTERN_ENABLE;
505 break;
506 default:
507 data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT)
508 | MT9V032_TEST_PATTERN_USE_DATA
509 | MT9V032_TEST_PATTERN_ENABLE
510 | MT9V032_TEST_PATTERN_FLIP;
511 break;
512 }
513
514 return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
515 }
516
517 return 0;
518}
519
520static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
521 .s_ctrl = mt9v032_s_ctrl,
522};
523
524static const struct v4l2_ctrl_config mt9v032_ctrls[] = {
525 {
526 .ops = &mt9v032_ctrl_ops,
527 .id = V4L2_CID_TEST_PATTERN,
528 .type = V4L2_CTRL_TYPE_INTEGER,
529 .name = "Test pattern",
530 .min = 0,
531 .max = 1023,
532 .step = 1,
533 .def = 0,
534 .flags = 0,
535 }
536};
537
538/* -----------------------------------------------------------------------------
539 * V4L2 subdev core operations
540 */
541
542static int mt9v032_set_power(struct v4l2_subdev *subdev, int on)
543{
544 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
545 int ret = 0;
546
547 mutex_lock(&mt9v032->power_lock);
548
549 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
550 * update the power state.
551 */
552 if (mt9v032->power_count == !on) {
553 ret = __mt9v032_set_power(mt9v032, !!on);
554 if (ret < 0)
555 goto done;
556 }
557
558 /* Update the power count. */
559 mt9v032->power_count += on ? 1 : -1;
560 WARN_ON(mt9v032->power_count < 0);
561
562done:
563 mutex_unlock(&mt9v032->power_lock);
564 return ret;
565}
566
567/* -----------------------------------------------------------------------------
568 * V4L2 subdev internal operations
569 */
570
571static int mt9v032_registered(struct v4l2_subdev *subdev)
572{
573 struct i2c_client *client = v4l2_get_subdevdata(subdev);
574 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
575 s32 data;
576 int ret;
577
578 dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
579 client->addr);
580
581 ret = mt9v032_power_on(mt9v032);
582 if (ret < 0) {
583 dev_err(&client->dev, "MT9V032 power up failed\n");
584 return ret;
585 }
586
587 /* Read and check the sensor version */
588 data = mt9v032_read(client, MT9V032_CHIP_VERSION);
589 if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) {
590 dev_err(&client->dev, "MT9V032 not detected, wrong version "
591 "0x%04x\n", data);
592 return -ENODEV;
593 }
594
595 mt9v032_power_off(mt9v032);
596
597 dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
598 client->addr);
599
600 return ret;
601}
602
603static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
604{
605 struct v4l2_mbus_framefmt *format;
606 struct v4l2_rect *crop;
607
608 crop = v4l2_subdev_get_try_crop(fh, 0);
609 crop->left = MT9V032_COLUMN_START_DEF;
610 crop->top = MT9V032_ROW_START_DEF;
611 crop->width = MT9V032_WINDOW_WIDTH_DEF;
612 crop->height = MT9V032_WINDOW_HEIGHT_DEF;
613
614 format = v4l2_subdev_get_try_format(fh, 0);
615 format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
616 format->width = MT9V032_WINDOW_WIDTH_DEF;
617 format->height = MT9V032_WINDOW_HEIGHT_DEF;
618 format->field = V4L2_FIELD_NONE;
619 format->colorspace = V4L2_COLORSPACE_SRGB;
620
621 return mt9v032_set_power(subdev, 1);
622}
623
624static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
625{
626 return mt9v032_set_power(subdev, 0);
627}
628
629static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
630 .s_power = mt9v032_set_power,
631};
632
633static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
634 .s_stream = mt9v032_s_stream,
635};
636
637static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
638 .enum_mbus_code = mt9v032_enum_mbus_code,
639 .enum_frame_size = mt9v032_enum_frame_size,
640 .get_fmt = mt9v032_get_format,
641 .set_fmt = mt9v032_set_format,
642 .get_crop = mt9v032_get_crop,
643 .set_crop = mt9v032_set_crop,
644};
645
646static struct v4l2_subdev_ops mt9v032_subdev_ops = {
647 .core = &mt9v032_subdev_core_ops,
648 .video = &mt9v032_subdev_video_ops,
649 .pad = &mt9v032_subdev_pad_ops,
650};
651
652static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
653 .registered = mt9v032_registered,
654 .open = mt9v032_open,
655 .close = mt9v032_close,
656};
657
658/* -----------------------------------------------------------------------------
659 * Driver initialization and probing
660 */
661
662static int mt9v032_probe(struct i2c_client *client,
663 const struct i2c_device_id *did)
664{
665 struct mt9v032 *mt9v032;
666 unsigned int i;
667 int ret;
668
669 if (!i2c_check_functionality(client->adapter,
670 I2C_FUNC_SMBUS_WORD_DATA)) {
671 dev_warn(&client->adapter->dev,
672 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
673 return -EIO;
674 }
675
676 mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
677 if (!mt9v032)
678 return -ENOMEM;
679
680 mutex_init(&mt9v032->power_lock);
681 mt9v032->pdata = client->dev.platform_data;
682
683 v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4);
684
685 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
686 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
687 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
688 V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN,
689 MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF);
690 v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops,
691 V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
692 V4L2_EXPOSURE_AUTO);
693 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
694 V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
695 MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
696 MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
697
698 for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
699 v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
700
701 mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
702
703 if (mt9v032->ctrls.error)
704 printk(KERN_INFO "%s: control initialization error %d\n",
705 __func__, mt9v032->ctrls.error);
706
707 mt9v032->crop.left = MT9V032_COLUMN_START_DEF;
708 mt9v032->crop.top = MT9V032_ROW_START_DEF;
709 mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
710 mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
711
712 mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
713 mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
714 mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
715 mt9v032->format.field = V4L2_FIELD_NONE;
716 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
717
718 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
719
720 v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
721 mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
722 mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
723
724 mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
725 ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
726 if (ret < 0)
727 kfree(mt9v032);
728
729 return ret;
730}
731
732static int mt9v032_remove(struct i2c_client *client)
733{
734 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
735 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
736
737 v4l2_device_unregister_subdev(subdev);
738 media_entity_cleanup(&subdev->entity);
739 kfree(mt9v032);
740 return 0;
741}
742
743static const struct i2c_device_id mt9v032_id[] = {
744 { "mt9v032", 0 },
745 { }
746};
747MODULE_DEVICE_TABLE(i2c, mt9v032_id);
748
749static struct i2c_driver mt9v032_driver = {
750 .driver = {
751 .name = "mt9v032",
752 },
753 .probe = mt9v032_probe,
754 .remove = mt9v032_remove,
755 .id_table = mt9v032_id,
756};
757
758static int __init mt9v032_init(void)
759{
760 return i2c_add_driver(&mt9v032_driver);
761}
762
763static void __exit mt9v032_exit(void)
764{
765 i2c_del_driver(&mt9v032_driver);
766}
767
768module_init(mt9v032_init);
769module_exit(mt9v032_exit);
770
771MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
772MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
773MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 502e2a40964c..c7680eb83664 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -400,6 +400,35 @@ static int mx3_videobuf_init(struct vb2_buffer *vb)
400 return 0; 400 return 0;
401} 401}
402 402
403static int mx3_stop_streaming(struct vb2_queue *q)
404{
405 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
406 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
407 struct mx3_camera_dev *mx3_cam = ici->priv;
408 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
409 struct dma_chan *chan;
410 struct mx3_camera_buffer *buf, *tmp;
411 unsigned long flags;
412
413 if (ichan) {
414 chan = &ichan->dma_chan;
415 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
416 }
417
418 spin_lock_irqsave(&mx3_cam->lock, flags);
419
420 mx3_cam->active = NULL;
421
422 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
423 buf->state = CSI_BUF_NEEDS_INIT;
424 list_del_init(&buf->queue);
425 }
426
427 spin_unlock_irqrestore(&mx3_cam->lock, flags);
428
429 return 0;
430}
431
403static struct vb2_ops mx3_videobuf_ops = { 432static struct vb2_ops mx3_videobuf_ops = {
404 .queue_setup = mx3_videobuf_setup, 433 .queue_setup = mx3_videobuf_setup,
405 .buf_prepare = mx3_videobuf_prepare, 434 .buf_prepare = mx3_videobuf_prepare,
@@ -408,6 +437,7 @@ static struct vb2_ops mx3_videobuf_ops = {
408 .buf_init = mx3_videobuf_init, 437 .buf_init = mx3_videobuf_init,
409 .wait_prepare = soc_camera_unlock, 438 .wait_prepare = soc_camera_unlock,
410 .wait_finish = soc_camera_lock, 439 .wait_finish = soc_camera_lock,
440 .stop_streaming = mx3_stop_streaming,
411}; 441};
412 442
413static int mx3_camera_init_videobuf(struct vb2_queue *q, 443static int mx3_camera_init_videobuf(struct vb2_queue *q,
@@ -658,8 +688,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
658 688
659 fmt = soc_mbus_get_fmtdesc(code); 689 fmt = soc_mbus_get_fmtdesc(code);
660 if (!fmt) { 690 if (!fmt) {
661 dev_err(icd->dev.parent, 691 dev_warn(icd->dev.parent,
662 "Invalid format code #%u: %d\n", idx, code); 692 "Unsupported format code #%u: %d\n", idx, code);
663 return 0; 693 return 0;
664 } 694 }
665 695
@@ -712,13 +742,9 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
712 742
713static void configure_geometry(struct mx3_camera_dev *mx3_cam, 743static void configure_geometry(struct mx3_camera_dev *mx3_cam,
714 unsigned int width, unsigned int height, 744 unsigned int width, unsigned int height,
715 enum v4l2_mbus_pixelcode code) 745 const struct soc_mbus_pixelfmt *fmt)
716{ 746{
717 u32 ctrl, width_field, height_field; 747 u32 ctrl, width_field, height_field;
718 const struct soc_mbus_pixelfmt *fmt;
719
720 fmt = soc_mbus_get_fmtdesc(code);
721 BUG_ON(!fmt);
722 748
723 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) { 749 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
724 /* 750 /*
@@ -726,8 +752,10 @@ static void configure_geometry(struct mx3_camera_dev *mx3_cam,
726 * the width parameter count the number of samples to 752 * the width parameter count the number of samples to
727 * capture to complete the whole image width. 753 * capture to complete the whole image width.
728 */ 754 */
729 width *= soc_mbus_samples_per_pixel(fmt); 755 unsigned int num, den;
730 BUG_ON(width < 0); 756 int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
757 BUG_ON(ret < 0);
758 width = width * num / den;
731 } 759 }
732 760
733 /* Setup frame size - this cannot be changed on-the-fly... */ 761 /* Setup frame size - this cannot be changed on-the-fly... */
@@ -774,8 +802,8 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
774 */ 802 */
775static inline void stride_align(__u32 *width) 803static inline void stride_align(__u32 *width)
776{ 804{
777 if (((*width + 7) & ~7) < 4096) 805 if (ALIGN(*width, 8) < 4096)
778 *width = (*width + 7) & ~7; 806 *width = ALIGN(*width, 8);
779 else 807 else
780 *width = *width & ~7; 808 *width = *width & ~7;
781} 809}
@@ -801,11 +829,14 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
801 if (ret < 0) 829 if (ret < 0)
802 return ret; 830 return ret;
803 831
804 /* The capture device might have changed its output */ 832 /* The capture device might have changed its output sizes */
805 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 833 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
806 if (ret < 0) 834 if (ret < 0)
807 return ret; 835 return ret;
808 836
837 if (mf.code != icd->current_fmt->code)
838 return -EINVAL;
839
809 if (mf.width & 7) { 840 if (mf.width & 7) {
810 /* Ouch! We can only handle 8-byte aligned width... */ 841 /* Ouch! We can only handle 8-byte aligned width... */
811 stride_align(&mf.width); 842 stride_align(&mf.width);
@@ -815,7 +846,8 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
815 } 846 }
816 847
817 if (mf.width != icd->user_width || mf.height != icd->user_height) 848 if (mf.width != icd->user_width || mf.height != icd->user_height)
818 configure_geometry(mx3_cam, mf.width, mf.height, mf.code); 849 configure_geometry(mx3_cam, mf.width, mf.height,
850 icd->current_fmt->host_fmt);
819 851
820 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 852 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
821 mf.width, mf.height); 853 mf.width, mf.height);
@@ -853,7 +885,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
853 * mxc_v4l2_s_fmt() 885 * mxc_v4l2_s_fmt()
854 */ 886 */
855 887
856 configure_geometry(mx3_cam, pix->width, pix->height, xlate->code); 888 configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
857 889
858 mf.width = pix->width; 890 mf.width = pix->width;
859 mf.height = pix->height; 891 mf.height = pix->height;
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index 5954b9306630..e7cfc85b0a1c 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -990,63 +990,80 @@ static void omap1_cam_remove_device(struct soc_camera_device *icd)
990} 990}
991 991
992/* Duplicate standard formats based on host capability of byte swapping */ 992/* Duplicate standard formats based on host capability of byte swapping */
993static const struct soc_mbus_pixelfmt omap1_cam_formats[] = { 993static const struct soc_mbus_lookup omap1_cam_formats[] = {
994 [V4L2_MBUS_FMT_UYVY8_2X8] = { 994{
995 .code = V4L2_MBUS_FMT_UYVY8_2X8,
996 .fmt = {
995 .fourcc = V4L2_PIX_FMT_YUYV, 997 .fourcc = V4L2_PIX_FMT_YUYV,
996 .name = "YUYV", 998 .name = "YUYV",
997 .bits_per_sample = 8, 999 .bits_per_sample = 8,
998 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1000 .packing = SOC_MBUS_PACKING_2X8_PADHI,
999 .order = SOC_MBUS_ORDER_BE, 1001 .order = SOC_MBUS_ORDER_BE,
1000 }, 1002 },
1001 [V4L2_MBUS_FMT_VYUY8_2X8] = { 1003}, {
1004 .code = V4L2_MBUS_FMT_VYUY8_2X8,
1005 .fmt = {
1002 .fourcc = V4L2_PIX_FMT_YVYU, 1006 .fourcc = V4L2_PIX_FMT_YVYU,
1003 .name = "YVYU", 1007 .name = "YVYU",
1004 .bits_per_sample = 8, 1008 .bits_per_sample = 8,
1005 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1009 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1006 .order = SOC_MBUS_ORDER_BE, 1010 .order = SOC_MBUS_ORDER_BE,
1007 }, 1011 },
1008 [V4L2_MBUS_FMT_YUYV8_2X8] = { 1012}, {
1013 .code = V4L2_MBUS_FMT_YUYV8_2X8,
1014 .fmt = {
1009 .fourcc = V4L2_PIX_FMT_UYVY, 1015 .fourcc = V4L2_PIX_FMT_UYVY,
1010 .name = "UYVY", 1016 .name = "UYVY",
1011 .bits_per_sample = 8, 1017 .bits_per_sample = 8,
1012 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1018 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1013 .order = SOC_MBUS_ORDER_BE, 1019 .order = SOC_MBUS_ORDER_BE,
1014 }, 1020 },
1015 [V4L2_MBUS_FMT_YVYU8_2X8] = { 1021}, {
1022 .code = V4L2_MBUS_FMT_YVYU8_2X8,
1023 .fmt = {
1016 .fourcc = V4L2_PIX_FMT_VYUY, 1024 .fourcc = V4L2_PIX_FMT_VYUY,
1017 .name = "VYUY", 1025 .name = "VYUY",
1018 .bits_per_sample = 8, 1026 .bits_per_sample = 8,
1019 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1027 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1020 .order = SOC_MBUS_ORDER_BE, 1028 .order = SOC_MBUS_ORDER_BE,
1021 }, 1029 },
1022 [V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE] = { 1030}, {
1031 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
1032 .fmt = {
1023 .fourcc = V4L2_PIX_FMT_RGB555, 1033 .fourcc = V4L2_PIX_FMT_RGB555,
1024 .name = "RGB555", 1034 .name = "RGB555",
1025 .bits_per_sample = 8, 1035 .bits_per_sample = 8,
1026 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1036 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1027 .order = SOC_MBUS_ORDER_BE, 1037 .order = SOC_MBUS_ORDER_BE,
1028 }, 1038 },
1029 [V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE] = { 1039}, {
1040 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
1041 .fmt = {
1030 .fourcc = V4L2_PIX_FMT_RGB555X, 1042 .fourcc = V4L2_PIX_FMT_RGB555X,
1031 .name = "RGB555X", 1043 .name = "RGB555X",
1032 .bits_per_sample = 8, 1044 .bits_per_sample = 8,
1033 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1045 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1034 .order = SOC_MBUS_ORDER_BE, 1046 .order = SOC_MBUS_ORDER_BE,
1035 }, 1047 },
1036 [V4L2_MBUS_FMT_RGB565_2X8_BE] = { 1048}, {
1049 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
1050 .fmt = {
1037 .fourcc = V4L2_PIX_FMT_RGB565, 1051 .fourcc = V4L2_PIX_FMT_RGB565,
1038 .name = "RGB565", 1052 .name = "RGB565",
1039 .bits_per_sample = 8, 1053 .bits_per_sample = 8,
1040 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1054 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1041 .order = SOC_MBUS_ORDER_BE, 1055 .order = SOC_MBUS_ORDER_BE,
1042 }, 1056 },
1043 [V4L2_MBUS_FMT_RGB565_2X8_LE] = { 1057}, {
1058 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
1059 .fmt = {
1044 .fourcc = V4L2_PIX_FMT_RGB565X, 1060 .fourcc = V4L2_PIX_FMT_RGB565X,
1045 .name = "RGB565X", 1061 .name = "RGB565X",
1046 .bits_per_sample = 8, 1062 .bits_per_sample = 8,
1047 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1063 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1048 .order = SOC_MBUS_ORDER_BE, 1064 .order = SOC_MBUS_ORDER_BE,
1049 }, 1065 },
1066},
1050}; 1067};
1051 1068
1052static int omap1_cam_get_formats(struct soc_camera_device *icd, 1069static int omap1_cam_get_formats(struct soc_camera_device *icd,
@@ -1065,7 +1082,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1065 1082
1066 fmt = soc_mbus_get_fmtdesc(code); 1083 fmt = soc_mbus_get_fmtdesc(code);
1067 if (!fmt) { 1084 if (!fmt) {
1068 dev_err(dev, "%s: invalid format code #%d: %d\n", __func__, 1085 dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
1069 idx, code); 1086 idx, code);
1070 return 0; 1087 return 0;
1071 } 1088 }
@@ -1085,12 +1102,14 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1085 case V4L2_MBUS_FMT_RGB565_2X8_LE: 1102 case V4L2_MBUS_FMT_RGB565_2X8_LE:
1086 formats++; 1103 formats++;
1087 if (xlate) { 1104 if (xlate) {
1088 xlate->host_fmt = &omap1_cam_formats[code]; 1105 xlate->host_fmt = soc_mbus_find_fmtdesc(code,
1106 omap1_cam_formats,
1107 ARRAY_SIZE(omap1_cam_formats));
1089 xlate->code = code; 1108 xlate->code = code;
1090 xlate++; 1109 xlate++;
1091 dev_dbg(dev, 1110 dev_dbg(dev,
1092 "%s: providing format %s as byte swapped code #%d\n", 1111 "%s: providing format %s as byte swapped code #%d\n",
1093 __func__, omap1_cam_formats[code].name, code); 1112 __func__, xlate->host_fmt->name, code);
1094 } 1113 }
1095 default: 1114 default:
1096 if (xlate) 1115 if (xlate)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
index ca9f83a85ca5..453627b07833 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -278,12 +278,10 @@ static struct v4l2_standard generic_standards[] = {
278 } 278 }
279}; 279};
280 280
281#define generic_standards_cnt ARRAY_SIZE(generic_standards)
282
283static struct v4l2_standard *match_std(v4l2_std_id id) 281static struct v4l2_standard *match_std(v4l2_std_id id)
284{ 282{
285 unsigned int idx; 283 unsigned int idx;
286 for (idx = 0; idx < generic_standards_cnt; idx++) { 284 for (idx = 0; idx < ARRAY_SIZE(generic_standards); idx++) {
287 if (generic_standards[idx].id & id) { 285 if (generic_standards[idx].id & id) {
288 return generic_standards + idx; 286 return generic_standards + idx;
289 } 287 }
@@ -370,7 +368,11 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
370 368
371 stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt, 369 stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt,
372 GFP_KERNEL); 370 GFP_KERNEL);
373 for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx; 371 if (!stddefs)
372 return NULL;
373
374 for (idx = 0; idx < std_cnt; idx++)
375 stddefs[idx].index = idx;
374 376
375 idx = 0; 377 idx = 0;
376 378
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 780af5f81642..356cd42b593b 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1850,7 +1850,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1850 } else { 1850 } else {
1851 /* Device is closed, so we can safely unregister it */ 1851 /* Device is closed, so we can safely unregister it */
1852 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); 1852 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
1853 pwc_cleanup(pdev);
1854 1853
1855disconnect_out: 1854disconnect_out:
1856 /* search device_hint[] table if we occupy a slot, by any chance */ 1855 /* search device_hint[] table if we occupy a slot, by any chance */
@@ -1860,6 +1859,7 @@ disconnect_out:
1860 } 1859 }
1861 1860
1862 mutex_unlock(&pdev->modlock); 1861 mutex_unlock(&pdev->modlock);
1862 pwc_cleanup(pdev);
1863} 1863}
1864 1864
1865 1865
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index aa87e462a958..f85c51249c7b 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -379,8 +379,27 @@ static int pwc_s_input(struct file *file, void *fh, unsigned int i)
379 379
380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
381{ 381{
382 int i; 382 int i, idx;
383 383 u32 id;
384
385 id = c->id;
386 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
387 id &= V4L2_CTRL_ID_MASK;
388 id++;
389 idx = -1;
390 for (i = 0; i < ARRAY_SIZE(pwc_controls); i++) {
391 if (pwc_controls[i].id < id)
392 continue;
393 if (idx >= 0
394 && pwc_controls[i].id > pwc_controls[idx].id)
395 continue;
396 idx = i;
397 }
398 if (idx < 0)
399 return -EINVAL;
400 memcpy(c, &pwc_controls[idx], sizeof pwc_controls[0]);
401 return 0;
402 }
384 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) { 403 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) {
385 if (pwc_controls[i].id == c->id) { 404 if (pwc_controls[i].id == c->id) {
386 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); 405 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c1ee09a043ba..b42bfa5ccdf2 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1155,15 +1155,11 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1155 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1155 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1156 struct pxa_camera_dev *pcdev = ici->priv; 1156 struct pxa_camera_dev *pcdev = ici->priv;
1157 unsigned long bus_flags, camera_flags, common_flags; 1157 unsigned long bus_flags, camera_flags, common_flags;
1158 const struct soc_mbus_pixelfmt *fmt;
1159 int ret; 1158 int ret;
1160 struct pxa_cam *cam = icd->host_priv; 1159 struct pxa_cam *cam = icd->host_priv;
1161 1160
1162 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); 1161 ret = test_platform_param(pcdev, icd->current_fmt->host_fmt->bits_per_sample,
1163 if (!fmt) 1162 &bus_flags);
1164 return -EINVAL;
1165
1166 ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags);
1167 if (ret < 0) 1163 if (ret < 0)
1168 return ret; 1164 return ret;
1169 1165
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 561909b65ce6..5b9dce85645c 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -394,12 +394,17 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
394/* start video number */ 394/* start video number */
395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 395static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
396 396
397/* Enable jpeg capture. */
398static int jpeg_enable = 1;
399
397module_param(debug, int, 0644); 400module_param(debug, int, 0644);
398MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); 401MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
399module_param(vid_limit, int, 0644); 402module_param(vid_limit, int, 0644);
400MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); 403MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
401module_param(video_nr, int, 0644); 404module_param(video_nr, int, 0644);
402MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); 405MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
406module_param(jpeg_enable, int, 0644);
407MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
403 408
404/* USB device table */ 409/* USB device table */
405#define USB_SENSORAY_VID 0x1943 410#define USB_SENSORAY_VID 0x1943
@@ -413,6 +418,7 @@ MODULE_DEVICE_TABLE(usb, s2255_table);
413#define BUFFER_TIMEOUT msecs_to_jiffies(400) 418#define BUFFER_TIMEOUT msecs_to_jiffies(400)
414 419
415/* image formats. */ 420/* image formats. */
421/* JPEG formats must be defined last to support jpeg_enable parameter */
416static const struct s2255_fmt formats[] = { 422static const struct s2255_fmt formats[] = {
417 { 423 {
418 .name = "4:2:2, planar, YUV422P", 424 .name = "4:2:2, planar, YUV422P",
@@ -429,13 +435,17 @@ static const struct s2255_fmt formats[] = {
429 .fourcc = V4L2_PIX_FMT_UYVY, 435 .fourcc = V4L2_PIX_FMT_UYVY,
430 .depth = 16 436 .depth = 16
431 }, { 437 }, {
438 .name = "8bpp GREY",
439 .fourcc = V4L2_PIX_FMT_GREY,
440 .depth = 8
441 }, {
432 .name = "JPG", 442 .name = "JPG",
433 .fourcc = V4L2_PIX_FMT_JPEG, 443 .fourcc = V4L2_PIX_FMT_JPEG,
434 .depth = 24 444 .depth = 24
435 }, { 445 }, {
436 .name = "8bpp GREY", 446 .name = "MJPG",
437 .fourcc = V4L2_PIX_FMT_GREY, 447 .fourcc = V4L2_PIX_FMT_MJPEG,
438 .depth = 8 448 .depth = 24
439 } 449 }
440}; 450};
441 451
@@ -610,6 +620,9 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)
610 for (i = 0; i < ARRAY_SIZE(formats); i++) { 620 for (i = 0; i < ARRAY_SIZE(formats); i++) {
611 if (-1 == formats[i].fourcc) 621 if (-1 == formats[i].fourcc)
612 continue; 622 continue;
623 if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
624 (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
625 continue;
613 if (formats[i].fourcc == fourcc) 626 if (formats[i].fourcc == fourcc)
614 return formats + i; 627 return formats + i;
615 } 628 }
@@ -653,6 +666,7 @@ static void s2255_fillbuff(struct s2255_channel *channel,
653 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); 666 memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
654 break; 667 break;
655 case V4L2_PIX_FMT_JPEG: 668 case V4L2_PIX_FMT_JPEG:
669 case V4L2_PIX_FMT_MJPEG:
656 buf->vb.size = jpgsize; 670 buf->vb.size = jpgsize;
657 memcpy(vbuf, tmpbuf, buf->vb.size); 671 memcpy(vbuf, tmpbuf, buf->vb.size);
658 break; 672 break;
@@ -856,7 +870,9 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
856 870
857 if (index >= ARRAY_SIZE(formats)) 871 if (index >= ARRAY_SIZE(formats))
858 return -EINVAL; 872 return -EINVAL;
859 873 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
874 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
875 return -EINVAL;
860 dprintk(4, "name %s\n", formats[index].name); 876 dprintk(4, "name %s\n", formats[index].name);
861 strlcpy(f->description, formats[index].name, sizeof(f->description)); 877 strlcpy(f->description, formats[index].name, sizeof(f->description));
862 f->pixelformat = formats[index].fourcc; 878 f->pixelformat = formats[index].fourcc;
@@ -1037,6 +1053,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1037 mode.color |= COLOR_Y8; 1053 mode.color |= COLOR_Y8;
1038 break; 1054 break;
1039 case V4L2_PIX_FMT_JPEG: 1055 case V4L2_PIX_FMT_JPEG:
1056 case V4L2_PIX_FMT_MJPEG:
1040 mode.color &= ~MASK_COLOR; 1057 mode.color &= ~MASK_COLOR;
1041 mode.color |= COLOR_JPG; 1058 mode.color |= COLOR_JPG;
1042 mode.color |= (channel->jc.quality << 8); 1059 mode.color |= (channel->jc.quality << 8);
@@ -2382,7 +2399,7 @@ static void read_pipe_completion(struct urb *purb)
2382 read_pipe_completion, pipe_info); 2399 read_pipe_completion, pipe_info);
2383 2400
2384 if (pipe_info->state != 0) { 2401 if (pipe_info->state != 0) {
2385 if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { 2402 if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
2386 dev_err(&dev->udev->dev, "error submitting urb\n"); 2403 dev_err(&dev->udev->dev, "error submitting urb\n");
2387 } 2404 }
2388 } else { 2405 } else {
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/video/s5p-fimc/Makefile
index 7ea1b1403b1e..df6954ab1d99 100644
--- a/drivers/media/video/s5p-fimc/Makefile
+++ b/drivers/media/video/s5p-fimc/Makefile
@@ -1,3 +1,5 @@
1s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-capture.o
2s5p-csis-objs := mipi-csis.o
1 3
2obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) := s5p-fimc.o 4obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
3s5p-fimc-y := fimc-core.o fimc-reg.o fimc-capture.o 5obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc.o
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c
new file mode 100644
index 000000000000..ef056d6605ca
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/mipi-csis.c
@@ -0,0 +1,724 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/kernel.h>
20#include <linux/memory.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/regulator/consumer.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-subdev.h>
29#include <plat/mipi_csis.h>
30#include "mipi-csis.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Debug level (0-1)");
35
36/* Register map definition */
37
38/* CSIS global control */
39#define S5PCSIS_CTRL 0x00
40#define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
41#define S5PCSIS_CTRL_DPDN_SWAP (1 << 31)
42#define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
43#define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
44#define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
45#define S5PCSIS_CTRL_RESET (1 << 4)
46#define S5PCSIS_CTRL_ENABLE (1 << 0)
47
48/* D-PHY control */
49#define S5PCSIS_DPHYCTRL 0x04
50#define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
51#define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
52
53#define S5PCSIS_CONFIG 0x08
54#define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
55#define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
56#define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
57#define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
58/* User defined formats, x = 1...4 */
59#define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
60#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
61#define S5PCSIS_CFG_NR_LANE_MASK 3
62
63/* Interrupt mask. */
64#define S5PCSIS_INTMSK 0x10
65#define S5PCSIS_INTMSK_EN_ALL 0xf000003f
66#define S5PCSIS_INTSRC 0x14
67
68/* Pixel resolution */
69#define S5PCSIS_RESOL 0x2c
70#define CSIS_MAX_PIX_WIDTH 0xffff
71#define CSIS_MAX_PIX_HEIGHT 0xffff
72
73enum {
74 CSIS_CLK_MUX,
75 CSIS_CLK_GATE,
76};
77
78static char *csi_clock_name[] = {
79 [CSIS_CLK_MUX] = "sclk_csis",
80 [CSIS_CLK_GATE] = "csis",
81};
82#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
83
84enum {
85 ST_POWERED = 1,
86 ST_STREAMING = 2,
87 ST_SUSPENDED = 4,
88};
89
90/**
91 * struct csis_state - the driver's internal state data structure
92 * @lock: mutex serializing the subdev and power management operations,
93 * protecting @format and @flags members
94 * @pads: CSIS pads array
95 * @sd: v4l2_subdev associated with CSIS device instance
96 * @pdev: CSIS platform device
97 * @regs_res: requested I/O register memory resource
98 * @regs: mmaped I/O registers memory
99 * @clock: CSIS clocks
100 * @irq: requested s5p-mipi-csis irq number
101 * @flags: the state variable for power and streaming control
102 * @csis_fmt: current CSIS pixel format
103 * @format: common media bus format for the source and sink pad
104 */
105struct csis_state {
106 struct mutex lock;
107 struct media_pad pads[CSIS_PADS_NUM];
108 struct v4l2_subdev sd;
109 struct platform_device *pdev;
110 struct resource *regs_res;
111 void __iomem *regs;
112 struct clk *clock[NUM_CSIS_CLOCKS];
113 int irq;
114 struct regulator *supply;
115 u32 flags;
116 const struct csis_pix_format *csis_fmt;
117 struct v4l2_mbus_framefmt format;
118};
119
120/**
121 * struct csis_pix_format - CSIS pixel format description
122 * @pix_width_alignment: horizontal pixel alignment, width will be
123 * multiple of 2^pix_width_alignment
124 * @code: corresponding media bus code
125 * @fmt_reg: S5PCSIS_CONFIG register value
126 */
127struct csis_pix_format {
128 unsigned int pix_width_alignment;
129 enum v4l2_mbus_pixelcode code;
130 u32 fmt_reg;
131};
132
133static const struct csis_pix_format s5pcsis_formats[] = {
134 {
135 .code = V4L2_MBUS_FMT_VYUY8_2X8,
136 .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
137 }, {
138 .code = V4L2_MBUS_FMT_JPEG_1X8,
139 .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
140 },
141};
142
143#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
144#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
145
146static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
147{
148 return container_of(sdev, struct csis_state, sd);
149}
150
151static const struct csis_pix_format *find_csis_format(
152 struct v4l2_mbus_framefmt *mf)
153{
154 int i;
155
156 for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
157 if (mf->code == s5pcsis_formats[i].code)
158 return &s5pcsis_formats[i];
159 return NULL;
160}
161
162static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
163{
164 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
165
166 val = on ? val | S5PCSIS_INTMSK_EN_ALL :
167 val & ~S5PCSIS_INTMSK_EN_ALL;
168 s5pcsis_write(state, S5PCSIS_INTMSK, val);
169}
170
171static void s5pcsis_reset(struct csis_state *state)
172{
173 u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
174
175 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
176 udelay(10);
177}
178
179static void s5pcsis_system_enable(struct csis_state *state, int on)
180{
181 u32 val;
182
183 val = s5pcsis_read(state, S5PCSIS_CTRL);
184 if (on)
185 val |= S5PCSIS_CTRL_ENABLE;
186 else
187 val &= ~S5PCSIS_CTRL_ENABLE;
188 s5pcsis_write(state, S5PCSIS_CTRL, val);
189
190 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
191 if (on)
192 val |= S5PCSIS_DPHYCTRL_ENABLE;
193 else
194 val &= ~S5PCSIS_DPHYCTRL_ENABLE;
195 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
196}
197
198/* Called with the state.lock mutex held */
199static void __s5pcsis_set_format(struct csis_state *state)
200{
201 struct v4l2_mbus_framefmt *mf = &state->format;
202 u32 val;
203
204 v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
205 mf->code, mf->width, mf->height);
206
207 /* Color format */
208 val = s5pcsis_read(state, S5PCSIS_CONFIG);
209 val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
210 s5pcsis_write(state, S5PCSIS_CONFIG, val);
211
212 /* Pixel resolution */
213 val = (mf->width << 16) | mf->height;
214 s5pcsis_write(state, S5PCSIS_RESOL, val);
215}
216
217static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
218{
219 u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
220
221 val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
222 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
223}
224
225static void s5pcsis_set_params(struct csis_state *state)
226{
227 struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
228 u32 val;
229
230 val = s5pcsis_read(state, S5PCSIS_CONFIG);
231 val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
232 s5pcsis_write(state, S5PCSIS_CONFIG, val);
233
234 __s5pcsis_set_format(state);
235 s5pcsis_set_hsync_settle(state, pdata->hs_settle);
236
237 val = s5pcsis_read(state, S5PCSIS_CTRL);
238 if (pdata->alignment == 32)
239 val |= S5PCSIS_CTRL_ALIGN_32BIT;
240 else /* 24-bits */
241 val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
242 /* Not using external clock. */
243 val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
244 s5pcsis_write(state, S5PCSIS_CTRL, val);
245
246 /* Update the shadow register. */
247 val = s5pcsis_read(state, S5PCSIS_CTRL);
248 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
249}
250
251static void s5pcsis_clk_put(struct csis_state *state)
252{
253 int i;
254
255 for (i = 0; i < NUM_CSIS_CLOCKS; i++)
256 if (!IS_ERR_OR_NULL(state->clock[i]))
257 clk_put(state->clock[i]);
258}
259
260static int s5pcsis_clk_get(struct csis_state *state)
261{
262 struct device *dev = &state->pdev->dev;
263 int i;
264
265 for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
266 state->clock[i] = clk_get(dev, csi_clock_name[i]);
267 if (IS_ERR(state->clock[i])) {
268 s5pcsis_clk_put(state);
269 dev_err(dev, "failed to get clock: %s\n",
270 csi_clock_name[i]);
271 return -ENXIO;
272 }
273 }
274 return 0;
275}
276
277static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
278{
279 struct csis_state *state = sd_to_csis_state(sd);
280 struct device *dev = &state->pdev->dev;
281
282 if (on)
283 return pm_runtime_get_sync(dev);
284
285 return pm_runtime_put_sync(dev);
286}
287
288static void s5pcsis_start_stream(struct csis_state *state)
289{
290 s5pcsis_reset(state);
291 s5pcsis_set_params(state);
292 s5pcsis_system_enable(state, true);
293 s5pcsis_enable_interrupts(state, true);
294}
295
296static void s5pcsis_stop_stream(struct csis_state *state)
297{
298 s5pcsis_enable_interrupts(state, false);
299 s5pcsis_system_enable(state, false);
300}
301
302/* v4l2_subdev operations */
303static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
304{
305 struct csis_state *state = sd_to_csis_state(sd);
306 int ret = 0;
307
308 v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
309 __func__, enable, state->flags);
310
311 if (enable) {
312 ret = pm_runtime_get_sync(&state->pdev->dev);
313 if (ret && ret != 1)
314 return ret;
315 }
316 mutex_lock(&state->lock);
317 if (enable) {
318 if (state->flags & ST_SUSPENDED) {
319 ret = -EBUSY;
320 goto unlock;
321 }
322 s5pcsis_start_stream(state);
323 state->flags |= ST_STREAMING;
324 } else {
325 s5pcsis_stop_stream(state);
326 state->flags &= ~ST_STREAMING;
327 }
328unlock:
329 mutex_unlock(&state->lock);
330 if (!enable)
331 pm_runtime_put(&state->pdev->dev);
332
333 return ret == 1 ? 0 : ret;
334}
335
336static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
337 struct v4l2_subdev_fh *fh,
338 struct v4l2_subdev_mbus_code_enum *code)
339{
340 if (code->index >= ARRAY_SIZE(s5pcsis_formats))
341 return -EINVAL;
342
343 code->code = s5pcsis_formats[code->index].code;
344 return 0;
345}
346
347static struct csis_pix_format const *s5pcsis_try_format(
348 struct v4l2_mbus_framefmt *mf)
349{
350 struct csis_pix_format const *csis_fmt;
351
352 csis_fmt = find_csis_format(mf);
353 if (csis_fmt == NULL)
354 csis_fmt = &s5pcsis_formats[0];
355
356 mf->code = csis_fmt->code;
357 v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
358 csis_fmt->pix_width_alignment,
359 &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
360 0);
361 return csis_fmt;
362}
363
364static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
365 struct csis_state *state, struct v4l2_subdev_fh *fh,
366 u32 pad, enum v4l2_subdev_format_whence which)
367{
368 if (which == V4L2_SUBDEV_FORMAT_TRY)
369 return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
370
371 return &state->format;
372}
373
374static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
375 struct v4l2_subdev_format *fmt)
376{
377 struct csis_state *state = sd_to_csis_state(sd);
378 struct csis_pix_format const *csis_fmt;
379 struct v4l2_mbus_framefmt *mf;
380
381 if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
382 return -EINVAL;
383
384 mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
385
386 if (fmt->pad == CSIS_PAD_SOURCE) {
387 if (mf) {
388 mutex_lock(&state->lock);
389 fmt->format = *mf;
390 mutex_unlock(&state->lock);
391 }
392 return 0;
393 }
394 csis_fmt = s5pcsis_try_format(&fmt->format);
395 if (mf) {
396 mutex_lock(&state->lock);
397 *mf = fmt->format;
398 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
399 state->csis_fmt = csis_fmt;
400 mutex_unlock(&state->lock);
401 }
402 return 0;
403}
404
405static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
406 struct v4l2_subdev_format *fmt)
407{
408 struct csis_state *state = sd_to_csis_state(sd);
409 struct v4l2_mbus_framefmt *mf;
410
411 if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
412 return -EINVAL;
413
414 mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
415 if (!mf)
416 return -EINVAL;
417
418 mutex_lock(&state->lock);
419 fmt->format = *mf;
420 mutex_unlock(&state->lock);
421 return 0;
422}
423
424static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
425 .s_power = s5pcsis_s_power,
426};
427
428static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
429 .enum_mbus_code = s5pcsis_enum_mbus_code,
430 .get_fmt = s5pcsis_get_fmt,
431 .set_fmt = s5pcsis_set_fmt,
432};
433
434static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
435 .s_stream = s5pcsis_s_stream,
436};
437
438static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
439 .core = &s5pcsis_core_ops,
440 .pad = &s5pcsis_pad_ops,
441 .video = &s5pcsis_video_ops,
442};
443
444static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
445{
446 struct csis_state *state = dev_id;
447 u32 val;
448
449 /* Just clear the interrupt pending bits. */
450 val = s5pcsis_read(state, S5PCSIS_INTSRC);
451 s5pcsis_write(state, S5PCSIS_INTSRC, val);
452
453 return IRQ_HANDLED;
454}
455
456static int __devinit s5pcsis_probe(struct platform_device *pdev)
457{
458 struct s5p_platform_mipi_csis *pdata;
459 struct resource *mem_res;
460 struct resource *regs_res;
461 struct csis_state *state;
462 int ret = -ENOMEM;
463
464 state = kzalloc(sizeof(*state), GFP_KERNEL);
465 if (!state)
466 return -ENOMEM;
467
468 mutex_init(&state->lock);
469 state->pdev = pdev;
470
471 pdata = pdev->dev.platform_data;
472 if (pdata == NULL || pdata->phy_enable == NULL) {
473 dev_err(&pdev->dev, "Platform data not fully specified\n");
474 goto e_free;
475 }
476
477 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
478 pdata->lanes > CSIS0_MAX_LANES) {
479 ret = -EINVAL;
480 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
481 pdata->lanes);
482 goto e_free;
483 }
484
485 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
486 if (!mem_res) {
487 dev_err(&pdev->dev, "Failed to get IO memory region\n");
488 goto e_free;
489 }
490
491 regs_res = request_mem_region(mem_res->start, resource_size(mem_res),
492 pdev->name);
493 if (!regs_res) {
494 dev_err(&pdev->dev, "Failed to request IO memory region\n");
495 goto e_free;
496 }
497 state->regs_res = regs_res;
498
499 state->regs = ioremap(mem_res->start, resource_size(mem_res));
500 if (!state->regs) {
501 dev_err(&pdev->dev, "Failed to remap IO region\n");
502 goto e_reqmem;
503 }
504
505 ret = s5pcsis_clk_get(state);
506 if (ret)
507 goto e_unmap;
508
509 clk_enable(state->clock[CSIS_CLK_MUX]);
510 if (pdata->clk_rate)
511 clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
512 else
513 dev_WARN(&pdev->dev, "No clock frequency specified!\n");
514
515 state->irq = platform_get_irq(pdev, 0);
516 if (state->irq < 0) {
517 ret = state->irq;
518 dev_err(&pdev->dev, "Failed to get irq\n");
519 goto e_clkput;
520 }
521
522 if (!pdata->fixed_phy_vdd) {
523 state->supply = regulator_get(&pdev->dev, "vdd");
524 if (IS_ERR(state->supply)) {
525 ret = PTR_ERR(state->supply);
526 state->supply = NULL;
527 goto e_clkput;
528 }
529 }
530
531 ret = request_irq(state->irq, s5pcsis_irq_handler, 0,
532 dev_name(&pdev->dev), state);
533 if (ret) {
534 dev_err(&pdev->dev, "request_irq failed\n");
535 goto e_regput;
536 }
537
538 v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
539 state->sd.owner = THIS_MODULE;
540 strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
541 state->csis_fmt = &s5pcsis_formats[0];
542
543 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
544 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
545 ret = media_entity_init(&state->sd.entity,
546 CSIS_PADS_NUM, state->pads, 0);
547 if (ret < 0)
548 goto e_irqfree;
549
550 /* This allows to retrieve the platform device id by the host driver */
551 v4l2_set_subdevdata(&state->sd, pdev);
552
553 /* .. and a pointer to the subdev. */
554 platform_set_drvdata(pdev, &state->sd);
555
556 state->flags = ST_SUSPENDED;
557 pm_runtime_enable(&pdev->dev);
558
559 return 0;
560
561e_irqfree:
562 free_irq(state->irq, state);
563e_regput:
564 if (state->supply)
565 regulator_put(state->supply);
566e_clkput:
567 clk_disable(state->clock[CSIS_CLK_MUX]);
568 s5pcsis_clk_put(state);
569e_unmap:
570 iounmap(state->regs);
571e_reqmem:
572 release_mem_region(regs_res->start, resource_size(regs_res));
573e_free:
574 kfree(state);
575 return ret;
576}
577
578static int s5pcsis_suspend(struct device *dev)
579{
580 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
581 struct platform_device *pdev = to_platform_device(dev);
582 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
583 struct csis_state *state = sd_to_csis_state(sd);
584 int ret = 0;
585
586 v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
587 __func__, state->flags);
588
589 mutex_lock(&state->lock);
590 if (state->flags & ST_POWERED) {
591 s5pcsis_stop_stream(state);
592 ret = pdata->phy_enable(state->pdev, false);
593 if (ret)
594 goto unlock;
595 if (state->supply) {
596 ret = regulator_disable(state->supply);
597 if (ret)
598 goto unlock;
599 }
600 clk_disable(state->clock[CSIS_CLK_GATE]);
601 state->flags &= ~ST_POWERED;
602 }
603 state->flags |= ST_SUSPENDED;
604 unlock:
605 mutex_unlock(&state->lock);
606 return ret ? -EAGAIN : 0;
607}
608
609static int s5pcsis_resume(struct device *dev)
610{
611 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
612 struct platform_device *pdev = to_platform_device(dev);
613 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
614 struct csis_state *state = sd_to_csis_state(sd);
615 int ret = 0;
616
617 v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
618 __func__, state->flags);
619
620 mutex_lock(&state->lock);
621 if (!(state->flags & ST_SUSPENDED))
622 goto unlock;
623
624 if (!(state->flags & ST_POWERED)) {
625 if (state->supply)
626 ret = regulator_enable(state->supply);
627 if (ret)
628 goto unlock;
629
630 ret = pdata->phy_enable(state->pdev, true);
631 if (!ret) {
632 state->flags |= ST_POWERED;
633 } else if (state->supply) {
634 regulator_disable(state->supply);
635 goto unlock;
636 }
637 clk_enable(state->clock[CSIS_CLK_GATE]);
638 }
639 if (state->flags & ST_STREAMING)
640 s5pcsis_start_stream(state);
641
642 state->flags &= ~ST_SUSPENDED;
643 unlock:
644 mutex_unlock(&state->lock);
645 return ret ? -EAGAIN : 0;
646}
647
648#ifdef CONFIG_PM_SLEEP
649static int s5pcsis_pm_suspend(struct device *dev)
650{
651 return s5pcsis_suspend(dev);
652}
653
654static int s5pcsis_pm_resume(struct device *dev)
655{
656 int ret;
657
658 ret = s5pcsis_resume(dev);
659
660 if (!ret) {
661 pm_runtime_disable(dev);
662 ret = pm_runtime_set_active(dev);
663 pm_runtime_enable(dev);
664 }
665
666 return ret;
667}
668#endif
669
670static int __devexit s5pcsis_remove(struct platform_device *pdev)
671{
672 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
673 struct csis_state *state = sd_to_csis_state(sd);
674 struct resource *res = state->regs_res;
675
676 pm_runtime_disable(&pdev->dev);
677 s5pcsis_suspend(&pdev->dev);
678 clk_disable(state->clock[CSIS_CLK_MUX]);
679 pm_runtime_set_suspended(&pdev->dev);
680
681 s5pcsis_clk_put(state);
682 if (state->supply)
683 regulator_put(state->supply);
684
685 media_entity_cleanup(&state->sd.entity);
686 free_irq(state->irq, state);
687 iounmap(state->regs);
688 release_mem_region(res->start, resource_size(res));
689 kfree(state);
690
691 return 0;
692}
693
694static const struct dev_pm_ops s5pcsis_pm_ops = {
695 SET_RUNTIME_PM_OPS(s5pcsis_suspend, s5pcsis_resume, NULL)
696 SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_pm_suspend, s5pcsis_pm_resume)
697};
698
699static struct platform_driver s5pcsis_driver = {
700 .probe = s5pcsis_probe,
701 .remove = __devexit_p(s5pcsis_remove),
702 .driver = {
703 .name = CSIS_DRIVER_NAME,
704 .owner = THIS_MODULE,
705 .pm = &s5pcsis_pm_ops,
706 },
707};
708
709static int __init s5pcsis_init(void)
710{
711 return platform_driver_probe(&s5pcsis_driver, s5pcsis_probe);
712}
713
714static void __exit s5pcsis_exit(void)
715{
716 platform_driver_unregister(&s5pcsis_driver);
717}
718
719module_init(s5pcsis_init);
720module_exit(s5pcsis_exit);
721
722MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
723MODULE_DESCRIPTION("S5P/EXYNOS4 MIPI CSI receiver driver");
724MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.h b/drivers/media/video/s5p-fimc/mipi-csis.h
new file mode 100644
index 000000000000..f5691336dd5c
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/mipi-csis.h
@@ -0,0 +1,22 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef S5P_MIPI_CSIS_H_
11#define S5P_MIPI_CSIS_H_
12
13#define CSIS_DRIVER_NAME "s5p-mipi-csis"
14#define CSIS_MAX_ENTITIES 2
15#define CSIS0_MAX_LANES 4
16#define CSIS1_MAX_LANES 2
17
18#define CSIS_PAD_SINK 0
19#define CSIS_PAD_SOURCE 1
20#define CSIS_PADS_NUM 2
21
22#endif
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 50f1be05ebd3..e2062b240e32 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5591,6 +5591,105 @@ struct saa7134_board saa7134_boards[] = {
5591 .amux = TV, 5591 .amux = TV,
5592 }, 5592 },
5593 }, 5593 },
5594 [SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2] = {
5595 /* Timothy Lee <timothy.lee@siriushk.com> */
5596 .name = "MagicPro ProHDTV Pro2 DMB-TH/Hybrid",
5597 .audio_clock = 0x00187de7,
5598 .tuner_type = TUNER_PHILIPS_TDA8290,
5599 .radio_type = UNSET,
5600 .tuner_config = 3,
5601 .tuner_addr = ADDR_UNSET,
5602 .radio_addr = ADDR_UNSET,
5603 .gpiomask = 0x02050000,
5604 .mpeg = SAA7134_MPEG_DVB,
5605 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5606 .inputs = { {
5607 .name = name_tv,
5608 .vmux = 1,
5609 .amux = TV,
5610 .tv = 1,
5611 .gpio = 0x00050000,
5612 }, {
5613 .name = name_comp1,
5614 .vmux = 3,
5615 .amux = LINE1,
5616 .gpio = 0x00050000,
5617 }, {
5618 .name = name_svideo,
5619 .vmux = 8,
5620 .amux = LINE1,
5621 .gpio = 0x00050000,
5622 } },
5623 .radio = {
5624 .name = name_radio,
5625 .amux = TV,
5626 .gpio = 0x00050000,
5627 },
5628 .mute = {
5629 .name = name_mute,
5630 .vmux = 0,
5631 .amux = TV,
5632 .gpio = 0x00050000,
5633 },
5634 },
5635 [SAA7134_BOARD_BEHOLD_501] = {
5636 /* Beholder Intl. Ltd. 2010 */
5637 /* Dmitry Belimov <d.belimov@gmail.com> */
5638 .name = "Beholder BeholdTV 501",
5639 .audio_clock = 0x00200000,
5640 .tuner_type = TUNER_ABSENT,
5641 .radio_type = UNSET,
5642 .tuner_addr = ADDR_UNSET,
5643 .radio_addr = ADDR_UNSET,
5644 .gpiomask = 0x00008000,
5645 .inputs = { {
5646 .name = name_tv,
5647 .vmux = 3,
5648 .amux = LINE2,
5649 .tv = 1,
5650 }, {
5651 .name = name_comp1,
5652 .vmux = 1,
5653 .amux = LINE1,
5654 }, {
5655 .name = name_svideo,
5656 .vmux = 8,
5657 .amux = LINE1,
5658 } },
5659 .mute = {
5660 .name = name_mute,
5661 .amux = LINE1,
5662 },
5663 },
5664 [SAA7134_BOARD_BEHOLD_503FM] = {
5665 /* Beholder Intl. Ltd. 2010 */
5666 /* Dmitry Belimov <d.belimov@gmail.com> */
5667 .name = "Beholder BeholdTV 503 FM",
5668 .audio_clock = 0x00200000,
5669 .tuner_type = TUNER_ABSENT,
5670 .radio_type = UNSET,
5671 .tuner_addr = ADDR_UNSET,
5672 .radio_addr = ADDR_UNSET,
5673 .gpiomask = 0x00008000,
5674 .inputs = { {
5675 .name = name_tv,
5676 .vmux = 3,
5677 .amux = LINE2,
5678 .tv = 1,
5679 }, {
5680 .name = name_comp1,
5681 .vmux = 1,
5682 .amux = LINE1,
5683 }, {
5684 .name = name_svideo,
5685 .vmux = 8,
5686 .amux = LINE1,
5687 } },
5688 .mute = {
5689 .name = name_mute,
5690 .amux = LINE1,
5691 },
5692 },
5594 5693
5595}; 5694};
5596 5695
@@ -6796,6 +6895,24 @@ struct pci_device_id saa7134_pci_tbl[] = {
6796 .subdevice = 0xc900, 6895 .subdevice = 0xc900,
6797 .driver_data = SAA7134_BOARD_VIDEOMATE_M1F, 6896 .driver_data = SAA7134_BOARD_VIDEOMATE_M1F,
6798 }, { 6897 }, {
6898 .vendor = PCI_VENDOR_ID_PHILIPS,
6899 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6900 .subvendor = 0x5ace,
6901 .subdevice = 0x5030,
6902 .driver_data = SAA7134_BOARD_BEHOLD_503FM,
6903 }, {
6904 .vendor = PCI_VENDOR_ID_PHILIPS,
6905 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6906 .subvendor = 0x5ace,
6907 .subdevice = 0x5010,
6908 .driver_data = SAA7134_BOARD_BEHOLD_501,
6909 }, {
6910 .vendor = PCI_VENDOR_ID_PHILIPS,
6911 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6912 .subvendor = 0x17de,
6913 .subdevice = 0xd136,
6914 .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
6915 }, {
6799 /* --- boards without eeprom + subsystem ID --- */ 6916 /* --- boards without eeprom + subsystem ID --- */
6800 .vendor = PCI_VENDOR_ID_PHILIPS, 6917 .vendor = PCI_VENDOR_ID_PHILIPS,
6801 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6918 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6988,6 +7105,7 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
6988 switch (dev->board) { 7105 switch (dev->board) {
6989 case SAA7134_BOARD_HAUPPAUGE_HVR1150: 7106 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
6990 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7107 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7108 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
6991 ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg); 7109 ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
6992 break; 7110 break;
6993 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7111 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
@@ -7014,6 +7132,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
7014 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7132 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7015 case SAA7134_BOARD_AVERMEDIA_M733A: 7133 case SAA7134_BOARD_AVERMEDIA_M733A:
7016 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7134 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
7135 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
7017 /* tda8290 + tda18271 */ 7136 /* tda8290 + tda18271 */
7018 ret = saa7134_tda8290_18271_callback(dev, command, arg); 7137 ret = saa7134_tda8290_18271_callback(dev, command, arg);
7019 break; 7138 break;
@@ -7264,6 +7383,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7264 break; 7383 break;
7265 case SAA7134_BOARD_HAUPPAUGE_HVR1150: 7384 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
7266 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7385 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7386 dev->has_remote = SAA7134_REMOTE_GPIO;
7267 /* GPIO 26 high for digital, low for analog */ 7387 /* GPIO 26 high for digital, low for analog */
7268 saa7134_set_gpio(dev, 26, 0); 7388 saa7134_set_gpio(dev, 26, 0);
7269 msleep(1); 7389 msleep(1);
@@ -7326,6 +7446,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7326 saa7134_set_gpio(dev, 1, 1); 7446 saa7134_set_gpio(dev, 1, 1);
7327 dev->has_remote = SAA7134_REMOTE_GPIO; 7447 dev->has_remote = SAA7134_REMOTE_GPIO;
7328 break; 7448 break;
7449 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
7450 /* enable LGS-8G75 */
7451 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0e050000, 0x0c050000);
7452 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0e050000, 0x0c050000);
7453 break;
7329 } 7454 }
7330 return 0; 7455 return 0;
7331} 7456}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 41f836fc93ec..f9be737ba6f4 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -927,7 +927,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
927 } 927 }
928 928
929 /* print pci info */ 929 /* print pci info */
930 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 930 dev->pci_rev = pci_dev->revision;
931 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 931 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
932 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 932 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
933 "latency: %d, mmio: 0x%llx\n", dev->name, 933 "latency: %d, mmio: 0x%llx\n", dev->name,
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index f65cad287b83..996a206c6d79 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -53,6 +53,7 @@
53#include "lgdt3305.h" 53#include "lgdt3305.h"
54#include "tda8290.h" 54#include "tda8290.h"
55#include "mb86a20s.h" 55#include "mb86a20s.h"
56#include "lgs8gxx.h"
56 57
57#include "zl10353.h" 58#include "zl10353.h"
58 59
@@ -1123,6 +1124,26 @@ static struct tda18271_config dtv1000s_tda18271_config = {
1123 .gate = TDA18271_GATE_ANALOG, 1124 .gate = TDA18271_GATE_ANALOG,
1124}; 1125};
1125 1126
1127static struct lgs8gxx_config prohdtv_pro2_lgs8g75_config = {
1128 .prod = LGS8GXX_PROD_LGS8G75,
1129 .demod_address = 0x1d,
1130 .serial_ts = 0,
1131 .ts_clk_pol = 1,
1132 .ts_clk_gated = 0,
1133 .if_clk_freq = 30400, /* 30.4 MHz */
1134 .if_freq = 4000, /* 4.00 MHz */
1135 .if_neg_center = 0,
1136 .ext_adc = 0,
1137 .adc_signed = 1,
1138 .adc_vpp = 3, /* 2.0 Vpp */
1139 .if_neg_edge = 1,
1140};
1141
1142static struct tda18271_config prohdtv_pro2_tda18271_config = {
1143 .gate = TDA18271_GATE_ANALOG,
1144 .output_opt = TDA18271_OUTPUT_LT_OFF,
1145};
1146
1126/* ================================================================== 1147/* ==================================================================
1127 * Core code 1148 * Core code
1128 */ 1149 */
@@ -1674,6 +1695,19 @@ static int dvb_init(struct saa7134_dev *dev)
1674 1695
1675 /* mb86a20s need to use the I2C gateway */ 1696 /* mb86a20s need to use the I2C gateway */
1676 break; 1697 break;
1698 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
1699 fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
1700 &prohdtv_pro2_lgs8g75_config,
1701 &dev->i2c_adap);
1702 if (fe0->dvb.frontend != NULL) {
1703 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1704 &dev->i2c_adap, 0x4b,
1705 &tda829x_no_probe);
1706 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1707 0x60, &dev->i2c_adap,
1708 &prohdtv_pro2_tda18271_config);
1709 }
1710 break;
1677 default: 1711 default:
1678 wprintk("Huh? unknown DVB card?\n"); 1712 wprintk("Huh? unknown DVB card?\n");
1679 break; 1713 break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index be1c2a2de27c..ff6c0e97563e 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -756,6 +756,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
756 mask_keycode = 0x0ff00; 756 mask_keycode = 0x0ff00;
757 mask_keyup = 0x040000; 757 mask_keyup = 0x040000;
758 break; 758 break;
759 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
760 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
761 ir_codes = RC_MAP_HAUPPAUGE;
762 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
763 mask_keyup = 0x0040000;
764 mask_keycode = 0xffff;
765 raw_decode = true;
766 break;
759 } 767 }
760 if (NULL == ir_codes) { 768 if (NULL == ir_codes) {
761 printk("%s: Oops: IR config error [card=%d]\n", 769 printk("%s: Oops: IR config error [card=%d]\n",
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index f96cd5d761f9..28eb10398323 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -328,6 +328,9 @@ struct saa7134_card_ir {
328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182 328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
329#define SAA7134_BOARD_VIDEOMATE_M1F 183 329#define SAA7134_BOARD_VIDEOMATE_M1F 183
330#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184 330#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184
331#define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185
332#define SAA7134_BOARD_BEHOLD_501 186
333#define SAA7134_BOARD_BEHOLD_503FM 187
331 334
332#define SAA7134_MAXBOARDS 32 335#define SAA7134_MAXBOARDS 32
333#define SAA7134_INPUT_MAX 8 336#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index b813aec1e456..3b7d7b4e3034 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -1247,7 +1247,7 @@ static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
1247 } 1247 }
1248 1248
1249 /* print pci info */ 1249 /* print pci info */
1250 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1250 dev->pci_rev = pci_dev->revision;
1251 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1251 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1252 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1252 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1253 "latency: %d, mmio: 0x%llx\n", dev->name, 1253 "latency: %d, mmio: 0x%llx\n", dev->name,
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 134e86bf6d97..3ae5c9c58cba 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/completion.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
21#include <linux/dma-mapping.h> 22#include <linux/dma-mapping.h>
22#include <linux/errno.h> 23#include <linux/errno.h>
@@ -106,6 +107,7 @@ struct sh_mobile_ceu_dev {
106 struct vb2_alloc_ctx *alloc_ctx; 107 struct vb2_alloc_ctx *alloc_ctx;
107 108
108 struct sh_mobile_ceu_info *pdata; 109 struct sh_mobile_ceu_info *pdata;
110 struct completion complete;
109 111
110 u32 cflcr; 112 u32 cflcr;
111 113
@@ -114,6 +116,7 @@ struct sh_mobile_ceu_dev {
114 116
115 unsigned int image_mode:1; 117 unsigned int image_mode:1;
116 unsigned int is_16bit:1; 118 unsigned int is_16bit:1;
119 unsigned int frozen:1;
117}; 120};
118 121
119struct sh_mobile_ceu_cam { 122struct sh_mobile_ceu_cam {
@@ -273,7 +276,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
273 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK); 276 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
274 status = ceu_read(pcdev, CETCR); 277 status = ceu_read(pcdev, CETCR);
275 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC); 278 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
276 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK); 279 if (!pcdev->frozen)
280 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
277 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP); 281 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
278 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW); 282 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
279 283
@@ -287,6 +291,11 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
287 ret = -EIO; 291 ret = -EIO;
288 } 292 }
289 293
294 if (pcdev->frozen) {
295 complete(&pcdev->complete);
296 return ret;
297 }
298
290 if (!pcdev->active) 299 if (!pcdev->active)
291 return ret; 300 return ret;
292 301
@@ -378,12 +387,11 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
378 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 387 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
379 struct sh_mobile_ceu_dev *pcdev = ici->priv; 388 struct sh_mobile_ceu_dev *pcdev = ici->priv;
380 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 389 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
381 unsigned long flags;
382 390
383 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 391 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
384 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 392 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
385 393
386 spin_lock_irqsave(&pcdev->lock, flags); 394 spin_lock_irq(&pcdev->lock);
387 list_add_tail(&buf->queue, &pcdev->capture); 395 list_add_tail(&buf->queue, &pcdev->capture);
388 396
389 if (!pcdev->active) { 397 if (!pcdev->active) {
@@ -395,7 +403,7 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
395 pcdev->active = vb; 403 pcdev->active = vb;
396 sh_mobile_ceu_capture(pcdev); 404 sh_mobile_ceu_capture(pcdev);
397 } 405 }
398 spin_unlock_irqrestore(&pcdev->lock, flags); 406 spin_unlock_irq(&pcdev->lock);
399} 407}
400 408
401static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb) 409static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -404,9 +412,8 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
404 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 412 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
405 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 413 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
406 struct sh_mobile_ceu_dev *pcdev = ici->priv; 414 struct sh_mobile_ceu_dev *pcdev = ici->priv;
407 unsigned long flags;
408 415
409 spin_lock_irqsave(&pcdev->lock, flags); 416 spin_lock_irq(&pcdev->lock);
410 417
411 if (pcdev->active == vb) { 418 if (pcdev->active == vb) {
412 /* disable capture (release DMA buffer), reset */ 419 /* disable capture (release DMA buffer), reset */
@@ -417,7 +424,7 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
417 /* Doesn't hurt also if the list is empty */ 424 /* Doesn't hurt also if the list is empty */
418 list_del_init(&buf->queue); 425 list_del_init(&buf->queue);
419 426
420 spin_unlock_irqrestore(&pcdev->lock, flags); 427 spin_unlock_irq(&pcdev->lock);
421} 428}
422 429
423static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb) 430static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
@@ -427,6 +434,25 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
427 return 0; 434 return 0;
428} 435}
429 436
437static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
438{
439 struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
440 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
441 struct sh_mobile_ceu_dev *pcdev = ici->priv;
442 struct list_head *buf_head, *tmp;
443
444 spin_lock_irq(&pcdev->lock);
445
446 pcdev->active = NULL;
447
448 list_for_each_safe(buf_head, tmp, &pcdev->capture)
449 list_del_init(buf_head);
450
451 spin_unlock_irq(&pcdev->lock);
452
453 return sh_mobile_ceu_soft_reset(pcdev);
454}
455
430static struct vb2_ops sh_mobile_ceu_videobuf_ops = { 456static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
431 .queue_setup = sh_mobile_ceu_videobuf_setup, 457 .queue_setup = sh_mobile_ceu_videobuf_setup,
432 .buf_prepare = sh_mobile_ceu_videobuf_prepare, 458 .buf_prepare = sh_mobile_ceu_videobuf_prepare,
@@ -435,6 +461,7 @@ static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
435 .buf_init = sh_mobile_ceu_videobuf_init, 461 .buf_init = sh_mobile_ceu_videobuf_init,
436 .wait_prepare = soc_camera_unlock, 462 .wait_prepare = soc_camera_unlock,
437 .wait_finish = soc_camera_lock, 463 .wait_finish = soc_camera_lock,
464 .stop_streaming = sh_mobile_ceu_stop_streaming,
438}; 465};
439 466
440static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) 467static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
@@ -500,7 +527,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
500{ 527{
501 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 528 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
502 struct sh_mobile_ceu_dev *pcdev = ici->priv; 529 struct sh_mobile_ceu_dev *pcdev = ici->priv;
503 unsigned long flags;
504 530
505 BUG_ON(icd != pcdev->icd); 531 BUG_ON(icd != pcdev->icd);
506 532
@@ -509,13 +535,13 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
509 sh_mobile_ceu_soft_reset(pcdev); 535 sh_mobile_ceu_soft_reset(pcdev);
510 536
511 /* make sure active buffer is canceled */ 537 /* make sure active buffer is canceled */
512 spin_lock_irqsave(&pcdev->lock, flags); 538 spin_lock_irq(&pcdev->lock);
513 if (pcdev->active) { 539 if (pcdev->active) {
514 list_del_init(&to_ceu_vb(pcdev->active)->queue); 540 list_del_init(&to_ceu_vb(pcdev->active)->queue);
515 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR); 541 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
516 pcdev->active = NULL; 542 pcdev->active = NULL;
517 } 543 }
518 spin_unlock_irqrestore(&pcdev->lock, flags); 544 spin_unlock_irq(&pcdev->lock);
519 545
520 pm_runtime_put_sync(ici->v4l2_dev.dev); 546 pm_runtime_put_sync(ici->v4l2_dev.dev);
521 547
@@ -891,8 +917,8 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
891 917
892 fmt = soc_mbus_get_fmtdesc(code); 918 fmt = soc_mbus_get_fmtdesc(code);
893 if (!fmt) { 919 if (!fmt) {
894 dev_err(dev, "Invalid format code #%u: %d\n", idx, code); 920 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
895 return -EINVAL; 921 return 0;
896 } 922 }
897 923
898 if (!pcdev->pdata->csi2_dev) { 924 if (!pcdev->pdata->csi2_dev) {
@@ -1330,7 +1356,7 @@ static int client_scale(struct soc_camera_device *icd,
1330/* 1356/*
1331 * CEU can scale and crop, but we don't want to waste bandwidth and kill the 1357 * CEU can scale and crop, but we don't want to waste bandwidth and kill the
1332 * framerate by always requesting the maximum image from the client. See 1358 * framerate by always requesting the maximum image from the client. See
1333 * Documentation/video4linux/sh_mobile_camera_ceu.txt for a description of 1359 * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of
1334 * scaling and cropping algorithms and for the meaning of referenced here steps. 1360 * scaling and cropping algorithms and for the meaning of referenced here steps.
1335 */ 1361 */
1336static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, 1362static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
@@ -1377,10 +1403,6 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1377 if (mf.width > 2560 || mf.height > 1920) 1403 if (mf.width > 2560 || mf.height > 1920)
1378 return -EINVAL; 1404 return -EINVAL;
1379 1405
1380 /* Cache camera output window */
1381 cam->width = mf.width;
1382 cam->height = mf.height;
1383
1384 /* 4. Calculate camera scales */ 1406 /* 4. Calculate camera scales */
1385 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width); 1407 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1386 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height); 1408 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
@@ -1389,6 +1411,39 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1389 interm_width = scale_down(rect->width, scale_cam_h); 1411 interm_width = scale_down(rect->width, scale_cam_h);
1390 interm_height = scale_down(rect->height, scale_cam_v); 1412 interm_height = scale_down(rect->height, scale_cam_v);
1391 1413
1414 if (interm_width < icd->user_width) {
1415 u32 new_scale_h;
1416
1417 new_scale_h = calc_generic_scale(rect->width, icd->user_width);
1418
1419 mf.width = scale_down(cam_rect->width, new_scale_h);
1420 }
1421
1422 if (interm_height < icd->user_height) {
1423 u32 new_scale_v;
1424
1425 new_scale_v = calc_generic_scale(rect->height, icd->user_height);
1426
1427 mf.height = scale_down(cam_rect->height, new_scale_v);
1428 }
1429
1430 if (interm_width < icd->user_width || interm_height < icd->user_height) {
1431 ret = v4l2_device_call_until_err(sd->v4l2_dev, (int)icd, video,
1432 s_mbus_fmt, &mf);
1433 if (ret < 0)
1434 return ret;
1435
1436 dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height);
1437 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1438 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
1439 interm_width = scale_down(rect->width, scale_cam_h);
1440 interm_height = scale_down(rect->height, scale_cam_v);
1441 }
1442
1443 /* Cache camera output window */
1444 cam->width = mf.width;
1445 cam->height = mf.height;
1446
1392 if (pcdev->image_mode) { 1447 if (pcdev->image_mode) {
1393 out_width = min(interm_width, icd->user_width); 1448 out_width = min(interm_width, icd->user_width);
1394 out_height = min(interm_height, icd->user_height); 1449 out_height = min(interm_height, icd->user_height);
@@ -1704,6 +1759,63 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1704 return ret; 1759 return ret;
1705} 1760}
1706 1761
1762static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1763 struct v4l2_crop *a)
1764{
1765 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1766 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1767 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1768 u32 out_width = icd->user_width, out_height = icd->user_height;
1769 int ret;
1770
1771 /* Freeze queue */
1772 pcdev->frozen = 1;
1773 /* Wait for frame */
1774 ret = wait_for_completion_interruptible(&pcdev->complete);
1775 /* Stop the client */
1776 ret = v4l2_subdev_call(sd, video, s_stream, 0);
1777 if (ret < 0)
1778 dev_warn(icd->dev.parent,
1779 "Client failed to stop the stream: %d\n", ret);
1780 else
1781 /* Do the crop, if it fails, there's nothing more we can do */
1782 sh_mobile_ceu_set_crop(icd, a);
1783
1784 dev_geo(icd->dev.parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
1785
1786 if (icd->user_width != out_width || icd->user_height != out_height) {
1787 struct v4l2_format f = {
1788 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1789 .fmt.pix = {
1790 .width = out_width,
1791 .height = out_height,
1792 .pixelformat = icd->current_fmt->host_fmt->fourcc,
1793 .field = pcdev->field,
1794 .colorspace = icd->colorspace,
1795 },
1796 };
1797 ret = sh_mobile_ceu_set_fmt(icd, &f);
1798 if (!ret && (out_width != f.fmt.pix.width ||
1799 out_height != f.fmt.pix.height))
1800 ret = -EINVAL;
1801 if (!ret) {
1802 icd->user_width = out_width;
1803 icd->user_height = out_height;
1804 ret = sh_mobile_ceu_set_bus_param(icd,
1805 icd->current_fmt->host_fmt->fourcc);
1806 }
1807 }
1808
1809 /* Thaw the queue */
1810 pcdev->frozen = 0;
1811 spin_lock_irq(&pcdev->lock);
1812 sh_mobile_ceu_capture(pcdev);
1813 spin_unlock_irq(&pcdev->lock);
1814 /* Start the client */
1815 ret = v4l2_subdev_call(sd, video, s_stream, 1);
1816 return ret;
1817}
1818
1707static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) 1819static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
1708{ 1820{
1709 struct soc_camera_device *icd = file->private_data; 1821 struct soc_camera_device *icd = file->private_data;
@@ -1790,6 +1902,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1790 .put_formats = sh_mobile_ceu_put_formats, 1902 .put_formats = sh_mobile_ceu_put_formats,
1791 .get_crop = sh_mobile_ceu_get_crop, 1903 .get_crop = sh_mobile_ceu_get_crop,
1792 .set_crop = sh_mobile_ceu_set_crop, 1904 .set_crop = sh_mobile_ceu_set_crop,
1905 .set_livecrop = sh_mobile_ceu_set_livecrop,
1793 .set_fmt = sh_mobile_ceu_set_fmt, 1906 .set_fmt = sh_mobile_ceu_set_fmt,
1794 .try_fmt = sh_mobile_ceu_try_fmt, 1907 .try_fmt = sh_mobile_ceu_try_fmt,
1795 .set_ctrl = sh_mobile_ceu_set_ctrl, 1908 .set_ctrl = sh_mobile_ceu_set_ctrl,
@@ -1856,6 +1969,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
1856 1969
1857 INIT_LIST_HEAD(&pcdev->capture); 1970 INIT_LIST_HEAD(&pcdev->capture);
1858 spin_lock_init(&pcdev->lock); 1971 spin_lock_init(&pcdev->lock);
1972 init_completion(&pcdev->complete);
1859 1973
1860 pcdev->pdata = pdev->dev.platform_data; 1974 pcdev->pdata = pdev->dev.platform_data;
1861 if (!pcdev->pdata) { 1975 if (!pcdev->pdata) {
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index ddb4c091dedc..398864370267 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -41,6 +41,11 @@
41#define DEFAULT_WIDTH 640 41#define DEFAULT_WIDTH 640
42#define DEFAULT_HEIGHT 480 42#define DEFAULT_HEIGHT 480
43 43
44#define is_streaming(ici, icd) \
45 (((ici)->ops->init_videobuf) ? \
46 (icd)->vb_vidq.streaming : \
47 vb2_is_streaming(&(icd)->vb2_vidq))
48
44static LIST_HEAD(hosts); 49static LIST_HEAD(hosts);
45static LIST_HEAD(devices); 50static LIST_HEAD(devices);
46static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ 51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
@@ -358,8 +363,6 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
358 if (!icd->user_formats) 363 if (!icd->user_formats)
359 return -ENOMEM; 364 return -ENOMEM;
360 365
361 icd->num_user_formats = fmts;
362
363 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts); 366 dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);
364 367
365 /* Second pass - actually fill data formats */ 368 /* Second pass - actually fill data formats */
@@ -367,9 +370,10 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
367 for (i = 0; i < raw_fmts; i++) 370 for (i = 0; i < raw_fmts; i++)
368 if (!ici->ops->get_formats) { 371 if (!ici->ops->get_formats) {
369 v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); 372 v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
370 icd->user_formats[i].host_fmt = 373 icd->user_formats[fmts].host_fmt =
371 soc_mbus_get_fmtdesc(code); 374 soc_mbus_get_fmtdesc(code);
372 icd->user_formats[i].code = code; 375 if (icd->user_formats[fmts].host_fmt)
376 icd->user_formats[fmts++].code = code;
373 } else { 377 } else {
374 ret = ici->ops->get_formats(icd, i, 378 ret = ici->ops->get_formats(icd, i,
375 &icd->user_formats[fmts]); 379 &icd->user_formats[fmts]);
@@ -378,12 +382,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
378 fmts += ret; 382 fmts += ret;
379 } 383 }
380 384
385 icd->num_user_formats = fmts;
381 icd->current_fmt = &icd->user_formats[0]; 386 icd->current_fmt = &icd->user_formats[0];
382 387
383 return 0; 388 return 0;
384 389
385egfmt: 390egfmt:
386 icd->num_user_formats = 0;
387 vfree(icd->user_formats); 391 vfree(icd->user_formats);
388 return ret; 392 return ret;
389} 393}
@@ -662,7 +666,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
662 if (icd->streamer && icd->streamer != file) 666 if (icd->streamer && icd->streamer != file)
663 return -EBUSY; 667 return -EBUSY;
664 668
665 if (icd->vb_vidq.bufs[0]) { 669 if (is_streaming(to_soc_camera_host(icd->dev.parent), icd)) {
666 dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); 670 dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
667 return -EBUSY; 671 return -EBUSY;
668 } 672 }
@@ -903,14 +907,17 @@ static int soc_camera_s_crop(struct file *file, void *fh,
903 if (ret < 0) { 907 if (ret < 0) {
904 dev_err(&icd->dev, 908 dev_err(&icd->dev,
905 "S_CROP denied: getting current crop failed\n"); 909 "S_CROP denied: getting current crop failed\n");
906 } else if (icd->vb_vidq.bufs[0] && 910 } else if ((a->c.width == current_crop.c.width &&
907 (a->c.width != current_crop.c.width || 911 a->c.height == current_crop.c.height) ||
908 a->c.height != current_crop.c.height)) { 912 !is_streaming(ici, icd)) {
913 /* same size or not streaming - use .set_crop() */
914 ret = ici->ops->set_crop(icd, a);
915 } else if (ici->ops->set_livecrop) {
916 ret = ici->ops->set_livecrop(icd, a);
917 } else {
909 dev_err(&icd->dev, 918 dev_err(&icd->dev,
910 "S_CROP denied: queue initialised and sizes differ\n"); 919 "S_CROP denied: queue initialised and sizes differ\n");
911 ret = -EBUSY; 920 ret = -EBUSY;
912 } else {
913 ret = ici->ops->set_crop(icd, a);
914 } 921 }
915 922
916 return ret; 923 return ret;
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index ed77aa055b63..bea7c9cf4f88 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -15,132 +15,329 @@
15#include <media/v4l2-mediabus.h> 15#include <media/v4l2-mediabus.h>
16#include <media/soc_mediabus.h> 16#include <media/soc_mediabus.h>
17 17
18#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1) 18static const struct soc_mbus_lookup mbus_fmt[] = {
19 19{
20static const struct soc_mbus_pixelfmt mbus_fmt[] = { 20 .code = V4L2_MBUS_FMT_YUYV8_2X8,
21 [MBUS_IDX(YUYV8_2X8)] = { 21 .fmt = {
22 .fourcc = V4L2_PIX_FMT_YUYV, 22 .fourcc = V4L2_PIX_FMT_YUYV,
23 .name = "YUYV", 23 .name = "YUYV",
24 .bits_per_sample = 8, 24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI, 25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE, 26 .order = SOC_MBUS_ORDER_LE,
27 }, 27 },
28 [MBUS_IDX(YVYU8_2X8)] = { 28}, {
29 .code = V4L2_MBUS_FMT_YVYU8_2X8,
30 .fmt = {
29 .fourcc = V4L2_PIX_FMT_YVYU, 31 .fourcc = V4L2_PIX_FMT_YVYU,
30 .name = "YVYU", 32 .name = "YVYU",
31 .bits_per_sample = 8, 33 .bits_per_sample = 8,
32 .packing = SOC_MBUS_PACKING_2X8_PADHI, 34 .packing = SOC_MBUS_PACKING_2X8_PADHI,
33 .order = SOC_MBUS_ORDER_LE, 35 .order = SOC_MBUS_ORDER_LE,
34 }, 36 },
35 [MBUS_IDX(UYVY8_2X8)] = { 37}, {
38 .code = V4L2_MBUS_FMT_UYVY8_2X8,
39 .fmt = {
36 .fourcc = V4L2_PIX_FMT_UYVY, 40 .fourcc = V4L2_PIX_FMT_UYVY,
37 .name = "UYVY", 41 .name = "UYVY",
38 .bits_per_sample = 8, 42 .bits_per_sample = 8,
39 .packing = SOC_MBUS_PACKING_2X8_PADHI, 43 .packing = SOC_MBUS_PACKING_2X8_PADHI,
40 .order = SOC_MBUS_ORDER_LE, 44 .order = SOC_MBUS_ORDER_LE,
41 }, 45 },
42 [MBUS_IDX(VYUY8_2X8)] = { 46}, {
47 .code = V4L2_MBUS_FMT_VYUY8_2X8,
48 .fmt = {
43 .fourcc = V4L2_PIX_FMT_VYUY, 49 .fourcc = V4L2_PIX_FMT_VYUY,
44 .name = "VYUY", 50 .name = "VYUY",
45 .bits_per_sample = 8, 51 .bits_per_sample = 8,
46 .packing = SOC_MBUS_PACKING_2X8_PADHI, 52 .packing = SOC_MBUS_PACKING_2X8_PADHI,
47 .order = SOC_MBUS_ORDER_LE, 53 .order = SOC_MBUS_ORDER_LE,
48 }, 54 },
49 [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { 55}, {
56 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
57 .fmt = {
50 .fourcc = V4L2_PIX_FMT_RGB555, 58 .fourcc = V4L2_PIX_FMT_RGB555,
51 .name = "RGB555", 59 .name = "RGB555",
52 .bits_per_sample = 8, 60 .bits_per_sample = 8,
53 .packing = SOC_MBUS_PACKING_2X8_PADHI, 61 .packing = SOC_MBUS_PACKING_2X8_PADHI,
54 .order = SOC_MBUS_ORDER_LE, 62 .order = SOC_MBUS_ORDER_LE,
55 }, 63 },
56 [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { 64}, {
65 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
66 .fmt = {
57 .fourcc = V4L2_PIX_FMT_RGB555X, 67 .fourcc = V4L2_PIX_FMT_RGB555X,
58 .name = "RGB555X", 68 .name = "RGB555X",
59 .bits_per_sample = 8, 69 .bits_per_sample = 8,
60 .packing = SOC_MBUS_PACKING_2X8_PADHI, 70 .packing = SOC_MBUS_PACKING_2X8_PADHI,
61 .order = SOC_MBUS_ORDER_LE, 71 .order = SOC_MBUS_ORDER_LE,
62 }, 72 },
63 [MBUS_IDX(RGB565_2X8_LE)] = { 73}, {
74 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
75 .fmt = {
64 .fourcc = V4L2_PIX_FMT_RGB565, 76 .fourcc = V4L2_PIX_FMT_RGB565,
65 .name = "RGB565", 77 .name = "RGB565",
66 .bits_per_sample = 8, 78 .bits_per_sample = 8,
67 .packing = SOC_MBUS_PACKING_2X8_PADHI, 79 .packing = SOC_MBUS_PACKING_2X8_PADHI,
68 .order = SOC_MBUS_ORDER_LE, 80 .order = SOC_MBUS_ORDER_LE,
69 }, 81 },
70 [MBUS_IDX(RGB565_2X8_BE)] = { 82}, {
83 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
84 .fmt = {
71 .fourcc = V4L2_PIX_FMT_RGB565X, 85 .fourcc = V4L2_PIX_FMT_RGB565X,
72 .name = "RGB565X", 86 .name = "RGB565X",
73 .bits_per_sample = 8, 87 .bits_per_sample = 8,
74 .packing = SOC_MBUS_PACKING_2X8_PADHI, 88 .packing = SOC_MBUS_PACKING_2X8_PADHI,
75 .order = SOC_MBUS_ORDER_LE, 89 .order = SOC_MBUS_ORDER_LE,
76 }, 90 },
77 [MBUS_IDX(SBGGR8_1X8)] = { 91}, {
92 .code = V4L2_MBUS_FMT_SBGGR8_1X8,
93 .fmt = {
78 .fourcc = V4L2_PIX_FMT_SBGGR8, 94 .fourcc = V4L2_PIX_FMT_SBGGR8,
79 .name = "Bayer 8 BGGR", 95 .name = "Bayer 8 BGGR",
80 .bits_per_sample = 8, 96 .bits_per_sample = 8,
81 .packing = SOC_MBUS_PACKING_NONE, 97 .packing = SOC_MBUS_PACKING_NONE,
82 .order = SOC_MBUS_ORDER_LE, 98 .order = SOC_MBUS_ORDER_LE,
83 }, 99 },
84 [MBUS_IDX(SBGGR10_1X10)] = { 100}, {
101 .code = V4L2_MBUS_FMT_SBGGR10_1X10,
102 .fmt = {
85 .fourcc = V4L2_PIX_FMT_SBGGR10, 103 .fourcc = V4L2_PIX_FMT_SBGGR10,
86 .name = "Bayer 10 BGGR", 104 .name = "Bayer 10 BGGR",
87 .bits_per_sample = 10, 105 .bits_per_sample = 10,
88 .packing = SOC_MBUS_PACKING_EXTEND16, 106 .packing = SOC_MBUS_PACKING_EXTEND16,
89 .order = SOC_MBUS_ORDER_LE, 107 .order = SOC_MBUS_ORDER_LE,
90 }, 108 },
91 [MBUS_IDX(Y8_1X8)] = { 109}, {
110 .code = V4L2_MBUS_FMT_Y8_1X8,
111 .fmt = {
92 .fourcc = V4L2_PIX_FMT_GREY, 112 .fourcc = V4L2_PIX_FMT_GREY,
93 .name = "Grey", 113 .name = "Grey",
94 .bits_per_sample = 8, 114 .bits_per_sample = 8,
95 .packing = SOC_MBUS_PACKING_NONE, 115 .packing = SOC_MBUS_PACKING_NONE,
96 .order = SOC_MBUS_ORDER_LE, 116 .order = SOC_MBUS_ORDER_LE,
97 }, 117 },
98 [MBUS_IDX(Y10_1X10)] = { 118}, {
119 .code = V4L2_MBUS_FMT_Y10_1X10,
120 .fmt = {
99 .fourcc = V4L2_PIX_FMT_Y10, 121 .fourcc = V4L2_PIX_FMT_Y10,
100 .name = "Grey 10bit", 122 .name = "Grey 10bit",
101 .bits_per_sample = 10, 123 .bits_per_sample = 10,
102 .packing = SOC_MBUS_PACKING_EXTEND16, 124 .packing = SOC_MBUS_PACKING_EXTEND16,
103 .order = SOC_MBUS_ORDER_LE, 125 .order = SOC_MBUS_ORDER_LE,
104 }, 126 },
105 [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { 127}, {
128 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
129 .fmt = {
106 .fourcc = V4L2_PIX_FMT_SBGGR10, 130 .fourcc = V4L2_PIX_FMT_SBGGR10,
107 .name = "Bayer 10 BGGR", 131 .name = "Bayer 10 BGGR",
108 .bits_per_sample = 8, 132 .bits_per_sample = 8,
109 .packing = SOC_MBUS_PACKING_2X8_PADHI, 133 .packing = SOC_MBUS_PACKING_2X8_PADHI,
110 .order = SOC_MBUS_ORDER_LE, 134 .order = SOC_MBUS_ORDER_LE,
111 }, 135 },
112 [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { 136}, {
137 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
138 .fmt = {
113 .fourcc = V4L2_PIX_FMT_SBGGR10, 139 .fourcc = V4L2_PIX_FMT_SBGGR10,
114 .name = "Bayer 10 BGGR", 140 .name = "Bayer 10 BGGR",
115 .bits_per_sample = 8, 141 .bits_per_sample = 8,
116 .packing = SOC_MBUS_PACKING_2X8_PADLO, 142 .packing = SOC_MBUS_PACKING_2X8_PADLO,
117 .order = SOC_MBUS_ORDER_LE, 143 .order = SOC_MBUS_ORDER_LE,
118 }, 144 },
119 [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { 145}, {
146 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
147 .fmt = {
120 .fourcc = V4L2_PIX_FMT_SBGGR10, 148 .fourcc = V4L2_PIX_FMT_SBGGR10,
121 .name = "Bayer 10 BGGR", 149 .name = "Bayer 10 BGGR",
122 .bits_per_sample = 8, 150 .bits_per_sample = 8,
123 .packing = SOC_MBUS_PACKING_2X8_PADHI, 151 .packing = SOC_MBUS_PACKING_2X8_PADHI,
124 .order = SOC_MBUS_ORDER_BE, 152 .order = SOC_MBUS_ORDER_BE,
125 }, 153 },
126 [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { 154}, {
155 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
156 .fmt = {
127 .fourcc = V4L2_PIX_FMT_SBGGR10, 157 .fourcc = V4L2_PIX_FMT_SBGGR10,
128 .name = "Bayer 10 BGGR", 158 .name = "Bayer 10 BGGR",
129 .bits_per_sample = 8, 159 .bits_per_sample = 8,
130 .packing = SOC_MBUS_PACKING_2X8_PADLO, 160 .packing = SOC_MBUS_PACKING_2X8_PADLO,
131 .order = SOC_MBUS_ORDER_BE, 161 .order = SOC_MBUS_ORDER_BE,
132 }, 162 },
163}, {
164 .code = V4L2_MBUS_FMT_JPEG_1X8,
165 .fmt = {
166 .fourcc = V4L2_PIX_FMT_JPEG,
167 .name = "JPEG",
168 .bits_per_sample = 8,
169 .packing = SOC_MBUS_PACKING_VARIABLE,
170 .order = SOC_MBUS_ORDER_LE,
171 },
172}, {
173 .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
174 .fmt = {
175 .fourcc = V4L2_PIX_FMT_RGB444,
176 .name = "RGB444",
177 .bits_per_sample = 8,
178 .packing = SOC_MBUS_PACKING_2X8_PADHI,
179 .order = SOC_MBUS_ORDER_BE,
180 },
181}, {
182 .code = V4L2_MBUS_FMT_YUYV8_1_5X8,
183 .fmt = {
184 .fourcc = V4L2_PIX_FMT_YUV420,
185 .name = "YUYV 4:2:0",
186 .bits_per_sample = 8,
187 .packing = SOC_MBUS_PACKING_1_5X8,
188 .order = SOC_MBUS_ORDER_LE,
189 },
190}, {
191 .code = V4L2_MBUS_FMT_YVYU8_1_5X8,
192 .fmt = {
193 .fourcc = V4L2_PIX_FMT_YVU420,
194 .name = "YVYU 4:2:0",
195 .bits_per_sample = 8,
196 .packing = SOC_MBUS_PACKING_1_5X8,
197 .order = SOC_MBUS_ORDER_LE,
198 },
199}, {
200 .code = V4L2_MBUS_FMT_UYVY8_1X16,
201 .fmt = {
202 .fourcc = V4L2_PIX_FMT_UYVY,
203 .name = "UYVY 16bit",
204 .bits_per_sample = 16,
205 .packing = SOC_MBUS_PACKING_EXTEND16,
206 .order = SOC_MBUS_ORDER_LE,
207 },
208}, {
209 .code = V4L2_MBUS_FMT_VYUY8_1X16,
210 .fmt = {
211 .fourcc = V4L2_PIX_FMT_VYUY,
212 .name = "VYUY 16bit",
213 .bits_per_sample = 16,
214 .packing = SOC_MBUS_PACKING_EXTEND16,
215 .order = SOC_MBUS_ORDER_LE,
216 },
217}, {
218 .code = V4L2_MBUS_FMT_YUYV8_1X16,
219 .fmt = {
220 .fourcc = V4L2_PIX_FMT_YUYV,
221 .name = "YUYV 16bit",
222 .bits_per_sample = 16,
223 .packing = SOC_MBUS_PACKING_EXTEND16,
224 .order = SOC_MBUS_ORDER_LE,
225 },
226}, {
227 .code = V4L2_MBUS_FMT_YVYU8_1X16,
228 .fmt = {
229 .fourcc = V4L2_PIX_FMT_YVYU,
230 .name = "YVYU 16bit",
231 .bits_per_sample = 16,
232 .packing = SOC_MBUS_PACKING_EXTEND16,
233 .order = SOC_MBUS_ORDER_LE,
234 },
235}, {
236 .code = V4L2_MBUS_FMT_SGRBG8_1X8,
237 .fmt = {
238 .fourcc = V4L2_PIX_FMT_SGRBG8,
239 .name = "Bayer 8 GRBG",
240 .bits_per_sample = 8,
241 .packing = SOC_MBUS_PACKING_NONE,
242 .order = SOC_MBUS_ORDER_LE,
243 },
244}, {
245 .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
246 .fmt = {
247 .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8,
248 .name = "Bayer 10 BGGR DPCM 8",
249 .bits_per_sample = 8,
250 .packing = SOC_MBUS_PACKING_NONE,
251 .order = SOC_MBUS_ORDER_LE,
252 },
253}, {
254 .code = V4L2_MBUS_FMT_SGBRG10_1X10,
255 .fmt = {
256 .fourcc = V4L2_PIX_FMT_SGBRG10,
257 .name = "Bayer 10 GBRG",
258 .bits_per_sample = 10,
259 .packing = SOC_MBUS_PACKING_EXTEND16,
260 .order = SOC_MBUS_ORDER_LE,
261 },
262}, {
263 .code = V4L2_MBUS_FMT_SGRBG10_1X10,
264 .fmt = {
265 .fourcc = V4L2_PIX_FMT_SGRBG10,
266 .name = "Bayer 10 GRBG",
267 .bits_per_sample = 10,
268 .packing = SOC_MBUS_PACKING_EXTEND16,
269 .order = SOC_MBUS_ORDER_LE,
270 },
271}, {
272 .code = V4L2_MBUS_FMT_SRGGB10_1X10,
273 .fmt = {
274 .fourcc = V4L2_PIX_FMT_SRGGB10,
275 .name = "Bayer 10 RGGB",
276 .bits_per_sample = 10,
277 .packing = SOC_MBUS_PACKING_EXTEND16,
278 .order = SOC_MBUS_ORDER_LE,
279 },
280}, {
281 .code = V4L2_MBUS_FMT_SBGGR12_1X12,
282 .fmt = {
283 .fourcc = V4L2_PIX_FMT_SBGGR12,
284 .name = "Bayer 12 BGGR",
285 .bits_per_sample = 12,
286 .packing = SOC_MBUS_PACKING_EXTEND16,
287 .order = SOC_MBUS_ORDER_LE,
288 },
289}, {
290 .code = V4L2_MBUS_FMT_SGBRG12_1X12,
291 .fmt = {
292 .fourcc = V4L2_PIX_FMT_SGBRG12,
293 .name = "Bayer 12 GBRG",
294 .bits_per_sample = 12,
295 .packing = SOC_MBUS_PACKING_EXTEND16,
296 .order = SOC_MBUS_ORDER_LE,
297 },
298}, {
299 .code = V4L2_MBUS_FMT_SGRBG12_1X12,
300 .fmt = {
301 .fourcc = V4L2_PIX_FMT_SGRBG12,
302 .name = "Bayer 12 GRBG",
303 .bits_per_sample = 12,
304 .packing = SOC_MBUS_PACKING_EXTEND16,
305 .order = SOC_MBUS_ORDER_LE,
306 },
307}, {
308 .code = V4L2_MBUS_FMT_SRGGB12_1X12,
309 .fmt = {
310 .fourcc = V4L2_PIX_FMT_SRGGB12,
311 .name = "Bayer 12 RGGB",
312 .bits_per_sample = 12,
313 .packing = SOC_MBUS_PACKING_EXTEND16,
314 .order = SOC_MBUS_ORDER_LE,
315 },
316},
133}; 317};
134 318
135int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf) 319int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
320 unsigned int *numerator, unsigned int *denominator)
136{ 321{
137 switch (mf->packing) { 322 switch (mf->packing) {
138 case SOC_MBUS_PACKING_NONE: 323 case SOC_MBUS_PACKING_NONE:
139 case SOC_MBUS_PACKING_EXTEND16: 324 case SOC_MBUS_PACKING_EXTEND16:
140 return 1; 325 *numerator = 1;
326 *denominator = 1;
327 return 0;
141 case SOC_MBUS_PACKING_2X8_PADHI: 328 case SOC_MBUS_PACKING_2X8_PADHI:
142 case SOC_MBUS_PACKING_2X8_PADLO: 329 case SOC_MBUS_PACKING_2X8_PADLO:
143 return 2; 330 *numerator = 2;
331 *denominator = 1;
332 return 0;
333 case SOC_MBUS_PACKING_1_5X8:
334 *numerator = 3;
335 *denominator = 2;
336 return 0;
337 case SOC_MBUS_PACKING_VARIABLE:
338 *numerator = 0;
339 *denominator = 1;
340 return 0;
144 } 341 }
145 return -EINVAL; 342 return -EINVAL;
146} 343}
@@ -155,18 +352,34 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
155 case SOC_MBUS_PACKING_2X8_PADLO: 352 case SOC_MBUS_PACKING_2X8_PADLO:
156 case SOC_MBUS_PACKING_EXTEND16: 353 case SOC_MBUS_PACKING_EXTEND16:
157 return width * 2; 354 return width * 2;
355 case SOC_MBUS_PACKING_1_5X8:
356 return width * 3 / 2;
357 case SOC_MBUS_PACKING_VARIABLE:
358 return 0;
158 } 359 }
159 return -EINVAL; 360 return -EINVAL;
160} 361}
161EXPORT_SYMBOL(soc_mbus_bytes_per_line); 362EXPORT_SYMBOL(soc_mbus_bytes_per_line);
162 363
364const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
365 enum v4l2_mbus_pixelcode code,
366 const struct soc_mbus_lookup *lookup,
367 int n)
368{
369 int i;
370
371 for (i = 0; i < n; i++)
372 if (lookup[i].code == code)
373 return &lookup[i].fmt;
374
375 return NULL;
376}
377EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
378
163const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 379const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
164 enum v4l2_mbus_pixelcode code) 380 enum v4l2_mbus_pixelcode code)
165{ 381{
166 if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) || 382 return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
167 code <= V4L2_MBUS_FMT_FIXED)
168 return NULL;
169 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
170} 383}
171EXPORT_SYMBOL(soc_mbus_get_fmtdesc); 384EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
172 385
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 07fabdd9b465..6103d1b1081e 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -267,21 +267,27 @@ hauppauge_tuner[] =
267 { TUNER_ABSENT, "Xceive XC4000"}, 267 { TUNER_ABSENT, "Xceive XC4000"},
268 { TUNER_ABSENT, "Dibcom 7070"}, 268 { TUNER_ABSENT, "Dibcom 7070"},
269 { TUNER_PHILIPS_TDA8290, "NXP 18271C2"}, 269 { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
270 { TUNER_ABSENT, "unknown"}, 270 { TUNER_ABSENT, "Siano SMS1010"},
271 { TUNER_ABSENT, "unknown"}, 271 { TUNER_ABSENT, "Siano SMS1150"},
272 { TUNER_ABSENT, "unknown"}, 272 { TUNER_ABSENT, "MaxLinear 5007"},
273 { TUNER_ABSENT, "unknown"}, 273 { TUNER_ABSENT, "TCL M09WPP_2P_E"},
274 /* 160-169 */ 274 /* 160-169 */
275 { TUNER_ABSENT, "unknown"}, 275 { TUNER_ABSENT, "Siano SMS1180"},
276 { TUNER_ABSENT, "unknown"}, 276 { TUNER_ABSENT, "Maxim_MAX2165"},
277 { TUNER_ABSENT, "unknown"}, 277 { TUNER_ABSENT, "Siano SMS1140"},
278 { TUNER_ABSENT, "unknown"}, 278 { TUNER_ABSENT, "Siano SMS1150 B1"},
279 { TUNER_ABSENT, "unknown"}, 279 { TUNER_ABSENT, "MaxLinear 111"},
280 { TUNER_ABSENT, "unknown"}, 280 { TUNER_ABSENT, "Dibcom 7770"},
281 { TUNER_ABSENT, "unknown"}, 281 { TUNER_ABSENT, "Siano SMS1180VNS"},
282 { TUNER_ABSENT, "unknown"}, 282 { TUNER_ABSENT, "Siano SMS1184"},
283 { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"}, 283 { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"},
284 { TUNER_ABSENT, "unknown"}, 284 { TUNER_ABSENT, "TCL_M11WPP_2PN_E"},
285 /* 170-179 */
286 { TUNER_ABSENT, "MaxLinear 301"},
287 { TUNER_ABSENT, "Mirics MSi001"},
288 { TUNER_ABSENT, "MaxLinear MxL241SF"},
289 { TUNER_ABSENT, "Xceive XC5000C"},
290 { TUNER_ABSENT, "Montage M68TS2020"},
285}; 291};
286 292
287/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are 293/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
index 68b998bd203f..8f5266157f15 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/video/usbvision/usbvision-cards.c
@@ -1025,6 +1025,34 @@ struct usbvision_device_data_st usbvision_device_data[] = {
1025 .y_offset = -1, 1025 .y_offset = -1,
1026 .model_string = "Hauppauge WinTv-USB", 1026 .model_string = "Hauppauge WinTv-USB",
1027 }, 1027 },
1028 [MICROCAM_NTSC] = {
1029 .interface = -1,
1030 .codec = CODEC_WEBCAM,
1031 .video_channels = 1,
1032 .video_norm = V4L2_STD_NTSC,
1033 .audio_channels = 0,
1034 .radio = 0,
1035 .vbi = 0,
1036 .tuner = 0,
1037 .tuner_type = 0,
1038 .x_offset = 71,
1039 .y_offset = 15,
1040 .model_string = "Nogatech USB MicroCam NTSC (NV3000N)",
1041 },
1042 [MICROCAM_PAL] = {
1043 .interface = -1,
1044 .codec = CODEC_WEBCAM,
1045 .video_channels = 1,
1046 .video_norm = V4L2_STD_PAL,
1047 .audio_channels = 0,
1048 .radio = 0,
1049 .vbi = 0,
1050 .tuner = 0,
1051 .tuner_type = 0,
1052 .x_offset = 71,
1053 .y_offset = 18,
1054 .model_string = "Nogatech USB MicroCam PAL (NV3001P)",
1055 },
1028}; 1056};
1029const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data); 1057const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data);
1030 1058
@@ -1042,6 +1070,8 @@ struct usb_device_id usbvision_table[] = {
1042 { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG }, 1070 { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG },
1043 { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN }, 1071 { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN },
1044 { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH }, 1072 { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH },
1073 { USB_DEVICE(0x0573, 0x3000), .driver_info = MICROCAM_NTSC },
1074 { USB_DEVICE(0x0573, 0x3001), .driver_info = MICROCAM_PAL },
1045 { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM }, 1075 { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM },
1046 { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM }, 1076 { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM },
1047 { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM }, 1077 { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM },
@@ -1088,8 +1118,7 @@ struct usb_device_id usbvision_table[] = {
1088 { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM }, 1118 { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM },
1089 { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB }, 1119 { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB },
1090 { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM }, 1120 { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM },
1091 { USB_DEVICE(0x2304, 0x0113), 1121 { USB_DEVICE(0x2304, 0x0113), .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
1092 .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
1093 { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 }, 1122 { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 },
1094 { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 }, 1123 { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 },
1095 { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 }, 1124 { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 },
diff --git a/drivers/media/video/usbvision/usbvision-cards.h b/drivers/media/video/usbvision/usbvision-cards.h
index 9c6ad22960d8..a51cc1185cce 100644
--- a/drivers/media/video/usbvision/usbvision-cards.h
+++ b/drivers/media/video/usbvision/usbvision-cards.h
@@ -63,5 +63,7 @@
63#define PINNA_PCTV_BUNGEE_PAL_FM 62 63#define PINNA_PCTV_BUNGEE_PAL_FM 62
64#define HPG_WINTV 63 64#define HPG_WINTV 63
65#define PINNA_PCTV_USB_NTSC_FM_V3 64 65#define PINNA_PCTV_USB_NTSC_FM_V3 64
66#define MICROCAM_NTSC 65
67#define MICROCAM_PAL 66
66 68
67extern const int usbvision_device_data_size; 69extern const int usbvision_device_data_size;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index c8feb0d6fccf..f344411a4578 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -49,10 +49,6 @@ static unsigned int core_debug;
49module_param(core_debug, int, 0644); 49module_param(core_debug, int, 0644);
50MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); 50MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
51 51
52static unsigned int force_testpattern;
53module_param(force_testpattern, int, 0644);
54MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]");
55
56static int adjust_compression = 1; /* Set the compression to be adaptive */ 52static int adjust_compression = 1; /* Set the compression to be adaptive */
57module_param(adjust_compression, int, 0444); 53module_param(adjust_compression, int, 0444);
58MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)"); 54MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device. Default: 1 (On)");
@@ -388,90 +384,6 @@ void usbvision_scratch_free(struct usb_usbvision *usbvision)
388} 384}
389 385
390/* 386/*
391 * usbvision_testpattern()
392 *
393 * Procedure forms a test pattern (yellow grid on blue background).
394 *
395 * Parameters:
396 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
397 * continues from the current scanline.
398 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
399 * 1: Draw a colored grid
400 *
401 */
402static void usbvision_testpattern(struct usb_usbvision *usbvision,
403 int fullframe, int pmode)
404{
405 static const char proc[] = "usbvision_testpattern";
406 struct usbvision_frame *frame;
407 unsigned char *f;
408 int num_cell = 0;
409 int scan_length = 0;
410 static int num_pass;
411
412 if (usbvision == NULL) {
413 printk(KERN_ERR "%s: usbvision == NULL\n", proc);
414 return;
415 }
416 if (usbvision->cur_frame == NULL) {
417 printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc);
418 return;
419 }
420
421 /* Grab the current frame */
422 frame = usbvision->cur_frame;
423
424 /* Optionally start at the beginning */
425 if (fullframe) {
426 frame->curline = 0;
427 frame->scanlength = 0;
428 }
429
430 /* Form every scan line */
431 for (; frame->curline < frame->frmheight; frame->curline++) {
432 int i;
433
434 f = frame->data + (usbvision->curwidth * 3 * frame->curline);
435 for (i = 0; i < usbvision->curwidth; i++) {
436 unsigned char cb = 0x80;
437 unsigned char cg = 0;
438 unsigned char cr = 0;
439
440 if (pmode == 1) {
441 if (frame->curline % 32 == 0)
442 cb = 0, cg = cr = 0xFF;
443 else if (i % 32 == 0) {
444 if (frame->curline % 32 == 1)
445 num_cell++;
446 cb = 0, cg = cr = 0xFF;
447 } else {
448 cb =
449 ((num_cell * 7) +
450 num_pass) & 0xFF;
451 cg =
452 ((num_cell * 5) +
453 num_pass * 2) & 0xFF;
454 cr =
455 ((num_cell * 3) +
456 num_pass * 3) & 0xFF;
457 }
458 } else {
459 /* Just the blue screen */
460 }
461
462 *f++ = cb;
463 *f++ = cg;
464 *f++ = cr;
465 scan_length += 3;
466 }
467 }
468
469 frame->grabstate = frame_state_done;
470 frame->scanlength += scan_length;
471 ++num_pass;
472}
473
474/*
475 * usbvision_decompress_alloc() 387 * usbvision_decompress_alloc()
476 * 388 *
477 * allocates intermediate buffer for decompression 389 * allocates intermediate buffer for decompression
@@ -571,10 +483,6 @@ static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision)
571 frame->scanstate = scan_state_lines; 483 frame->scanstate = scan_state_lines;
572 frame->curline = 0; 484 frame->curline = 0;
573 485
574 if (force_testpattern) {
575 usbvision_testpattern(usbvision, 1, 1);
576 return parse_state_next_frame;
577 }
578 return parse_state_continue; 486 return parse_state_continue;
579} 487}
580 488
@@ -1679,6 +1587,55 @@ int usbvision_power_off(struct usb_usbvision *usbvision)
1679 return err_code; 1587 return err_code;
1680} 1588}
1681 1589
1590/* configure webcam image sensor using the serial port */
1591static int usbvision_init_webcam(struct usb_usbvision *usbvision)
1592{
1593 int rc;
1594 int i;
1595 static char init_values[38][3] = {
1596 { 0x04, 0x12, 0x08 }, { 0x05, 0xff, 0xc8 }, { 0x06, 0x18, 0x07 }, { 0x07, 0x90, 0x00 },
1597 { 0x09, 0x00, 0x00 }, { 0x0a, 0x00, 0x00 }, { 0x0b, 0x08, 0x00 }, { 0x0d, 0xcc, 0xcc },
1598 { 0x0e, 0x13, 0x14 }, { 0x10, 0x9b, 0x83 }, { 0x11, 0x5a, 0x3f }, { 0x12, 0xe4, 0x73 },
1599 { 0x13, 0x88, 0x84 }, { 0x14, 0x89, 0x80 }, { 0x15, 0x00, 0x20 }, { 0x16, 0x00, 0x00 },
1600 { 0x17, 0xff, 0xa0 }, { 0x18, 0x6b, 0x20 }, { 0x19, 0x22, 0x40 }, { 0x1a, 0x10, 0x07 },
1601 { 0x1b, 0x00, 0x47 }, { 0x1c, 0x03, 0xe0 }, { 0x1d, 0x00, 0x00 }, { 0x1e, 0x00, 0x00 },
1602 { 0x1f, 0x00, 0x00 }, { 0x20, 0x00, 0x00 }, { 0x21, 0x00, 0x00 }, { 0x22, 0x00, 0x00 },
1603 { 0x23, 0x00, 0x00 }, { 0x24, 0x00, 0x00 }, { 0x25, 0x00, 0x00 }, { 0x26, 0x00, 0x00 },
1604 { 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
1605 { 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
1606 };
1607 char value[3];
1608
1609 /* the only difference between PAL and NTSC init_values */
1610 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
1611 init_values[4][1] = 0x34;
1612
1613 for (i = 0; i < sizeof(init_values) / 3; i++) {
1614 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1615 memcpy(value, init_values[i], 3);
1616 rc = usb_control_msg(usbvision->dev,
1617 usb_sndctrlpipe(usbvision->dev, 1),
1618 USBVISION_OP_CODE,
1619 USB_DIR_OUT | USB_TYPE_VENDOR |
1620 USB_RECIP_ENDPOINT, 0,
1621 (__u16) USBVISION_SER_DAT1, value,
1622 3, HZ);
1623 if (rc < 0)
1624 return rc;
1625 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SIO);
1626 /* write 3 bytes to the serial port using SIO mode */
1627 usbvision_write_reg(usbvision, USBVISION_SER_CONT, 3 | 0x10);
1628 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, 0);
1629 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1630 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_IO_2);
1631 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT);
1632 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_DAT_IO);
1633 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT | USBVISION_DAT_IO);
1634 }
1635
1636 return 0;
1637}
1638
1682/* 1639/*
1683 * usbvision_set_video_format() 1640 * usbvision_set_video_format()
1684 * 1641 *
@@ -1797,6 +1754,13 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
1797 1754
1798 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */ 1755 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */
1799 1756
1757 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
1758 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_PAL)
1759 frame_drop = 25;
1760 else
1761 frame_drop = 30;
1762 }
1763
1800 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ... 1764 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
1801 => frame_skip = 4; 1765 => frame_skip = 4;
1802 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25; 1766 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
@@ -2046,6 +2010,12 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
2046 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */ 2010 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */
2047 } 2011 }
2048 2012
2013 /* webcam is only 480 pixels wide, both PAL and NTSC version */
2014 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2015 value[0] = 0xe0;
2016 value[1] = 0x01; /* 0x01E0 -> 480 Input video line length */
2017 }
2018
2049 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) { 2019 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
2050 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff; 2020 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
2051 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8; 2021 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
@@ -2148,7 +2118,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
2148 (__u16) USBVISION_DRM_PRM1, value, 8, HZ); 2118 (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
2149 2119
2150 if (rc < 0) { 2120 if (rc < 0) {
2151 dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc); 2121 dev_err(&usbvision->dev->dev, "%s: ERROR=%d\n", __func__, rc);
2152 return rc; 2122 return rc;
2153 } 2123 }
2154 2124
@@ -2180,8 +2150,15 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
2180 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2150 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2181 USBVISION_SSPND_EN | USBVISION_RES2); 2151 USBVISION_SSPND_EN | USBVISION_RES2);
2182 2152
2153 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2154 usbvision_write_reg(usbvision, USBVISION_VIN_REG1,
2155 USBVISION_16_422_SYNC | USBVISION_HVALID_PO);
2156 usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
2157 USBVISION_NOHVALID | USBVISION_KEEP_BLANK);
2158 }
2183 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2159 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2184 USBVISION_SSPND_EN | USBVISION_PWR_VID); 2160 USBVISION_SSPND_EN | USBVISION_PWR_VID);
2161 mdelay(10);
2185 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2162 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2186 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2); 2163 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
2187 if (err_code == 1) 2164 if (err_code == 1)
@@ -2310,6 +2287,8 @@ int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
2310 2287
2311int usbvision_setup(struct usb_usbvision *usbvision, int format) 2288int usbvision_setup(struct usb_usbvision *usbvision, int format)
2312{ 2289{
2290 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM)
2291 usbvision_init_webcam(usbvision);
2313 usbvision_set_video_format(usbvision, format); 2292 usbvision_set_video_format(usbvision, format);
2314 usbvision_set_dram_settings(usbvision); 2293 usbvision_set_dram_settings(usbvision);
2315 usbvision_set_compress_params(usbvision); 2294 usbvision_set_compress_params(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 05b1344181cd..d7f97513b289 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -222,7 +222,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
222 i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); 222 i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
223 223
224 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { 224 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
225 printk(KERN_ERR "usbvision_register: can't write reg\n"); 225 printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
226 return -EBUSY; 226 return -EBUSY;
227 } 227 }
228 228
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 9855fbe5927a..ea8ea8a48dfe 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1471,7 +1471,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
1471 1471
1472 /* This should be here to make i2c clients to be able to register */ 1472 /* This should be here to make i2c clients to be able to register */
1473 /* first switch off audio */ 1473 /* first switch off audio */
1474 usbvision_audio_off(usbvision); 1474 if (usbvision_device_data[model].audio_channels > 0)
1475 usbvision_audio_off(usbvision);
1475 if (!power_on_at_open) { 1476 if (!power_on_at_open) {
1476 /* and then power up the noisy tuner */ 1477 /* and then power up the noisy tuner */
1477 usbvision_power_on(usbvision); 1478 usbvision_power_on(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index 8074787fd1ac..43cf61fe4943 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -59,6 +59,11 @@
59 #define USBVISION_AUDIO_RADIO 2 59 #define USBVISION_AUDIO_RADIO 2
60 #define USBVISION_AUDIO_MUTE 3 60 #define USBVISION_AUDIO_MUTE 3
61#define USBVISION_SER_MODE 0x07 61#define USBVISION_SER_MODE 0x07
62 #define USBVISION_CLK_OUT (1 << 0)
63 #define USBVISION_DAT_IO (1 << 1)
64 #define USBVISION_SENS_OUT (1 << 2)
65 #define USBVISION_SER_MODE_SOFT (0 << 4)
66 #define USBVISION_SER_MODE_SIO (1 << 4)
62#define USBVISION_SER_ADRS 0x08 67#define USBVISION_SER_ADRS 0x08
63#define USBVISION_SER_CONT 0x09 68#define USBVISION_SER_CONT 0x09
64#define USBVISION_SER_DAT1 0x0A 69#define USBVISION_SER_DAT1 0x0A
@@ -328,6 +333,7 @@ struct usbvision_frame {
328 333
329#define CODEC_SAA7113 7113 334#define CODEC_SAA7113 7113
330#define CODEC_SAA7111 7111 335#define CODEC_SAA7111 7111
336#define CODEC_WEBCAM 3000
331#define BRIDGE_NT1003 1003 337#define BRIDGE_NT1003 1003
332#define BRIDGE_NT1004 1004 338#define BRIDGE_NT1004 1004
333#define BRIDGE_NT1005 1005 339#define BRIDGE_NT1005 1005
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 59f8a9ad3796..a4db26fa2f53 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -42,281 +42,313 @@ static struct uvc_control_info uvc_ctrls[] = {
42 .selector = UVC_PU_BRIGHTNESS_CONTROL, 42 .selector = UVC_PU_BRIGHTNESS_CONTROL,
43 .index = 0, 43 .index = 0,
44 .size = 2, 44 .size = 2,
45 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 45 .flags = UVC_CTRL_FLAG_SET_CUR
46 | UVC_CONTROL_RESTORE, 46 | UVC_CTRL_FLAG_GET_RANGE
47 | UVC_CTRL_FLAG_RESTORE,
47 }, 48 },
48 { 49 {
49 .entity = UVC_GUID_UVC_PROCESSING, 50 .entity = UVC_GUID_UVC_PROCESSING,
50 .selector = UVC_PU_CONTRAST_CONTROL, 51 .selector = UVC_PU_CONTRAST_CONTROL,
51 .index = 1, 52 .index = 1,
52 .size = 2, 53 .size = 2,
53 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 54 .flags = UVC_CTRL_FLAG_SET_CUR
54 | UVC_CONTROL_RESTORE, 55 | UVC_CTRL_FLAG_GET_RANGE
56 | UVC_CTRL_FLAG_RESTORE,
55 }, 57 },
56 { 58 {
57 .entity = UVC_GUID_UVC_PROCESSING, 59 .entity = UVC_GUID_UVC_PROCESSING,
58 .selector = UVC_PU_HUE_CONTROL, 60 .selector = UVC_PU_HUE_CONTROL,
59 .index = 2, 61 .index = 2,
60 .size = 2, 62 .size = 2,
61 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 63 .flags = UVC_CTRL_FLAG_SET_CUR
62 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 64 | UVC_CTRL_FLAG_GET_RANGE
65 | UVC_CTRL_FLAG_RESTORE
66 | UVC_CTRL_FLAG_AUTO_UPDATE,
63 }, 67 },
64 { 68 {
65 .entity = UVC_GUID_UVC_PROCESSING, 69 .entity = UVC_GUID_UVC_PROCESSING,
66 .selector = UVC_PU_SATURATION_CONTROL, 70 .selector = UVC_PU_SATURATION_CONTROL,
67 .index = 3, 71 .index = 3,
68 .size = 2, 72 .size = 2,
69 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 73 .flags = UVC_CTRL_FLAG_SET_CUR
70 | UVC_CONTROL_RESTORE, 74 | UVC_CTRL_FLAG_GET_RANGE
75 | UVC_CTRL_FLAG_RESTORE,
71 }, 76 },
72 { 77 {
73 .entity = UVC_GUID_UVC_PROCESSING, 78 .entity = UVC_GUID_UVC_PROCESSING,
74 .selector = UVC_PU_SHARPNESS_CONTROL, 79 .selector = UVC_PU_SHARPNESS_CONTROL,
75 .index = 4, 80 .index = 4,
76 .size = 2, 81 .size = 2,
77 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 82 .flags = UVC_CTRL_FLAG_SET_CUR
78 | UVC_CONTROL_RESTORE, 83 | UVC_CTRL_FLAG_GET_RANGE
84 | UVC_CTRL_FLAG_RESTORE,
79 }, 85 },
80 { 86 {
81 .entity = UVC_GUID_UVC_PROCESSING, 87 .entity = UVC_GUID_UVC_PROCESSING,
82 .selector = UVC_PU_GAMMA_CONTROL, 88 .selector = UVC_PU_GAMMA_CONTROL,
83 .index = 5, 89 .index = 5,
84 .size = 2, 90 .size = 2,
85 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 91 .flags = UVC_CTRL_FLAG_SET_CUR
86 | UVC_CONTROL_RESTORE, 92 | UVC_CTRL_FLAG_GET_RANGE
93 | UVC_CTRL_FLAG_RESTORE,
87 }, 94 },
88 { 95 {
89 .entity = UVC_GUID_UVC_PROCESSING, 96 .entity = UVC_GUID_UVC_PROCESSING,
90 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL, 97 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
91 .index = 6, 98 .index = 6,
92 .size = 2, 99 .size = 2,
93 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 100 .flags = UVC_CTRL_FLAG_SET_CUR
94 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 101 | UVC_CTRL_FLAG_GET_RANGE
102 | UVC_CTRL_FLAG_RESTORE
103 | UVC_CTRL_FLAG_AUTO_UPDATE,
95 }, 104 },
96 { 105 {
97 .entity = UVC_GUID_UVC_PROCESSING, 106 .entity = UVC_GUID_UVC_PROCESSING,
98 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL, 107 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
99 .index = 7, 108 .index = 7,
100 .size = 4, 109 .size = 4,
101 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 110 .flags = UVC_CTRL_FLAG_SET_CUR
102 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 111 | UVC_CTRL_FLAG_GET_RANGE
112 | UVC_CTRL_FLAG_RESTORE
113 | UVC_CTRL_FLAG_AUTO_UPDATE,
103 }, 114 },
104 { 115 {
105 .entity = UVC_GUID_UVC_PROCESSING, 116 .entity = UVC_GUID_UVC_PROCESSING,
106 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL, 117 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
107 .index = 8, 118 .index = 8,
108 .size = 2, 119 .size = 2,
109 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 120 .flags = UVC_CTRL_FLAG_SET_CUR
110 | UVC_CONTROL_RESTORE, 121 | UVC_CTRL_FLAG_GET_RANGE
122 | UVC_CTRL_FLAG_RESTORE,
111 }, 123 },
112 { 124 {
113 .entity = UVC_GUID_UVC_PROCESSING, 125 .entity = UVC_GUID_UVC_PROCESSING,
114 .selector = UVC_PU_GAIN_CONTROL, 126 .selector = UVC_PU_GAIN_CONTROL,
115 .index = 9, 127 .index = 9,
116 .size = 2, 128 .size = 2,
117 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 129 .flags = UVC_CTRL_FLAG_SET_CUR
118 | UVC_CONTROL_RESTORE, 130 | UVC_CTRL_FLAG_GET_RANGE
131 | UVC_CTRL_FLAG_RESTORE,
119 }, 132 },
120 { 133 {
121 .entity = UVC_GUID_UVC_PROCESSING, 134 .entity = UVC_GUID_UVC_PROCESSING,
122 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL, 135 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
123 .index = 10, 136 .index = 10,
124 .size = 1, 137 .size = 1,
125 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 138 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
126 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 139 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
127 }, 140 },
128 { 141 {
129 .entity = UVC_GUID_UVC_PROCESSING, 142 .entity = UVC_GUID_UVC_PROCESSING,
130 .selector = UVC_PU_HUE_AUTO_CONTROL, 143 .selector = UVC_PU_HUE_AUTO_CONTROL,
131 .index = 11, 144 .index = 11,
132 .size = 1, 145 .size = 1,
133 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 146 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
134 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 147 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
135 }, 148 },
136 { 149 {
137 .entity = UVC_GUID_UVC_PROCESSING, 150 .entity = UVC_GUID_UVC_PROCESSING,
138 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, 151 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
139 .index = 12, 152 .index = 12,
140 .size = 1, 153 .size = 1,
141 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 154 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
142 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 155 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
143 }, 156 },
144 { 157 {
145 .entity = UVC_GUID_UVC_PROCESSING, 158 .entity = UVC_GUID_UVC_PROCESSING,
146 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, 159 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
147 .index = 13, 160 .index = 13,
148 .size = 1, 161 .size = 1,
149 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 162 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
150 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 163 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
151 }, 164 },
152 { 165 {
153 .entity = UVC_GUID_UVC_PROCESSING, 166 .entity = UVC_GUID_UVC_PROCESSING,
154 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL, 167 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
155 .index = 14, 168 .index = 14,
156 .size = 2, 169 .size = 2,
157 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 170 .flags = UVC_CTRL_FLAG_SET_CUR
158 | UVC_CONTROL_RESTORE, 171 | UVC_CTRL_FLAG_GET_RANGE
172 | UVC_CTRL_FLAG_RESTORE,
159 }, 173 },
160 { 174 {
161 .entity = UVC_GUID_UVC_PROCESSING, 175 .entity = UVC_GUID_UVC_PROCESSING,
162 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, 176 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
163 .index = 15, 177 .index = 15,
164 .size = 2, 178 .size = 2,
165 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 179 .flags = UVC_CTRL_FLAG_SET_CUR
166 | UVC_CONTROL_RESTORE, 180 | UVC_CTRL_FLAG_GET_RANGE
181 | UVC_CTRL_FLAG_RESTORE,
167 }, 182 },
168 { 183 {
169 .entity = UVC_GUID_UVC_PROCESSING, 184 .entity = UVC_GUID_UVC_PROCESSING,
170 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL, 185 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
171 .index = 16, 186 .index = 16,
172 .size = 1, 187 .size = 1,
173 .flags = UVC_CONTROL_GET_CUR, 188 .flags = UVC_CTRL_FLAG_GET_CUR,
174 }, 189 },
175 { 190 {
176 .entity = UVC_GUID_UVC_PROCESSING, 191 .entity = UVC_GUID_UVC_PROCESSING,
177 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL, 192 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
178 .index = 17, 193 .index = 17,
179 .size = 1, 194 .size = 1,
180 .flags = UVC_CONTROL_GET_CUR, 195 .flags = UVC_CTRL_FLAG_GET_CUR,
181 }, 196 },
182 { 197 {
183 .entity = UVC_GUID_UVC_CAMERA, 198 .entity = UVC_GUID_UVC_CAMERA,
184 .selector = UVC_CT_SCANNING_MODE_CONTROL, 199 .selector = UVC_CT_SCANNING_MODE_CONTROL,
185 .index = 0, 200 .index = 0,
186 .size = 1, 201 .size = 1,
187 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 202 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
188 | UVC_CONTROL_RESTORE, 203 | UVC_CTRL_FLAG_RESTORE,
189 }, 204 },
190 { 205 {
191 .entity = UVC_GUID_UVC_CAMERA, 206 .entity = UVC_GUID_UVC_CAMERA,
192 .selector = UVC_CT_AE_MODE_CONTROL, 207 .selector = UVC_CT_AE_MODE_CONTROL,
193 .index = 1, 208 .index = 1,
194 .size = 1, 209 .size = 1,
195 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 210 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
196 | UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES 211 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_GET_RES
197 | UVC_CONTROL_RESTORE, 212 | UVC_CTRL_FLAG_RESTORE,
198 }, 213 },
199 { 214 {
200 .entity = UVC_GUID_UVC_CAMERA, 215 .entity = UVC_GUID_UVC_CAMERA,
201 .selector = UVC_CT_AE_PRIORITY_CONTROL, 216 .selector = UVC_CT_AE_PRIORITY_CONTROL,
202 .index = 2, 217 .index = 2,
203 .size = 1, 218 .size = 1,
204 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 219 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
205 | UVC_CONTROL_RESTORE, 220 | UVC_CTRL_FLAG_RESTORE,
206 }, 221 },
207 { 222 {
208 .entity = UVC_GUID_UVC_CAMERA, 223 .entity = UVC_GUID_UVC_CAMERA,
209 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, 224 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
210 .index = 3, 225 .index = 3,
211 .size = 4, 226 .size = 4,
212 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 227 .flags = UVC_CTRL_FLAG_SET_CUR
213 | UVC_CONTROL_RESTORE, 228 | UVC_CTRL_FLAG_GET_RANGE
229 | UVC_CTRL_FLAG_RESTORE,
214 }, 230 },
215 { 231 {
216 .entity = UVC_GUID_UVC_CAMERA, 232 .entity = UVC_GUID_UVC_CAMERA,
217 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL, 233 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
218 .index = 4, 234 .index = 4,
219 .size = 1, 235 .size = 1,
220 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_RESTORE, 236 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_RESTORE,
221 }, 237 },
222 { 238 {
223 .entity = UVC_GUID_UVC_CAMERA, 239 .entity = UVC_GUID_UVC_CAMERA,
224 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL, 240 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
225 .index = 5, 241 .index = 5,
226 .size = 2, 242 .size = 2,
227 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 243 .flags = UVC_CTRL_FLAG_SET_CUR
228 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 244 | UVC_CTRL_FLAG_GET_RANGE
245 | UVC_CTRL_FLAG_RESTORE
246 | UVC_CTRL_FLAG_AUTO_UPDATE,
229 }, 247 },
230 { 248 {
231 .entity = UVC_GUID_UVC_CAMERA, 249 .entity = UVC_GUID_UVC_CAMERA,
232 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL, 250 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
233 .index = 6, 251 .index = 6,
234 .size = 2, 252 .size = 2,
235 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 253 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
236 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 254 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
237 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 255 | UVC_CTRL_FLAG_GET_DEF
256 | UVC_CTRL_FLAG_AUTO_UPDATE,
238 }, 257 },
239 { 258 {
240 .entity = UVC_GUID_UVC_CAMERA, 259 .entity = UVC_GUID_UVC_CAMERA,
241 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL, 260 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
242 .index = 7, 261 .index = 7,
243 .size = 2, 262 .size = 2,
244 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 263 .flags = UVC_CTRL_FLAG_SET_CUR
245 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 264 | UVC_CTRL_FLAG_GET_RANGE
265 | UVC_CTRL_FLAG_RESTORE
266 | UVC_CTRL_FLAG_AUTO_UPDATE,
246 }, 267 },
247 { 268 {
248 .entity = UVC_GUID_UVC_CAMERA, 269 .entity = UVC_GUID_UVC_CAMERA,
249 .selector = UVC_CT_IRIS_RELATIVE_CONTROL, 270 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
250 .index = 8, 271 .index = 8,
251 .size = 1, 272 .size = 1,
252 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_AUTO_UPDATE, 273 .flags = UVC_CTRL_FLAG_SET_CUR
274 | UVC_CTRL_FLAG_AUTO_UPDATE,
253 }, 275 },
254 { 276 {
255 .entity = UVC_GUID_UVC_CAMERA, 277 .entity = UVC_GUID_UVC_CAMERA,
256 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL, 278 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
257 .index = 9, 279 .index = 9,
258 .size = 2, 280 .size = 2,
259 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 281 .flags = UVC_CTRL_FLAG_SET_CUR
260 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 282 | UVC_CTRL_FLAG_GET_RANGE
283 | UVC_CTRL_FLAG_RESTORE
284 | UVC_CTRL_FLAG_AUTO_UPDATE,
261 }, 285 },
262 { 286 {
263 .entity = UVC_GUID_UVC_CAMERA, 287 .entity = UVC_GUID_UVC_CAMERA,
264 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL, 288 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
265 .index = 10, 289 .index = 10,
266 .size = 3, 290 .size = 3,
267 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 291 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
268 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 292 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
269 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 293 | UVC_CTRL_FLAG_GET_DEF
294 | UVC_CTRL_FLAG_AUTO_UPDATE,
270 }, 295 },
271 { 296 {
272 .entity = UVC_GUID_UVC_CAMERA, 297 .entity = UVC_GUID_UVC_CAMERA,
273 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL, 298 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
274 .index = 11, 299 .index = 11,
275 .size = 8, 300 .size = 8,
276 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 301 .flags = UVC_CTRL_FLAG_SET_CUR
277 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 302 | UVC_CTRL_FLAG_GET_RANGE
303 | UVC_CTRL_FLAG_RESTORE
304 | UVC_CTRL_FLAG_AUTO_UPDATE,
278 }, 305 },
279 { 306 {
280 .entity = UVC_GUID_UVC_CAMERA, 307 .entity = UVC_GUID_UVC_CAMERA,
281 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL, 308 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
282 .index = 12, 309 .index = 12,
283 .size = 4, 310 .size = 4,
284 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 311 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
285 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 312 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
286 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 313 | UVC_CTRL_FLAG_GET_DEF
314 | UVC_CTRL_FLAG_AUTO_UPDATE,
287 }, 315 },
288 { 316 {
289 .entity = UVC_GUID_UVC_CAMERA, 317 .entity = UVC_GUID_UVC_CAMERA,
290 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL, 318 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,
291 .index = 13, 319 .index = 13,
292 .size = 2, 320 .size = 2,
293 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 321 .flags = UVC_CTRL_FLAG_SET_CUR
294 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 322 | UVC_CTRL_FLAG_GET_RANGE
323 | UVC_CTRL_FLAG_RESTORE
324 | UVC_CTRL_FLAG_AUTO_UPDATE,
295 }, 325 },
296 { 326 {
297 .entity = UVC_GUID_UVC_CAMERA, 327 .entity = UVC_GUID_UVC_CAMERA,
298 .selector = UVC_CT_ROLL_RELATIVE_CONTROL, 328 .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
299 .index = 14, 329 .index = 14,
300 .size = 2, 330 .size = 2,
301 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN 331 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
302 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES 332 | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
303 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE, 333 | UVC_CTRL_FLAG_GET_DEF
334 | UVC_CTRL_FLAG_AUTO_UPDATE,
304 }, 335 },
305 { 336 {
306 .entity = UVC_GUID_UVC_CAMERA, 337 .entity = UVC_GUID_UVC_CAMERA,
307 .selector = UVC_CT_FOCUS_AUTO_CONTROL, 338 .selector = UVC_CT_FOCUS_AUTO_CONTROL,
308 .index = 17, 339 .index = 17,
309 .size = 1, 340 .size = 1,
310 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 341 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
311 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, 342 | UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
312 }, 343 },
313 { 344 {
314 .entity = UVC_GUID_UVC_CAMERA, 345 .entity = UVC_GUID_UVC_CAMERA,
315 .selector = UVC_CT_PRIVACY_CONTROL, 346 .selector = UVC_CT_PRIVACY_CONTROL,
316 .index = 18, 347 .index = 18,
317 .size = 1, 348 .size = 1,
318 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 349 .flags = UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
319 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, 350 | UVC_CTRL_FLAG_RESTORE
351 | UVC_CTRL_FLAG_AUTO_UPDATE,
320 }, 352 },
321}; 353};
322 354
@@ -816,7 +848,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
816{ 848{
817 int ret; 849 int ret;
818 850
819 if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { 851 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
820 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, 852 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
821 chain->dev->intfnum, ctrl->info.selector, 853 chain->dev->intfnum, ctrl->info.selector,
822 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), 854 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
@@ -825,7 +857,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
825 return ret; 857 return ret;
826 } 858 }
827 859
828 if (ctrl->info.flags & UVC_CONTROL_GET_MIN) { 860 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {
829 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, 861 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
830 chain->dev->intfnum, ctrl->info.selector, 862 chain->dev->intfnum, ctrl->info.selector,
831 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), 863 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
@@ -833,7 +865,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
833 if (ret < 0) 865 if (ret < 0)
834 return ret; 866 return ret;
835 } 867 }
836 if (ctrl->info.flags & UVC_CONTROL_GET_MAX) { 868 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) {
837 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, 869 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
838 chain->dev->intfnum, ctrl->info.selector, 870 chain->dev->intfnum, ctrl->info.selector,
839 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), 871 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
@@ -841,7 +873,7 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
841 if (ret < 0) 873 if (ret < 0)
842 return ret; 874 return ret;
843 } 875 }
844 if (ctrl->info.flags & UVC_CONTROL_GET_RES) { 876 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
845 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, 877 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
846 chain->dev->intfnum, ctrl->info.selector, 878 chain->dev->intfnum, ctrl->info.selector,
847 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 879 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
@@ -879,9 +911,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
879 strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); 911 strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
880 v4l2_ctrl->flags = 0; 912 v4l2_ctrl->flags = 0;
881 913
882 if (!(ctrl->info.flags & UVC_CONTROL_GET_CUR)) 914 if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
883 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; 915 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
884 if (!(ctrl->info.flags & UVC_CONTROL_SET_CUR)) 916 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
885 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 917 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
886 918
887 if (!ctrl->cached) { 919 if (!ctrl->cached) {
@@ -890,7 +922,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
890 goto done; 922 goto done;
891 } 923 }
892 924
893 if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { 925 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
894 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, 926 v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
895 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); 927 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
896 } 928 }
@@ -927,15 +959,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
927 break; 959 break;
928 } 960 }
929 961
930 if (ctrl->info.flags & UVC_CONTROL_GET_MIN) 962 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
931 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, 963 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
932 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); 964 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
933 965
934 if (ctrl->info.flags & UVC_CONTROL_GET_MAX) 966 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
935 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, 967 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
936 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); 968 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
937 969
938 if (ctrl->info.flags & UVC_CONTROL_GET_RES) 970 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
939 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, 971 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
940 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); 972 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
941 973
@@ -983,6 +1015,24 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
983 } 1015 }
984 1016
985 menu_info = &mapping->menu_info[query_menu->index]; 1017 menu_info = &mapping->menu_info[query_menu->index];
1018
1019 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
1020 s32 bitmap;
1021
1022 if (!ctrl->cached) {
1023 ret = uvc_ctrl_populate_cache(chain, ctrl);
1024 if (ret < 0)
1025 goto done;
1026 }
1027
1028 bitmap = mapping->get(mapping, UVC_GET_RES,
1029 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1030 if (!(bitmap & menu_info->value)) {
1031 ret = -EINVAL;
1032 goto done;
1033 }
1034 }
1035
986 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); 1036 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
987 1037
988done: 1038done:
@@ -1039,7 +1089,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1039 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent 1089 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
1040 * uvc_ctrl_get from using the cached value. 1090 * uvc_ctrl_get from using the cached value.
1041 */ 1091 */
1042 if (ctrl->info.flags & UVC_CONTROL_AUTO_UPDATE) 1092 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE)
1043 ctrl->loaded = 0; 1093 ctrl->loaded = 0;
1044 1094
1045 if (!ctrl->dirty) 1095 if (!ctrl->dirty)
@@ -1094,7 +1144,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
1094 int ret; 1144 int ret;
1095 1145
1096 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1146 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1097 if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) 1147 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
1098 return -EINVAL; 1148 return -EINVAL;
1099 1149
1100 if (!ctrl->loaded) { 1150 if (!ctrl->loaded) {
@@ -1136,7 +1186,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1136 int ret; 1186 int ret;
1137 1187
1138 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1188 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1139 if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_SET_CUR) == 0) 1189 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
1140 return -EINVAL; 1190 return -EINVAL;
1141 1191
1142 /* Clamp out of range values. */ 1192 /* Clamp out of range values. */
@@ -1171,6 +1221,23 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1171 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count) 1221 if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
1172 return -ERANGE; 1222 return -ERANGE;
1173 value = mapping->menu_info[xctrl->value].value; 1223 value = mapping->menu_info[xctrl->value].value;
1224
1225 /* Valid menu indices are reported by the GET_RES request for
1226 * UVC controls that support it.
1227 */
1228 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
1229 if (!ctrl->cached) {
1230 ret = uvc_ctrl_populate_cache(chain, ctrl);
1231 if (ret < 0)
1232 return ret;
1233 }
1234
1235 step = mapping->get(mapping, UVC_GET_RES,
1236 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1237 if (!(step & value))
1238 return -ERANGE;
1239 }
1240
1174 break; 1241 break;
1175 1242
1176 default: 1243 default:
@@ -1183,7 +1250,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1183 * operation. 1250 * operation.
1184 */ 1251 */
1185 if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { 1252 if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
1186 if ((ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) { 1253 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
1187 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1254 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1188 0, ctrl->info.size); 1255 0, ctrl->info.size);
1189 } else { 1256 } else {
@@ -1230,17 +1297,17 @@ static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
1230 1297
1231 static const struct uvc_ctrl_fixup fixups[] = { 1298 static const struct uvc_ctrl_fixup fixups[] = {
1232 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1, 1299 { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
1233 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | 1300 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1234 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | 1301 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1235 UVC_CONTROL_AUTO_UPDATE }, 1302 UVC_CTRL_FLAG_AUTO_UPDATE },
1236 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1, 1303 { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
1237 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | 1304 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1238 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | 1305 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1239 UVC_CONTROL_AUTO_UPDATE }, 1306 UVC_CTRL_FLAG_AUTO_UPDATE },
1240 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1, 1307 { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
1241 UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | 1308 UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
1242 UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR | 1309 UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
1243 UVC_CONTROL_AUTO_UPDATE }, 1310 UVC_CTRL_FLAG_AUTO_UPDATE },
1244 }; 1311 };
1245 1312
1246 unsigned int i; 1313 unsigned int i;
@@ -1297,21 +1364,23 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
1297 goto done; 1364 goto done;
1298 } 1365 }
1299 1366
1300 info->flags = UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX 1367 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
1301 | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF 1368 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
1302 | (data[0] & UVC_CONTROL_CAP_GET ? UVC_CONTROL_GET_CUR : 0) 1369 | (data[0] & UVC_CONTROL_CAP_GET ?
1303 | (data[0] & UVC_CONTROL_CAP_SET ? UVC_CONTROL_SET_CUR : 0) 1370 UVC_CTRL_FLAG_GET_CUR : 0)
1371 | (data[0] & UVC_CONTROL_CAP_SET ?
1372 UVC_CTRL_FLAG_SET_CUR : 0)
1304 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? 1373 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
1305 UVC_CONTROL_AUTO_UPDATE : 0); 1374 UVC_CTRL_FLAG_AUTO_UPDATE : 0);
1306 1375
1307 uvc_ctrl_fixup_xu_info(dev, ctrl, info); 1376 uvc_ctrl_fixup_xu_info(dev, ctrl, info);
1308 1377
1309 uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " 1378 uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, "
1310 "flags { get %u set %u auto %u }.\n", 1379 "flags { get %u set %u auto %u }.\n",
1311 info->entity, info->selector, info->size, 1380 info->entity, info->selector, info->size,
1312 (info->flags & UVC_CONTROL_GET_CUR) ? 1 : 0, 1381 (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,
1313 (info->flags & UVC_CONTROL_SET_CUR) ? 1 : 0, 1382 (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,
1314 (info->flags & UVC_CONTROL_AUTO_UPDATE) ? 1 : 0); 1383 (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0);
1315 1384
1316done: 1385done:
1317 kfree(data); 1386 kfree(data);
@@ -1344,32 +1413,33 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
1344} 1413}
1345 1414
1346int uvc_xu_ctrl_query(struct uvc_video_chain *chain, 1415int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1347 struct uvc_xu_control *xctrl, int set) 1416 struct uvc_xu_control_query *xqry)
1348{ 1417{
1349 struct uvc_entity *entity; 1418 struct uvc_entity *entity;
1350 struct uvc_control *ctrl = NULL; 1419 struct uvc_control *ctrl;
1351 unsigned int i, found = 0; 1420 unsigned int i, found = 0;
1352 int restore = 0; 1421 __u32 reqflags;
1353 __u8 *data; 1422 __u16 size;
1423 __u8 *data = NULL;
1354 int ret; 1424 int ret;
1355 1425
1356 /* Find the extension unit. */ 1426 /* Find the extension unit. */
1357 list_for_each_entry(entity, &chain->entities, chain) { 1427 list_for_each_entry(entity, &chain->entities, chain) {
1358 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && 1428 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
1359 entity->id == xctrl->unit) 1429 entity->id == xqry->unit)
1360 break; 1430 break;
1361 } 1431 }
1362 1432
1363 if (entity->id != xctrl->unit) { 1433 if (entity->id != xqry->unit) {
1364 uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n", 1434 uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
1365 xctrl->unit); 1435 xqry->unit);
1366 return -EINVAL; 1436 return -ENOENT;
1367 } 1437 }
1368 1438
1369 /* Find the control and perform delayed initialization if needed. */ 1439 /* Find the control and perform delayed initialization if needed. */
1370 for (i = 0; i < entity->ncontrols; ++i) { 1440 for (i = 0; i < entity->ncontrols; ++i) {
1371 ctrl = &entity->controls[i]; 1441 ctrl = &entity->controls[i];
1372 if (ctrl->index == xctrl->selector - 1) { 1442 if (ctrl->index == xqry->selector - 1) {
1373 found = 1; 1443 found = 1;
1374 break; 1444 break;
1375 } 1445 }
@@ -1377,8 +1447,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1377 1447
1378 if (!found) { 1448 if (!found) {
1379 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n", 1449 uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
1380 entity->extension.guidExtensionCode, xctrl->selector); 1450 entity->extension.guidExtensionCode, xqry->selector);
1381 return -EINVAL; 1451 return -ENOENT;
1382 } 1452 }
1383 1453
1384 if (mutex_lock_interruptible(&chain->ctrl_mutex)) 1454 if (mutex_lock_interruptible(&chain->ctrl_mutex))
@@ -1390,43 +1460,72 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1390 goto done; 1460 goto done;
1391 } 1461 }
1392 1462
1393 /* Validate control data size. */ 1463 /* Validate the required buffer size and flags for the request */
1394 if (ctrl->info.size != xctrl->size) { 1464 reqflags = 0;
1465 size = ctrl->info.size;
1466
1467 switch (xqry->query) {
1468 case UVC_GET_CUR:
1469 reqflags = UVC_CTRL_FLAG_GET_CUR;
1470 break;
1471 case UVC_GET_MIN:
1472 reqflags = UVC_CTRL_FLAG_GET_MIN;
1473 break;
1474 case UVC_GET_MAX:
1475 reqflags = UVC_CTRL_FLAG_GET_MAX;
1476 break;
1477 case UVC_GET_DEF:
1478 reqflags = UVC_CTRL_FLAG_GET_DEF;
1479 break;
1480 case UVC_GET_RES:
1481 reqflags = UVC_CTRL_FLAG_GET_RES;
1482 break;
1483 case UVC_SET_CUR:
1484 reqflags = UVC_CTRL_FLAG_SET_CUR;
1485 break;
1486 case UVC_GET_LEN:
1487 size = 2;
1488 break;
1489 case UVC_GET_INFO:
1490 size = 1;
1491 break;
1492 default:
1395 ret = -EINVAL; 1493 ret = -EINVAL;
1396 goto done; 1494 goto done;
1397 } 1495 }
1398 1496
1399 if ((set && !(ctrl->info.flags & UVC_CONTROL_SET_CUR)) || 1497 if (size != xqry->size) {
1400 (!set && !(ctrl->info.flags & UVC_CONTROL_GET_CUR))) { 1498 ret = -ENOBUFS;
1401 ret = -EINVAL;
1402 goto done; 1499 goto done;
1403 } 1500 }
1404 1501
1405 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1502 if (reqflags && !(ctrl->info.flags & reqflags)) {
1406 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1503 ret = -EBADRQC;
1407 ctrl->info.size); 1504 goto done;
1408 data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); 1505 }
1409 restore = set;
1410 1506
1411 if (set && copy_from_user(data, xctrl->data, xctrl->size)) { 1507 data = kmalloc(size, GFP_KERNEL);
1508 if (data == NULL) {
1509 ret = -ENOMEM;
1510 goto done;
1511 }
1512
1513 if (xqry->query == UVC_SET_CUR &&
1514 copy_from_user(data, xqry->data, size)) {
1412 ret = -EFAULT; 1515 ret = -EFAULT;
1413 goto done; 1516 goto done;
1414 } 1517 }
1415 1518
1416 ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR, 1519 ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit,
1417 xctrl->unit, chain->dev->intfnum, xctrl->selector, 1520 chain->dev->intfnum, xqry->selector, data, size);
1418 data, xctrl->size);
1419 if (ret < 0) 1521 if (ret < 0)
1420 goto done; 1522 goto done;
1421 1523
1422 if (!set && copy_to_user(xctrl->data, data, xctrl->size)) 1524 if (xqry->query != UVC_SET_CUR &&
1525 copy_to_user(xqry->data, data, size))
1423 ret = -EFAULT; 1526 ret = -EFAULT;
1424done: 1527done:
1425 if (ret && restore) 1528 kfree(data);
1426 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1427 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1428 xctrl->size);
1429
1430 mutex_unlock(&chain->ctrl_mutex); 1529 mutex_unlock(&chain->ctrl_mutex);
1431 return ret; 1530 return ret;
1432} 1531}
@@ -1458,7 +1557,7 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
1458 ctrl = &entity->controls[i]; 1557 ctrl = &entity->controls[i];
1459 1558
1460 if (!ctrl->initialized || !ctrl->modified || 1559 if (!ctrl->initialized || !ctrl->modified ||
1461 (ctrl->info.flags & UVC_CONTROL_RESTORE) == 0) 1560 (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)
1462 continue; 1561 continue;
1463 1562
1464 printk(KERN_INFO "restoring control %pUl/%u/%u\n", 1563 printk(KERN_INFO "restoring control %pUl/%u/%u\n",
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 6459b8cba223..823f4b389745 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -84,6 +84,11 @@ static struct uvc_format_desc uvc_fmts[] = {
84 .fcc = V4L2_PIX_FMT_YUV420, 84 .fcc = V4L2_PIX_FMT_YUV420,
85 }, 85 },
86 { 86 {
87 .name = "YUV 4:2:0 (M420)",
88 .guid = UVC_GUID_FORMAT_M420,
89 .fcc = V4L2_PIX_FMT_M420,
90 },
91 {
87 .name = "YUV 4:2:2 (UYVY)", 92 .name = "YUV 4:2:2 (UYVY)",
88 .guid = UVC_GUID_FORMAT_UYVY, 93 .guid = UVC_GUID_FORMAT_UYVY,
89 .fcc = V4L2_PIX_FMT_UYVY, 94 .fcc = V4L2_PIX_FMT_UYVY,
@@ -103,6 +108,11 @@ static struct uvc_format_desc uvc_fmts[] = {
103 .guid = UVC_GUID_FORMAT_BY8, 108 .guid = UVC_GUID_FORMAT_BY8,
104 .fcc = V4L2_PIX_FMT_SBGGR8, 109 .fcc = V4L2_PIX_FMT_SBGGR8,
105 }, 110 },
111 {
112 .name = "RGB565",
113 .guid = UVC_GUID_FORMAT_RGBP,
114 .fcc = V4L2_PIX_FMT_RGB565,
115 },
106}; 116};
107 117
108/* ------------------------------------------------------------------------ 118/* ------------------------------------------------------------------------
@@ -2077,6 +2087,15 @@ static struct usb_device_id uvc_ids[] = {
2077 .bInterfaceSubClass = 1, 2087 .bInterfaceSubClass = 1,
2078 .bInterfaceProtocol = 0, 2088 .bInterfaceProtocol = 0,
2079 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 2089 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2090 /* Hercules Classic Silver */
2091 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2092 | USB_DEVICE_ID_MATCH_INT_INFO,
2093 .idVendor = 0x06f8,
2094 .idProduct = 0x300c,
2095 .bInterfaceClass = USB_CLASS_VIDEO,
2096 .bInterfaceSubClass = 1,
2097 .bInterfaceProtocol = 0,
2098 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2080 /* ViMicro Vega */ 2099 /* ViMicro Vega */
2081 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2100 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2082 | USB_DEVICE_ID_MATCH_INT_INFO, 2101 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2142,15 @@ static struct usb_device_id uvc_ids[] = {
2123 .bInterfaceSubClass = 1, 2142 .bInterfaceSubClass = 1,
2124 .bInterfaceProtocol = 0, 2143 .bInterfaceProtocol = 0,
2125 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 2144 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2145 /* JMicron USB2.0 XGA WebCam */
2146 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2147 | USB_DEVICE_ID_MATCH_INT_INFO,
2148 .idVendor = 0x152d,
2149 .idProduct = 0x0310,
2150 .bInterfaceClass = USB_CLASS_VIDEO,
2151 .bInterfaceSubClass = 1,
2152 .bInterfaceProtocol = 0,
2153 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2126 /* Syntek (HP Spartan) */ 2154 /* Syntek (HP Spartan) */
2127 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2155 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2128 | USB_DEVICE_ID_MATCH_INT_INFO, 2156 | USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index f14581bd707f..109a06384a8f 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -424,7 +424,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
424 break; 424 break;
425 } 425 }
426 426
427 if (i == queue->count || size != queue->buf_size) { 427 if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) {
428 ret = -EINVAL; 428 ret = -EINVAL;
429 goto done; 429 goto done;
430 } 430 }
@@ -436,6 +436,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
436 vma->vm_flags |= VM_IO; 436 vma->vm_flags |= VM_IO;
437 437
438 addr = (unsigned long)queue->mem + buffer->buf.m.offset; 438 addr = (unsigned long)queue->mem + buffer->buf.m.offset;
439#ifdef CONFIG_MMU
439 while (size > 0) { 440 while (size > 0) {
440 page = vmalloc_to_page((void *)addr); 441 page = vmalloc_to_page((void *)addr);
441 if ((ret = vm_insert_page(vma, start, page)) < 0) 442 if ((ret = vm_insert_page(vma, start, page)) < 0)
@@ -445,6 +446,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
445 addr += PAGE_SIZE; 446 addr += PAGE_SIZE;
446 size -= PAGE_SIZE; 447 size -= PAGE_SIZE;
447 } 448 }
449#endif
448 450
449 vma->vm_ops = &uvc_vm_ops; 451 vma->vm_ops = &uvc_vm_ops;
450 vma->vm_private_data = buffer; 452 vma->vm_private_data = buffer;
@@ -488,6 +490,36 @@ done:
488 return mask; 490 return mask;
489} 491}
490 492
493#ifndef CONFIG_MMU
494/*
495 * Get unmapped area.
496 *
497 * NO-MMU arch need this function to make mmap() work correctly.
498 */
499unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
500 unsigned long pgoff)
501{
502 struct uvc_buffer *buffer;
503 unsigned int i;
504 unsigned long ret;
505
506 mutex_lock(&queue->mutex);
507 for (i = 0; i < queue->count; ++i) {
508 buffer = &queue->buffer[i];
509 if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff)
510 break;
511 }
512 if (i == queue->count) {
513 ret = -EINVAL;
514 goto done;
515 }
516 ret = (unsigned long)queue->mem + buffer->buf.m.offset;
517done:
518 mutex_unlock(&queue->mutex);
519 return ret;
520}
521#endif
522
491/* 523/*
492 * Enable or disable the video buffers queue. 524 * Enable or disable the video buffers queue.
493 * 525 *
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 9005a8d9d5f8..543a80395b7f 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -538,6 +538,20 @@ static int uvc_v4l2_release(struct file *file)
538 return 0; 538 return 0;
539} 539}
540 540
541static void uvc_v4l2_ioctl_warn(void)
542{
543 static int warned;
544
545 if (warned)
546 return;
547
548 uvc_printk(KERN_INFO, "Deprecated UVCIOC_CTRL_{ADD,MAP_OLD,GET,SET} "
549 "ioctls will be removed in 2.6.42.\n");
550 uvc_printk(KERN_INFO, "See http://www.ideasonboard.org/uvc/upgrade/ "
551 "for upgrade instructions.\n");
552 warned = 1;
553}
554
541static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) 555static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
542{ 556{
543 struct video_device *vdev = video_devdata(file); 557 struct video_device *vdev = video_devdata(file);
@@ -1018,21 +1032,40 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1018 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); 1032 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
1019 return -EINVAL; 1033 return -EINVAL;
1020 1034
1021 /* Dynamic controls. */ 1035 /* Dynamic controls. UVCIOC_CTRL_ADD, UVCIOC_CTRL_MAP_OLD,
1022 case UVCIOC_CTRL_ADD: 1036 * UVCIOC_CTRL_GET and UVCIOC_CTRL_SET are deprecated and scheduled for
1023 /* Legacy ioctl, kept for API compatibility reasons */ 1037 * removal in 2.6.42.
1038 */
1039 case __UVCIOC_CTRL_ADD:
1040 uvc_v4l2_ioctl_warn();
1024 return -EEXIST; 1041 return -EEXIST;
1025 1042
1026 case UVCIOC_CTRL_MAP_OLD: 1043 case __UVCIOC_CTRL_MAP_OLD:
1044 uvc_v4l2_ioctl_warn();
1045 case __UVCIOC_CTRL_MAP:
1027 case UVCIOC_CTRL_MAP: 1046 case UVCIOC_CTRL_MAP:
1028 return uvc_ioctl_ctrl_map(chain, arg, 1047 return uvc_ioctl_ctrl_map(chain, arg,
1029 cmd == UVCIOC_CTRL_MAP_OLD); 1048 cmd == __UVCIOC_CTRL_MAP_OLD);
1030 1049
1031 case UVCIOC_CTRL_GET: 1050 case __UVCIOC_CTRL_GET:
1032 return uvc_xu_ctrl_query(chain, arg, 0); 1051 case __UVCIOC_CTRL_SET:
1052 {
1053 struct uvc_xu_control *xctrl = arg;
1054 struct uvc_xu_control_query xqry = {
1055 .unit = xctrl->unit,
1056 .selector = xctrl->selector,
1057 .query = cmd == __UVCIOC_CTRL_GET
1058 ? UVC_GET_CUR : UVC_SET_CUR,
1059 .size = xctrl->size,
1060 .data = xctrl->data,
1061 };
1062
1063 uvc_v4l2_ioctl_warn();
1064 return uvc_xu_ctrl_query(chain, &xqry);
1065 }
1033 1066
1034 case UVCIOC_CTRL_SET: 1067 case UVCIOC_CTRL_QUERY:
1035 return uvc_xu_ctrl_query(chain, arg, 1); 1068 return uvc_xu_ctrl_query(chain, arg);
1036 1069
1037 default: 1070 default:
1038 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); 1071 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
@@ -1081,6 +1114,20 @@ static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
1081 return uvc_queue_poll(&stream->queue, file, wait); 1114 return uvc_queue_poll(&stream->queue, file, wait);
1082} 1115}
1083 1116
1117#ifndef CONFIG_MMU
1118static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1119 unsigned long addr, unsigned long len, unsigned long pgoff,
1120 unsigned long flags)
1121{
1122 struct uvc_fh *handle = file->private_data;
1123 struct uvc_streaming *stream = handle->stream;
1124
1125 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
1126
1127 return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1128}
1129#endif
1130
1084const struct v4l2_file_operations uvc_fops = { 1131const struct v4l2_file_operations uvc_fops = {
1085 .owner = THIS_MODULE, 1132 .owner = THIS_MODULE,
1086 .open = uvc_v4l2_open, 1133 .open = uvc_v4l2_open,
@@ -1089,5 +1136,8 @@ const struct v4l2_file_operations uvc_fops = {
1089 .read = uvc_v4l2_read, 1136 .read = uvc_v4l2_read,
1090 .mmap = uvc_v4l2_mmap, 1137 .mmap = uvc_v4l2_mmap,
1091 .poll = uvc_v4l2_poll, 1138 .poll = uvc_v4l2_poll,
1139#ifndef CONFIG_MMU
1140 .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1141#endif
1092}; 1142};
1093 1143
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 45f01e7e13d2..7cf224bae2e5 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -4,6 +4,14 @@
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/videodev2.h> 5#include <linux/videodev2.h>
6 6
7#ifndef __KERNEL__
8/*
9 * This header provides binary compatibility with applications using the private
10 * uvcvideo API. This API is deprecated and will be removed in 2.6.42.
11 * Applications should be recompiled against the public linux/uvcvideo.h header.
12 */
13#warn "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
14
7/* 15/*
8 * Dynamic controls 16 * Dynamic controls
9 */ 17 */
@@ -23,32 +31,18 @@
23#define UVC_CONTROL_GET_MAX (1 << 3) 31#define UVC_CONTROL_GET_MAX (1 << 3)
24#define UVC_CONTROL_GET_RES (1 << 4) 32#define UVC_CONTROL_GET_RES (1 << 4)
25#define UVC_CONTROL_GET_DEF (1 << 5) 33#define UVC_CONTROL_GET_DEF (1 << 5)
26/* Control should be saved at suspend and restored at resume. */
27#define UVC_CONTROL_RESTORE (1 << 6) 34#define UVC_CONTROL_RESTORE (1 << 6)
28/* Control can be updated by the camera. */
29#define UVC_CONTROL_AUTO_UPDATE (1 << 7) 35#define UVC_CONTROL_AUTO_UPDATE (1 << 7)
30 36
31#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ 37#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \
32 UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ 38 UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \
33 UVC_CONTROL_GET_DEF) 39 UVC_CONTROL_GET_DEF)
34 40
35struct uvc_xu_control_info {
36 __u8 entity[16];
37 __u8 index;
38 __u8 selector;
39 __u16 size;
40 __u32 flags;
41};
42
43struct uvc_menu_info { 41struct uvc_menu_info {
44 __u32 value; 42 __u32 value;
45 __u8 name[32]; 43 __u8 name[32];
46}; 44};
47 45
48struct uvc_xu_control_mapping_old {
49 __u8 reserved[64];
50};
51
52struct uvc_xu_control_mapping { 46struct uvc_xu_control_mapping {
53 __u32 id; 47 __u32 id;
54 __u8 name[32]; 48 __u8 name[32];
@@ -57,7 +51,7 @@ struct uvc_xu_control_mapping {
57 51
58 __u8 size; 52 __u8 size;
59 __u8 offset; 53 __u8 offset;
60 enum v4l2_ctrl_type v4l2_type; 54 __u32 v4l2_type;
61 __u32 data_type; 55 __u32 data_type;
62 56
63 struct uvc_menu_info __user *menu_info; 57 struct uvc_menu_info __user *menu_info;
@@ -66,6 +60,20 @@ struct uvc_xu_control_mapping {
66 __u32 reserved[4]; 60 __u32 reserved[4];
67}; 61};
68 62
63#endif
64
65struct uvc_xu_control_info {
66 __u8 entity[16];
67 __u8 index;
68 __u8 selector;
69 __u16 size;
70 __u32 flags;
71};
72
73struct uvc_xu_control_mapping_old {
74 __u8 reserved[64];
75};
76
69struct uvc_xu_control { 77struct uvc_xu_control {
70 __u8 unit; 78 __u8 unit;
71 __u8 selector; 79 __u8 selector;
@@ -73,16 +81,25 @@ struct uvc_xu_control {
73 __u8 __user *data; 81 __u8 __user *data;
74}; 82};
75 83
84#ifndef __KERNEL__
76#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) 85#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
77#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old) 86#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old)
78#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) 87#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
79#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) 88#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
80#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) 89#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
90#else
91#define __UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
92#define __UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old)
93#define __UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
94#define __UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
95#define __UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
96#endif
81 97
82#ifdef __KERNEL__ 98#ifdef __KERNEL__
83 99
84#include <linux/poll.h> 100#include <linux/poll.h>
85#include <linux/usb/video.h> 101#include <linux/usb/video.h>
102#include <linux/uvcvideo.h>
86 103
87/* -------------------------------------------------------------------------- 104/* --------------------------------------------------------------------------
88 * UVC constants 105 * UVC constants
@@ -152,13 +169,19 @@ struct uvc_xu_control {
152#define UVC_GUID_FORMAT_BY8 \ 169#define UVC_GUID_FORMAT_BY8 \
153 { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 170 { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
154 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 171 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
172#define UVC_GUID_FORMAT_RGBP \
173 { 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \
174 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
175#define UVC_GUID_FORMAT_M420 \
176 { 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
177 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
155 178
156/* ------------------------------------------------------------------------ 179/* ------------------------------------------------------------------------
157 * Driver specific constants. 180 * Driver specific constants.
158 */ 181 */
159 182
160#define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 0, 0) 183#define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 1, 0)
161#define DRIVER_VERSION "v1.0.0" 184#define DRIVER_VERSION "v1.1.0"
162 185
163/* Number of isochronous URBs. */ 186/* Number of isochronous URBs. */
164#define UVC_URBS 5 187#define UVC_URBS 5
@@ -580,6 +603,10 @@ extern int uvc_queue_mmap(struct uvc_video_queue *queue,
580 struct vm_area_struct *vma); 603 struct vm_area_struct *vma);
581extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, 604extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
582 struct file *file, poll_table *wait); 605 struct file *file, poll_table *wait);
606#ifndef CONFIG_MMU
607extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
608 unsigned long pgoff);
609#endif
583extern int uvc_queue_allocated(struct uvc_video_queue *queue); 610extern int uvc_queue_allocated(struct uvc_video_queue *queue);
584static inline int uvc_queue_streaming(struct uvc_video_queue *queue) 611static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
585{ 612{
@@ -638,7 +665,7 @@ extern int uvc_ctrl_set(struct uvc_video_chain *chain,
638 struct v4l2_ext_control *xctrl); 665 struct v4l2_ext_control *xctrl);
639 666
640extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, 667extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
641 struct uvc_xu_control *ctrl, int set); 668 struct uvc_xu_control_query *xqry);
642 669
643/* Utility functions */ 670/* Utility functions */
644extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, 671extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
@@ -655,4 +682,3 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
655#endif /* __KERNEL__ */ 682#endif /* __KERNEL__ */
656 683
657#endif 684#endif
658
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 6dc7196296b3..19d5ae293780 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -352,6 +352,23 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
352 return ret; 352 return ret;
353} 353}
354 354
355#ifdef CONFIG_MMU
356#define v4l2_get_unmapped_area NULL
357#else
358static unsigned long v4l2_get_unmapped_area(struct file *filp,
359 unsigned long addr, unsigned long len, unsigned long pgoff,
360 unsigned long flags)
361{
362 struct video_device *vdev = video_devdata(filp);
363
364 if (!vdev->fops->get_unmapped_area)
365 return -ENOSYS;
366 if (!video_is_registered(vdev))
367 return -ENODEV;
368 return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
369}
370#endif
371
355static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) 372static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
356{ 373{
357 struct video_device *vdev = video_devdata(filp); 374 struct video_device *vdev = video_devdata(filp);
@@ -454,6 +471,7 @@ static const struct file_operations v4l2_fops = {
454 .read = v4l2_read, 471 .read = v4l2_read,
455 .write = v4l2_write, 472 .write = v4l2_write,
456 .open = v4l2_open, 473 .open = v4l2_open,
474 .get_unmapped_area = v4l2_get_unmapped_area,
457 .mmap = v4l2_mmap, 475 .mmap = v4l2_mmap,
458 .unlocked_ioctl = v4l2_ioctl, 476 .unlocked_ioctl = v4l2_ioctl,
459#ifdef CONFIG_COMPAT 477#ifdef CONFIG_COMPAT
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 8c780c2d937b..85d3048c1d67 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -29,6 +29,7 @@
29 29
30#include "via-camera.h" 30#include "via-camera.h"
31 31
32MODULE_ALIAS("platform:viafb-camera");
32MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>"); 33MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
33MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver"); 34MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 9f2bac519647..79b04ac0f1ad 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -64,14 +64,6 @@ static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
64module_param_array(card, int, NULL, 0444); 64module_param_array(card, int, NULL, 0444);
65MODULE_PARM_DESC(card, "Card type"); 65MODULE_PARM_DESC(card, "Card type");
66 66
67static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
68module_param_array(encoder, int, NULL, 0444);
69MODULE_PARM_DESC(encoder, "Video encoder chip");
70
71static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
72module_param_array(decoder, int, NULL, 0444);
73MODULE_PARM_DESC(decoder, "Video decoder chip");
74
75/* 67/*
76 The video mem address of the video card. 68 The video mem address of the video card.
77 The driver has a little database for some videocards 69 The driver has a little database for some videocards
@@ -1230,7 +1222,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
1230 mutex_init(&zr->other_lock); 1222 mutex_init(&zr->other_lock);
1231 if (pci_enable_device(pdev)) 1223 if (pci_enable_device(pdev))
1232 goto zr_unreg; 1224 goto zr_unreg;
1233 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); 1225 zr->revision = zr->pci_dev->revision;
1234 1226
1235 dprintk(1, 1227 dprintk(1,
1236 KERN_INFO 1228 KERN_INFO
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c
index 63a438d1c849..7080cdeab5a6 100644
--- a/drivers/staging/lirc/lirc_sasem.c
+++ b/drivers/staging/lirc/lirc_sasem.c
@@ -570,6 +570,7 @@ static void incoming_packet(struct sasem_context *context,
570 unsigned char *buf = urb->transfer_buffer; 570 unsigned char *buf = urb->transfer_buffer;
571 long ms; 571 long ms;
572 struct timeval tv; 572 struct timeval tv;
573 int i;
573 574
574 if (len != 8) { 575 if (len != 8) {
575 printk(KERN_WARNING "%s: invalid incoming packet size (%d)\n", 576 printk(KERN_WARNING "%s: invalid incoming packet size (%d)\n",
@@ -577,12 +578,12 @@ static void incoming_packet(struct sasem_context *context,
577 return; 578 return;
578 } 579 }
579 580
580#ifdef DEBUG 581 if (debug) {
581 int i; 582 printk(KERN_INFO "Incoming data: ");
582 for (i = 0; i < 8; ++i) 583 for (i = 0; i < 8; ++i)
583 printk(KERN_INFO "%02x ", buf[i]); 584 printk(KERN_CONT "%02x ", buf[i]);
584 printk(KERN_INFO "\n"); 585 printk(KERN_CONT "\n");
585#endif 586 }
586 587
587 /* 588 /*
588 * Lirc could deal with the repeat code, but we really need to block it 589 * Lirc could deal with the repeat code, but we really need to block it
diff --git a/drivers/staging/tm6000/CARDLIST b/drivers/staging/tm6000/CARDLIST
new file mode 100644
index 000000000000..b5edce487997
--- /dev/null
+++ b/drivers/staging/tm6000/CARDLIST
@@ -0,0 +1,16 @@
1 1 -> Generic tm5600 board (tm5600) [6000:0001]
2 2 -> Generic tm6000 board (tm6000) [6000:0001]
3 3 -> Generic tm6010 board (tm6010) [6000:0002]
4 4 -> 10Moons UT821 (tm5600) [6000:0001]
5 5 -> 10Moons UT330 (tm5600)
6 6 -> ADSTech Dual TV (tm6000) [06e1:f332]
7 7 -> FreeCom and similar (tm6000) [14aa:0620]
8 8 -> ADSTech Mini Dual TV (tm6000) [06e1:b339]
9 9 -> Hauppauge WinTV HVR-900H/USB2 Stick (tm6010) [2040:6600,2040:6601,2040:6610,2040:6611]
10 10 -> Beholder Wander (tm6010) [6000:dec0]
11 11 -> Beholder Voyager (tm6010) [6000:dec1]
12 12 -> TerraTec Cinergy Hybrid XE/Cinergy Hybrid Stick (tm6010) [0ccd:0086,0ccd:00a5]
13 13 -> TwinHan TU501 (tm6010) [13d3:3240,13d3:3241,13d3:3243,13d3:3264]
14 14 -> Beholder Wander Lite (tm6010) [6000:dec2]
15 15 -> Beholder Voyager Lite (tm6010) [6000:dec3]
16
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index acb03172a887..2b96047c2983 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -84,7 +84,6 @@ static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
84 84
85 tm6000_set_audio_bitrate(core, 48000); 85 tm6000_set_audio_bitrate(core, 48000);
86 86
87 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0x80);
88 87
89 return 0; 88 return 0;
90} 89}
@@ -101,8 +100,6 @@ static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
101 /* Disables audio */ 100 /* Disables audio */
102 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40); 101 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40);
103 102
104 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0);
105
106 return 0; 103 return 0;
107} 104}
108 105
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 146c7e86deca..a69c82e11991 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -54,6 +54,11 @@
54#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15 54#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
55#define TM5600_BOARD_TERRATEC_GRABSTER 16 55#define TM5600_BOARD_TERRATEC_GRABSTER 16
56 56
57#define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \
58 (model == TM5600_BOARD_GENERIC) || \
59 (model == TM6000_BOARD_GENERIC) || \
60 (model == TM6010_BOARD_GENERIC))
61
57#define TM6000_MAXBOARDS 16 62#define TM6000_MAXBOARDS 16
58static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET }; 63static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
59 64
@@ -64,10 +69,11 @@ static unsigned long tm6000_devused;
64 69
65struct tm6000_board { 70struct tm6000_board {
66 char *name; 71 char *name;
72 char eename[16]; /* EEPROM name */
73 unsigned eename_size; /* size of EEPROM name */
74 unsigned eename_pos; /* Position where it appears at ROM */
67 75
68 struct tm6000_capabilities caps; 76 struct tm6000_capabilities caps;
69 enum tm6000_inaudio aradio;
70 enum tm6000_inaudio avideo;
71 77
72 enum tm6000_devtype type; /* variant of the chipset */ 78 enum tm6000_devtype type; /* variant of the chipset */
73 int tuner_type; /* type of the tuner */ 79 int tuner_type; /* type of the tuner */
@@ -76,6 +82,9 @@ struct tm6000_board {
76 82
77 struct tm6000_gpio gpio; 83 struct tm6000_gpio gpio;
78 84
85 struct tm6000_input vinput[3];
86 struct tm6000_input rinput;
87
79 char *ir_codes; 88 char *ir_codes;
80}; 89};
81 90
@@ -83,11 +92,26 @@ struct tm6000_board tm6000_boards[] = {
83 [TM6000_BOARD_UNKNOWN] = { 92 [TM6000_BOARD_UNKNOWN] = {
84 .name = "Unknown tm6000 video grabber", 93 .name = "Unknown tm6000 video grabber",
85 .caps = { 94 .caps = {
86 .has_tuner = 1, 95 .has_tuner = 1,
96 .has_eeprom = 1,
87 }, 97 },
88 .gpio = { 98 .gpio = {
89 .tuner_reset = TM6000_GPIO_1, 99 .tuner_reset = TM6000_GPIO_1,
90 }, 100 },
101 .vinput = { {
102 .type = TM6000_INPUT_TV,
103 .vmux = TM6000_VMUX_VIDEO_B,
104 .amux = TM6000_AMUX_ADC1,
105 }, {
106 .type = TM6000_INPUT_COMPOSITE1,
107 .vmux = TM6000_VMUX_VIDEO_A,
108 .amux = TM6000_AMUX_ADC2,
109 }, {
110 .type = TM6000_INPUT_SVIDEO,
111 .vmux = TM6000_VMUX_VIDEO_AB,
112 .amux = TM6000_AMUX_ADC2,
113 },
114 },
91 }, 115 },
92 [TM5600_BOARD_GENERIC] = { 116 [TM5600_BOARD_GENERIC] = {
93 .name = "Generic tm5600 board", 117 .name = "Generic tm5600 board",
@@ -96,10 +120,25 @@ struct tm6000_board tm6000_boards[] = {
96 .tuner_addr = 0xc2 >> 1, 120 .tuner_addr = 0xc2 >> 1,
97 .caps = { 121 .caps = {
98 .has_tuner = 1, 122 .has_tuner = 1,
123 .has_eeprom = 1,
99 }, 124 },
100 .gpio = { 125 .gpio = {
101 .tuner_reset = TM6000_GPIO_1, 126 .tuner_reset = TM6000_GPIO_1,
102 }, 127 },
128 .vinput = { {
129 .type = TM6000_INPUT_TV,
130 .vmux = TM6000_VMUX_VIDEO_B,
131 .amux = TM6000_AMUX_ADC1,
132 }, {
133 .type = TM6000_INPUT_COMPOSITE1,
134 .vmux = TM6000_VMUX_VIDEO_A,
135 .amux = TM6000_AMUX_ADC2,
136 }, {
137 .type = TM6000_INPUT_SVIDEO,
138 .vmux = TM6000_VMUX_VIDEO_AB,
139 .amux = TM6000_AMUX_ADC2,
140 },
141 },
103 }, 142 },
104 [TM6000_BOARD_GENERIC] = { 143 [TM6000_BOARD_GENERIC] = {
105 .name = "Generic tm6000 board", 144 .name = "Generic tm6000 board",
@@ -107,11 +146,25 @@ struct tm6000_board tm6000_boards[] = {
107 .tuner_addr = 0xc2 >> 1, 146 .tuner_addr = 0xc2 >> 1,
108 .caps = { 147 .caps = {
109 .has_tuner = 1, 148 .has_tuner = 1,
110 .has_dvb = 1, 149 .has_eeprom = 1,
111 }, 150 },
112 .gpio = { 151 .gpio = {
113 .tuner_reset = TM6000_GPIO_1, 152 .tuner_reset = TM6000_GPIO_1,
114 }, 153 },
154 .vinput = { {
155 .type = TM6000_INPUT_TV,
156 .vmux = TM6000_VMUX_VIDEO_B,
157 .amux = TM6000_AMUX_ADC1,
158 }, {
159 .type = TM6000_INPUT_COMPOSITE1,
160 .vmux = TM6000_VMUX_VIDEO_A,
161 .amux = TM6000_AMUX_ADC2,
162 }, {
163 .type = TM6000_INPUT_SVIDEO,
164 .vmux = TM6000_VMUX_VIDEO_AB,
165 .amux = TM6000_AMUX_ADC2,
166 },
167 },
115 }, 168 },
116 [TM6010_BOARD_GENERIC] = { 169 [TM6010_BOARD_GENERIC] = {
117 .name = "Generic tm6010 board", 170 .name = "Generic tm6010 board",
@@ -135,10 +188,27 @@ struct tm6000_board tm6000_boards[] = {
135 .dvb_led = TM6010_GPIO_5, 188 .dvb_led = TM6010_GPIO_5,
136 .ir = TM6010_GPIO_0, 189 .ir = TM6010_GPIO_0,
137 }, 190 },
191 .vinput = { {
192 .type = TM6000_INPUT_TV,
193 .vmux = TM6000_VMUX_VIDEO_B,
194 .amux = TM6000_AMUX_SIF1,
195 }, {
196 .type = TM6000_INPUT_COMPOSITE1,
197 .vmux = TM6000_VMUX_VIDEO_A,
198 .amux = TM6000_AMUX_ADC2,
199 }, {
200 .type = TM6000_INPUT_SVIDEO,
201 .vmux = TM6000_VMUX_VIDEO_AB,
202 .amux = TM6000_AMUX_ADC2,
203 },
204 },
138 }, 205 },
139 [TM5600_BOARD_10MOONS_UT821] = { 206 [TM5600_BOARD_10MOONS_UT821] = {
140 .name = "10Moons UT 821", 207 .name = "10Moons UT 821",
141 .tuner_type = TUNER_XC2028, 208 .tuner_type = TUNER_XC2028,
209 .eename = { '1', '0', 'M', 'O', 'O', 'N', 'S', '5', '6', '0', '0', 0xff, 0x45, 0x5b},
210 .eename_size = 14,
211 .eename_pos = 0x14,
142 .type = TM5600, 212 .type = TM5600,
143 .tuner_addr = 0xc2 >> 1, 213 .tuner_addr = 0xc2 >> 1,
144 .caps = { 214 .caps = {
@@ -148,6 +218,20 @@ struct tm6000_board tm6000_boards[] = {
148 .gpio = { 218 .gpio = {
149 .tuner_reset = TM6000_GPIO_1, 219 .tuner_reset = TM6000_GPIO_1,
150 }, 220 },
221 .vinput = { {
222 .type = TM6000_INPUT_TV,
223 .vmux = TM6000_VMUX_VIDEO_B,
224 .amux = TM6000_AMUX_ADC1,
225 }, {
226 .type = TM6000_INPUT_COMPOSITE1,
227 .vmux = TM6000_VMUX_VIDEO_A,
228 .amux = TM6000_AMUX_ADC2,
229 }, {
230 .type = TM6000_INPUT_SVIDEO,
231 .vmux = TM6000_VMUX_VIDEO_AB,
232 .amux = TM6000_AMUX_ADC2,
233 },
234 },
151 }, 235 },
152 [TM5600_BOARD_10MOONS_UT330] = { 236 [TM5600_BOARD_10MOONS_UT330] = {
153 .name = "10Moons UT 330", 237 .name = "10Moons UT 330",
@@ -159,6 +243,20 @@ struct tm6000_board tm6000_boards[] = {
159 .has_zl10353 = 0, 243 .has_zl10353 = 0,
160 .has_eeprom = 1, 244 .has_eeprom = 1,
161 }, 245 },
246 .vinput = { {
247 .type = TM6000_INPUT_TV,
248 .vmux = TM6000_VMUX_VIDEO_B,
249 .amux = TM6000_AMUX_ADC1,
250 }, {
251 .type = TM6000_INPUT_COMPOSITE1,
252 .vmux = TM6000_VMUX_VIDEO_A,
253 .amux = TM6000_AMUX_ADC2,
254 }, {
255 .type = TM6000_INPUT_SVIDEO,
256 .vmux = TM6000_VMUX_VIDEO_AB,
257 .amux = TM6000_AMUX_ADC2,
258 },
259 },
162 }, 260 },
163 [TM6000_BOARD_ADSTECH_DUAL_TV] = { 261 [TM6000_BOARD_ADSTECH_DUAL_TV] = {
164 .name = "ADSTECH Dual TV USB", 262 .name = "ADSTECH Dual TV USB",
@@ -171,6 +269,20 @@ struct tm6000_board tm6000_boards[] = {
171 .has_zl10353 = 1, 269 .has_zl10353 = 1,
172 .has_eeprom = 1, 270 .has_eeprom = 1,
173 }, 271 },
272 .vinput = { {
273 .type = TM6000_INPUT_TV,
274 .vmux = TM6000_VMUX_VIDEO_B,
275 .amux = TM6000_AMUX_ADC1,
276 }, {
277 .type = TM6000_INPUT_COMPOSITE1,
278 .vmux = TM6000_VMUX_VIDEO_A,
279 .amux = TM6000_AMUX_ADC2,
280 }, {
281 .type = TM6000_INPUT_SVIDEO,
282 .vmux = TM6000_VMUX_VIDEO_AB,
283 .amux = TM6000_AMUX_ADC2,
284 },
285 },
174 }, 286 },
175 [TM6000_BOARD_FREECOM_AND_SIMILAR] = { 287 [TM6000_BOARD_FREECOM_AND_SIMILAR] = {
176 .name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual", 288 .name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
@@ -187,6 +299,20 @@ struct tm6000_board tm6000_boards[] = {
187 .gpio = { 299 .gpio = {
188 .tuner_reset = TM6000_GPIO_4, 300 .tuner_reset = TM6000_GPIO_4,
189 }, 301 },
302 .vinput = { {
303 .type = TM6000_INPUT_TV,
304 .vmux = TM6000_VMUX_VIDEO_B,
305 .amux = TM6000_AMUX_ADC1,
306 }, {
307 .type = TM6000_INPUT_COMPOSITE1,
308 .vmux = TM6000_VMUX_VIDEO_A,
309 .amux = TM6000_AMUX_ADC2,
310 }, {
311 .type = TM6000_INPUT_SVIDEO,
312 .vmux = TM6000_VMUX_VIDEO_AB,
313 .amux = TM6000_AMUX_ADC2,
314 },
315 },
190 }, 316 },
191 [TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = { 317 [TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = {
192 .name = "ADSTECH Mini Dual TV USB", 318 .name = "ADSTECH Mini Dual TV USB",
@@ -202,9 +328,26 @@ struct tm6000_board tm6000_boards[] = {
202 .gpio = { 328 .gpio = {
203 .tuner_reset = TM6000_GPIO_4, 329 .tuner_reset = TM6000_GPIO_4,
204 }, 330 },
331 .vinput = { {
332 .type = TM6000_INPUT_TV,
333 .vmux = TM6000_VMUX_VIDEO_B,
334 .amux = TM6000_AMUX_ADC1,
335 }, {
336 .type = TM6000_INPUT_COMPOSITE1,
337 .vmux = TM6000_VMUX_VIDEO_A,
338 .amux = TM6000_AMUX_ADC2,
339 }, {
340 .type = TM6000_INPUT_SVIDEO,
341 .vmux = TM6000_VMUX_VIDEO_AB,
342 .amux = TM6000_AMUX_ADC2,
343 },
344 },
205 }, 345 },
206 [TM6010_BOARD_HAUPPAUGE_900H] = { 346 [TM6010_BOARD_HAUPPAUGE_900H] = {
207 .name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick", 347 .name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
348 .eename = { 'H', 0, 'V', 0, 'R', 0, '9', 0, '0', 0, '0', 0, 'H', 0 },
349 .eename_size = 14,
350 .eename_pos = 0x42,
208 .tuner_type = TUNER_XC2028, /* has a XC3028 */ 351 .tuner_type = TUNER_XC2028, /* has a XC3028 */
209 .tuner_addr = 0xc2 >> 1, 352 .tuner_addr = 0xc2 >> 1,
210 .demod_addr = 0x1e >> 1, 353 .demod_addr = 0x1e >> 1,
@@ -225,6 +368,20 @@ struct tm6000_board tm6000_boards[] = {
225 .dvb_led = TM6010_GPIO_5, 368 .dvb_led = TM6010_GPIO_5,
226 .ir = TM6010_GPIO_0, 369 .ir = TM6010_GPIO_0,
227 }, 370 },
371 .vinput = { {
372 .type = TM6000_INPUT_TV,
373 .vmux = TM6000_VMUX_VIDEO_B,
374 .amux = TM6000_AMUX_SIF1,
375 }, {
376 .type = TM6000_INPUT_COMPOSITE1,
377 .vmux = TM6000_VMUX_VIDEO_A,
378 .amux = TM6000_AMUX_ADC2,
379 }, {
380 .type = TM6000_INPUT_SVIDEO,
381 .vmux = TM6000_VMUX_VIDEO_AB,
382 .amux = TM6000_AMUX_ADC2,
383 },
384 },
228 }, 385 },
229 [TM6010_BOARD_BEHOLD_WANDER] = { 386 [TM6010_BOARD_BEHOLD_WANDER] = {
230 .name = "Beholder Wander DVB-T/TV/FM USB2.0", 387 .name = "Beholder Wander DVB-T/TV/FM USB2.0",
@@ -232,43 +389,73 @@ struct tm6000_board tm6000_boards[] = {
232 .tuner_addr = 0xc2 >> 1, 389 .tuner_addr = 0xc2 >> 1,
233 .demod_addr = 0x1e >> 1, 390 .demod_addr = 0x1e >> 1,
234 .type = TM6010, 391 .type = TM6010,
235 .avideo = TM6000_AIP_SIF1,
236 .aradio = TM6000_AIP_LINE1,
237 .caps = { 392 .caps = {
238 .has_tuner = 1, 393 .has_tuner = 1,
239 .has_dvb = 1, 394 .has_dvb = 1,
240 .has_zl10353 = 1, 395 .has_zl10353 = 1,
241 .has_eeprom = 1, 396 .has_eeprom = 1,
242 .has_remote = 1, 397 .has_remote = 1,
243 .has_input_comp = 1, 398 .has_radio = 1.
244 .has_input_svid = 1,
245 }, 399 },
246 .gpio = { 400 .gpio = {
247 .tuner_reset = TM6010_GPIO_0, 401 .tuner_reset = TM6010_GPIO_0,
248 .demod_reset = TM6010_GPIO_1, 402 .demod_reset = TM6010_GPIO_1,
249 .power_led = TM6010_GPIO_6, 403 .power_led = TM6010_GPIO_6,
250 }, 404 },
405 .vinput = { {
406 .type = TM6000_INPUT_TV,
407 .vmux = TM6000_VMUX_VIDEO_B,
408 .amux = TM6000_AMUX_SIF1,
409 }, {
410 .type = TM6000_INPUT_COMPOSITE1,
411 .vmux = TM6000_VMUX_VIDEO_A,
412 .amux = TM6000_AMUX_ADC2,
413 }, {
414 .type = TM6000_INPUT_SVIDEO,
415 .vmux = TM6000_VMUX_VIDEO_AB,
416 .amux = TM6000_AMUX_ADC2,
417 },
418 },
419 .rinput = {
420 .type = TM6000_INPUT_RADIO,
421 .amux = TM6000_AMUX_ADC1,
422 },
251 }, 423 },
252 [TM6010_BOARD_BEHOLD_VOYAGER] = { 424 [TM6010_BOARD_BEHOLD_VOYAGER] = {
253 .name = "Beholder Voyager TV/FM USB2.0", 425 .name = "Beholder Voyager TV/FM USB2.0",
254 .tuner_type = TUNER_XC5000, 426 .tuner_type = TUNER_XC5000,
255 .tuner_addr = 0xc2 >> 1, 427 .tuner_addr = 0xc2 >> 1,
256 .type = TM6010, 428 .type = TM6010,
257 .avideo = TM6000_AIP_SIF1,
258 .aradio = TM6000_AIP_LINE1,
259 .caps = { 429 .caps = {
260 .has_tuner = 1, 430 .has_tuner = 1,
261 .has_dvb = 0, 431 .has_dvb = 0,
262 .has_zl10353 = 0, 432 .has_zl10353 = 0,
263 .has_eeprom = 1, 433 .has_eeprom = 1,
264 .has_remote = 1, 434 .has_remote = 1,
265 .has_input_comp = 1, 435 .has_radio = 1,
266 .has_input_svid = 1,
267 }, 436 },
268 .gpio = { 437 .gpio = {
269 .tuner_reset = TM6010_GPIO_0, 438 .tuner_reset = TM6010_GPIO_0,
270 .power_led = TM6010_GPIO_6, 439 .power_led = TM6010_GPIO_6,
271 }, 440 },
441 .vinput = { {
442 .type = TM6000_INPUT_TV,
443 .vmux = TM6000_VMUX_VIDEO_B,
444 .amux = TM6000_AMUX_SIF1,
445 }, {
446 .type = TM6000_INPUT_COMPOSITE1,
447 .vmux = TM6000_VMUX_VIDEO_A,
448 .amux = TM6000_AMUX_ADC2,
449 }, {
450 .type = TM6000_INPUT_SVIDEO,
451 .vmux = TM6000_VMUX_VIDEO_AB,
452 .amux = TM6000_AMUX_ADC2,
453 },
454 },
455 .rinput = {
456 .type = TM6000_INPUT_RADIO,
457 .amux = TM6000_AMUX_ADC1,
458 },
272 }, 459 },
273 [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = { 460 [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
274 .name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick", 461 .name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
@@ -293,11 +480,39 @@ struct tm6000_board tm6000_boards[] = {
293 .ir = TM6010_GPIO_0, 480 .ir = TM6010_GPIO_0,
294 }, 481 },
295 .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, 482 .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
483 .vinput = { {
484 .type = TM6000_INPUT_TV,
485 .vmux = TM6000_VMUX_VIDEO_B,
486 .amux = TM6000_AMUX_SIF1,
487 }, {
488 .type = TM6000_INPUT_COMPOSITE1,
489 .vmux = TM6000_VMUX_VIDEO_A,
490 .amux = TM6000_AMUX_ADC2,
491 }, {
492 .type = TM6000_INPUT_SVIDEO,
493 .vmux = TM6000_VMUX_VIDEO_AB,
494 .amux = TM6000_AMUX_ADC2,
495 },
496 },
296 }, 497 },
297 [TM5600_BOARD_TERRATEC_GRABSTER] = { 498 [TM5600_BOARD_TERRATEC_GRABSTER] = {
298 .name = "Terratec Grabster AV 150/250 MX", 499 .name = "Terratec Grabster AV 150/250 MX",
299 .type = TM5600, 500 .type = TM5600,
300 .tuner_type = TUNER_ABSENT, 501 .tuner_type = TUNER_ABSENT,
502 .vinput = { {
503 .type = TM6000_INPUT_TV,
504 .vmux = TM6000_VMUX_VIDEO_B,
505 .amux = TM6000_AMUX_ADC1,
506 }, {
507 .type = TM6000_INPUT_COMPOSITE1,
508 .vmux = TM6000_VMUX_VIDEO_A,
509 .amux = TM6000_AMUX_ADC2,
510 }, {
511 .type = TM6000_INPUT_SVIDEO,
512 .vmux = TM6000_VMUX_VIDEO_AB,
513 .amux = TM6000_AMUX_ADC2,
514 },
515 },
301 }, 516 },
302 [TM6010_BOARD_TWINHAN_TU501] = { 517 [TM6010_BOARD_TWINHAN_TU501] = {
303 .name = "Twinhan TU501(704D1)", 518 .name = "Twinhan TU501(704D1)",
@@ -321,6 +536,20 @@ struct tm6000_board tm6000_boards[] = {
321 .dvb_led = TM6010_GPIO_5, 536 .dvb_led = TM6010_GPIO_5,
322 .ir = TM6010_GPIO_0, 537 .ir = TM6010_GPIO_0,
323 }, 538 },
539 .vinput = { {
540 .type = TM6000_INPUT_TV,
541 .vmux = TM6000_VMUX_VIDEO_B,
542 .amux = TM6000_AMUX_SIF1,
543 }, {
544 .type = TM6000_INPUT_COMPOSITE1,
545 .vmux = TM6000_VMUX_VIDEO_A,
546 .amux = TM6000_AMUX_ADC2,
547 }, {
548 .type = TM6000_INPUT_SVIDEO,
549 .vmux = TM6000_VMUX_VIDEO_AB,
550 .amux = TM6000_AMUX_ADC2,
551 },
552 },
324 }, 553 },
325 [TM6010_BOARD_BEHOLD_WANDER_LITE] = { 554 [TM6010_BOARD_BEHOLD_WANDER_LITE] = {
326 .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0", 555 .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
@@ -328,49 +557,63 @@ struct tm6000_board tm6000_boards[] = {
328 .tuner_addr = 0xc2 >> 1, 557 .tuner_addr = 0xc2 >> 1,
329 .demod_addr = 0x1e >> 1, 558 .demod_addr = 0x1e >> 1,
330 .type = TM6010, 559 .type = TM6010,
331 .avideo = TM6000_AIP_SIF1,
332 .aradio = TM6000_AIP_LINE1,
333 .caps = { 560 .caps = {
334 .has_tuner = 1, 561 .has_tuner = 1,
335 .has_dvb = 1, 562 .has_dvb = 1,
336 .has_zl10353 = 1, 563 .has_zl10353 = 1,
337 .has_eeprom = 1, 564 .has_eeprom = 1,
338 .has_remote = 0, 565 .has_remote = 0,
339 .has_input_comp = 0, 566 .has_radio = 1,
340 .has_input_svid = 0,
341 }, 567 },
342 .gpio = { 568 .gpio = {
343 .tuner_reset = TM6010_GPIO_0, 569 .tuner_reset = TM6010_GPIO_0,
344 .demod_reset = TM6010_GPIO_1, 570 .demod_reset = TM6010_GPIO_1,
345 .power_led = TM6010_GPIO_6, 571 .power_led = TM6010_GPIO_6,
346 }, 572 },
573 .vinput = { {
574 .type = TM6000_INPUT_TV,
575 .vmux = TM6000_VMUX_VIDEO_B,
576 .amux = TM6000_AMUX_SIF1,
577 },
578 },
579 .rinput = {
580 .type = TM6000_INPUT_RADIO,
581 .amux = TM6000_AMUX_ADC1,
582 },
347 }, 583 },
348 [TM6010_BOARD_BEHOLD_VOYAGER_LITE] = { 584 [TM6010_BOARD_BEHOLD_VOYAGER_LITE] = {
349 .name = "Beholder Voyager Lite TV/FM USB2.0", 585 .name = "Beholder Voyager Lite TV/FM USB2.0",
350 .tuner_type = TUNER_XC5000, 586 .tuner_type = TUNER_XC5000,
351 .tuner_addr = 0xc2 >> 1, 587 .tuner_addr = 0xc2 >> 1,
352 .type = TM6010, 588 .type = TM6010,
353 .avideo = TM6000_AIP_SIF1,
354 .aradio = TM6000_AIP_LINE1,
355 .caps = { 589 .caps = {
356 .has_tuner = 1, 590 .has_tuner = 1,
357 .has_dvb = 0, 591 .has_dvb = 0,
358 .has_zl10353 = 0, 592 .has_zl10353 = 0,
359 .has_eeprom = 1, 593 .has_eeprom = 1,
360 .has_remote = 0, 594 .has_remote = 0,
361 .has_input_comp = 0, 595 .has_radio = 1,
362 .has_input_svid = 0,
363 }, 596 },
364 .gpio = { 597 .gpio = {
365 .tuner_reset = TM6010_GPIO_0, 598 .tuner_reset = TM6010_GPIO_0,
366 .power_led = TM6010_GPIO_6, 599 .power_led = TM6010_GPIO_6,
367 }, 600 },
601 .vinput = { {
602 .type = TM6000_INPUT_TV,
603 .vmux = TM6000_VMUX_VIDEO_B,
604 .amux = TM6000_AMUX_SIF1,
605 },
606 },
607 .rinput = {
608 .type = TM6000_INPUT_RADIO,
609 .amux = TM6000_AMUX_ADC1,
610 },
368 }, 611 },
369}; 612};
370 613
371/* table of devices that work with this driver */ 614/* table of devices that work with this driver */
372struct usb_device_id tm6000_id_table[] = { 615struct usb_device_id tm6000_id_table[] = {
373 { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_10MOONS_UT821 }, 616 { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC },
374 { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC }, 617 { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
375 { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV }, 618 { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
376 { USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR }, 619 { USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR },
@@ -679,12 +922,8 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
679 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg)); 922 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
680 memset(&ctl, 0, sizeof(ctl)); 923 memset(&ctl, 0, sizeof(ctl));
681 924
682 ctl.input1 = 1;
683 ctl.read_not_reliable = 0;
684 ctl.msleep = 10;
685 ctl.demod = XC3028_FE_ZARLINK456; 925 ctl.demod = XC3028_FE_ZARLINK456;
686 ctl.vhfbw7 = 1; 926
687 ctl.uhfbw8 = 1;
688 xc2028_cfg.tuner = TUNER_XC2028; 927 xc2028_cfg.tuner = TUNER_XC2028;
689 xc2028_cfg.priv = &ctl; 928 xc2028_cfg.priv = &ctl;
690 929
@@ -729,16 +968,10 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
729 } 968 }
730} 969}
731 970
732static int tm6000_init_dev(struct tm6000_core *dev) 971static int fill_board_specific_data(struct tm6000_core *dev)
733{ 972{
734 struct v4l2_frequency f; 973 int rc;
735 int rc = 0;
736
737 mutex_init(&dev->lock);
738
739 mutex_lock(&dev->lock);
740 974
741 /* Initializa board-specific data */
742 dev->dev_type = tm6000_boards[dev->model].type; 975 dev->dev_type = tm6000_boards[dev->model].type;
743 dev->tuner_type = tm6000_boards[dev->model].tuner_type; 976 dev->tuner_type = tm6000_boards[dev->model].tuner_type;
744 dev->tuner_addr = tm6000_boards[dev->model].tuner_addr; 977 dev->tuner_addr = tm6000_boards[dev->model].tuner_addr;
@@ -751,21 +984,85 @@ static int tm6000_init_dev(struct tm6000_core *dev)
751 984
752 dev->caps = tm6000_boards[dev->model].caps; 985 dev->caps = tm6000_boards[dev->model].caps;
753 986
754 dev->avideo = tm6000_boards[dev->model].avideo; 987 dev->vinput[0] = tm6000_boards[dev->model].vinput[0];
755 dev->aradio = tm6000_boards[dev->model].aradio; 988 dev->vinput[1] = tm6000_boards[dev->model].vinput[1];
989 dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
990 dev->rinput = tm6000_boards[dev->model].rinput;
991
756 /* initialize hardware */ 992 /* initialize hardware */
757 rc = tm6000_init(dev); 993 rc = tm6000_init(dev);
758 if (rc < 0) 994 if (rc < 0)
759 goto err; 995 return rc;
760 996
761 rc = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); 997 rc = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
762 if (rc < 0) 998 if (rc < 0)
763 goto err; 999 return rc;
764 1000
765 /* register i2c bus */ 1001 return rc;
766 rc = tm6000_i2c_register(dev); 1002}
767 if (rc < 0) 1003
768 goto err; 1004
1005static void use_alternative_detection_method(struct tm6000_core *dev)
1006{
1007 int i, model = -1;
1008
1009 if (!dev->eedata_size)
1010 return;
1011
1012 for (i = 0; i < ARRAY_SIZE(tm6000_boards); i++) {
1013 if (!tm6000_boards[i].eename_size)
1014 continue;
1015 if (dev->eedata_size < tm6000_boards[i].eename_pos +
1016 tm6000_boards[i].eename_size)
1017 continue;
1018
1019 if (!memcmp(&dev->eedata[tm6000_boards[i].eename_pos],
1020 tm6000_boards[i].eename,
1021 tm6000_boards[i].eename_size)) {
1022 model = i;
1023 break;
1024 }
1025 }
1026 if (model < 0) {
1027 printk(KERN_INFO "Device has eeprom but is currently unknown\n");
1028 return;
1029 }
1030
1031 dev->model = model;
1032
1033 printk(KERN_INFO "Device identified via eeprom as %s (type = %d)\n",
1034 tm6000_boards[model].name, model);
1035}
1036
1037static int tm6000_init_dev(struct tm6000_core *dev)
1038{
1039 struct v4l2_frequency f;
1040 int rc = 0;
1041
1042 mutex_init(&dev->lock);
1043 mutex_lock(&dev->lock);
1044
1045 if (!is_generic(dev->model)) {
1046 rc = fill_board_specific_data(dev);
1047 if (rc < 0)
1048 goto err;
1049
1050 /* register i2c bus */
1051 rc = tm6000_i2c_register(dev);
1052 if (rc < 0)
1053 goto err;
1054 } else {
1055 /* register i2c bus */
1056 rc = tm6000_i2c_register(dev);
1057 if (rc < 0)
1058 goto err;
1059
1060 use_alternative_detection_method(dev);
1061
1062 rc = fill_board_specific_data(dev);
1063 if (rc < 0)
1064 goto err;
1065 }
769 1066
770 /* Default values for STD and resolutions */ 1067 /* Default values for STD and resolutions */
771 dev->width = 720; 1068 dev->width = 720;
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 778e53413afb..d7eb2e23cdbd 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -268,19 +268,18 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
268 struct v4l2_frequency f; 268 struct v4l2_frequency f;
269 269
270 if (dev->dev_type == TM6010) { 270 if (dev->dev_type == TM6010) {
271 /* Enable video */ 271 /* Enable video and audio */
272
273 tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 272 tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
274 0x60, 0x60); 273 0x60, 0x60);
274 /* Disable TS input */
275 tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 275 tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
276 0x00, 0x40); 276 0x00, 0x40);
277 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
278
279 } else { 277 } else {
280 /* Enables soft reset */ 278 /* Enables soft reset */
281 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); 279 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
282 280
283 if (dev->scaler) 281 if (dev->scaler)
282 /* Disable Hfilter and Enable TS Drop err */
284 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20); 283 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
285 else /* Enable Hfilter and disable TS Drop err */ 284 else /* Enable Hfilter and disable TS Drop err */
286 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80); 285 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
@@ -300,14 +299,6 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
300 299
301 /* Disables soft reset */ 300 /* Disables soft reset */
302 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); 301 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
303
304 /* E3: Select input 0 - TV tuner */
305 tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
306 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x60);
307
308 /* This controls input */
309 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0);
310 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_3, 0x01);
311 } 302 }
312 msleep(20); 303 msleep(20);
313 304
@@ -327,7 +318,7 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
327 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); 318 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
328 319
329 msleep(100); 320 msleep(100);
330 tm6000_set_standard(dev, &dev->norm); 321 tm6000_set_standard(dev);
331 tm6000_set_vbi(dev); 322 tm6000_set_vbi(dev);
332 tm6000_set_audio_bitrate(dev, 48000); 323 tm6000_set_audio_bitrate(dev, 48000);
333 324
@@ -343,21 +334,16 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
343int tm6000_init_digital_mode(struct tm6000_core *dev) 334int tm6000_init_digital_mode(struct tm6000_core *dev)
344{ 335{
345 if (dev->dev_type == TM6010) { 336 if (dev->dev_type == TM6010) {
346 int val; 337 /* Disable video and audio */
347 u8 buf[2]; 338 tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
348 339 0x00, 0x60);
349 /* digital init */ 340 /* Enable TS input */
350 val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0); 341 tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
351 val &= ~0x60; 342 0x40, 0x40);
352 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val); 343 /* all power down, but not the digital data port */
353 val = tm6000_get_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0);
354 val |= 0x40;
355 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val);
356 tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28); 344 tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28);
357 tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc); 345 tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc);
358 tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff); 346 tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff);
359 tm6000_read_write_usb(dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
360 printk(KERN_INFO"buf %#x %#x\n", buf[0], buf[1]);
361 } else { 347 } else {
362 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); 348 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
363 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00); 349 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
@@ -489,14 +475,6 @@ struct reg_init tm6010_init_tab[] = {
489 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 }, 475 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 },
490 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 }, 476 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 },
491 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 }, 477 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 },
492 { TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00},
493 { TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80},
494 { TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a},
495 { TM6010_REQ08_R0D_A_AMD_THRES, 0x40},
496 { TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64},
497 { TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20},
498 { TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe},
499 { TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01},
500 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc }, 478 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc },
501 479
502 { TM6010_REQ07_R3F_RESET, 0x01 }, 480 { TM6010_REQ07_R3F_RESET, 0x01 },
@@ -657,24 +635,29 @@ int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
657} 635}
658EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); 636EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
659 637
660int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp) 638int tm6000_set_audio_rinput(struct tm6000_core *dev)
661{ 639{
662 if (dev->dev_type == TM6010) { 640 if (dev->dev_type == TM6010) {
663 /* Audio crossbar setting, default SIF1 */ 641 /* Audio crossbar setting, default SIF1 */
664 u8 areg_f0 = 0x03; 642 u8 areg_f0;
665 643
666 switch (ainp) { 644 switch (dev->rinput.amux) {
667 case TM6000_AIP_SIF1: 645 case TM6000_AMUX_SIF1:
668 case TM6000_AIP_SIF2: 646 case TM6000_AMUX_SIF2:
669 areg_f0 = 0x03; 647 areg_f0 = 0x03;
670 break; 648 break;
671 case TM6000_AIP_LINE1: 649 case TM6000_AMUX_ADC1:
672 areg_f0 = 0x00; 650 areg_f0 = 0x00;
673 break; 651 break;
674 case TM6000_AIP_LINE2: 652 case TM6000_AMUX_ADC2:
675 areg_f0 = 0x08; 653 areg_f0 = 0x08;
676 break; 654 break;
655 case TM6000_AMUX_I2S:
656 areg_f0 = 0x04;
657 break;
677 default: 658 default:
659 printk(KERN_INFO "%s: audio input dosn't support\n",
660 dev->name);
678 return 0; 661 return 0;
679 break; 662 break;
680 } 663 }
@@ -682,17 +665,18 @@ int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp)
682 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 665 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
683 areg_f0, 0x0f); 666 areg_f0, 0x0f);
684 } else { 667 } else {
668 u8 areg_eb;
685 /* Audio setting, default LINE1 */ 669 /* Audio setting, default LINE1 */
686 u8 areg_eb = 0x00; 670 switch (dev->rinput.amux) {
687 671 case TM6000_AMUX_ADC1:
688 switch (ainp) {
689 case TM6000_AIP_LINE1:
690 areg_eb = 0x00; 672 areg_eb = 0x00;
691 break; 673 break;
692 case TM6000_AIP_LINE2: 674 case TM6000_AMUX_ADC2:
693 areg_eb = 0x04; 675 areg_eb = 0x04;
694 break; 676 break;
695 default: 677 default:
678 printk(KERN_INFO "%s: audio input dosn't support\n",
679 dev->name);
696 return 0; 680 return 0;
697 break; 681 break;
698 } 682 }
@@ -702,7 +686,6 @@ int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp)
702 } 686 }
703 return 0; 687 return 0;
704} 688}
705EXPORT_SYMBOL_GPL(tm6000_set_audio_input);
706 689
707void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute) 690void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
708{ 691{
@@ -736,16 +719,16 @@ void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute)
736 719
737int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute) 720int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
738{ 721{
739 enum tm6000_inaudio ainp; 722 enum tm6000_mux mux;
740 723
741 if (dev->radio) 724 if (dev->radio)
742 ainp = dev->aradio; 725 mux = dev->rinput.amux;
743 else 726 else
744 ainp = dev->avideo; 727 mux = dev->vinput[dev->input].amux;
745 728
746 switch (ainp) { 729 switch (mux) {
747 case TM6000_AIP_SIF1: 730 case TM6000_AMUX_SIF1:
748 case TM6000_AIP_SIF2: 731 case TM6000_AMUX_SIF2:
749 if (dev->dev_type == TM6010) 732 if (dev->dev_type == TM6010)
750 tm6010_set_mute_sif(dev, mute); 733 tm6010_set_mute_sif(dev, mute);
751 else { 734 else {
@@ -755,8 +738,8 @@ int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
755 return -EINVAL; 738 return -EINVAL;
756 } 739 }
757 break; 740 break;
758 case TM6000_AIP_LINE1: 741 case TM6000_AMUX_ADC1:
759 case TM6000_AIP_LINE2: 742 case TM6000_AMUX_ADC2:
760 tm6010_set_mute_adc(dev, mute); 743 tm6010_set_mute_adc(dev, mute);
761 break; 744 break;
762 default: 745 default:
@@ -765,7 +748,6 @@ int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
765 } 748 }
766 return 0; 749 return 0;
767} 750}
768EXPORT_SYMBOL_GPL(tm6000_tvaudio_set_mute);
769 751
770void tm6010_set_volume_sif(struct tm6000_core *dev, int vol) 752void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
771{ 753{
@@ -797,17 +779,17 @@ void tm6010_set_volume_adc(struct tm6000_core *dev, int vol)
797 779
798void tm6000_set_volume(struct tm6000_core *dev, int vol) 780void tm6000_set_volume(struct tm6000_core *dev, int vol)
799{ 781{
800 enum tm6000_inaudio ainp; 782 enum tm6000_mux mux;
801 783
802 if (dev->radio) { 784 if (dev->radio) {
803 ainp = dev->aradio; 785 mux = dev->rinput.amux;
804 vol += 8; /* Offset to 0 dB */ 786 vol += 8; /* Offset to 0 dB */
805 } else 787 } else
806 ainp = dev->avideo; 788 mux = dev->vinput[dev->input].amux;
807 789
808 switch (ainp) { 790 switch (mux) {
809 case TM6000_AIP_SIF1: 791 case TM6000_AMUX_SIF1:
810 case TM6000_AIP_SIF2: 792 case TM6000_AMUX_SIF2:
811 if (dev->dev_type == TM6010) 793 if (dev->dev_type == TM6010)
812 tm6010_set_volume_sif(dev, vol); 794 tm6010_set_volume_sif(dev, vol);
813 else 795 else
@@ -815,15 +797,14 @@ void tm6000_set_volume(struct tm6000_core *dev, int vol)
815 " SIF audio inputs. Please check the %s" 797 " SIF audio inputs. Please check the %s"
816 " configuration.\n", dev->name); 798 " configuration.\n", dev->name);
817 break; 799 break;
818 case TM6000_AIP_LINE1: 800 case TM6000_AMUX_ADC1:
819 case TM6000_AIP_LINE2: 801 case TM6000_AMUX_ADC2:
820 tm6010_set_volume_adc(dev, vol); 802 tm6010_set_volume_adc(dev, vol);
821 break; 803 break;
822 default: 804 default:
823 break; 805 break;
824 } 806 }
825} 807}
826EXPORT_SYMBOL_GPL(tm6000_set_volume);
827 808
828static LIST_HEAD(tm6000_devlist); 809static LIST_HEAD(tm6000_devlist);
829static DEFINE_MUTEX(tm6000_devlist_mutex); 810static DEFINE_MUTEX(tm6000_devlist_mutex);
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 18de4748f27e..8828c120b5ca 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -237,35 +237,36 @@ err:
237 return rc; 237 return rc;
238} 238}
239 239
240static int tm6000_i2c_eeprom(struct tm6000_core *dev, 240static int tm6000_i2c_eeprom(struct tm6000_core *dev)
241 unsigned char *eedata, int len)
242{ 241{
243 int i, rc; 242 int i, rc;
244 unsigned char *p = eedata; 243 unsigned char *p = dev->eedata;
245 unsigned char bytes[17]; 244 unsigned char bytes[17];
246 245
247 dev->i2c_client.addr = 0xa0 >> 1; 246 dev->i2c_client.addr = 0xa0 >> 1;
247 dev->eedata_size = 0;
248 248
249 bytes[16] = '\0'; 249 bytes[16] = '\0';
250 for (i = 0; i < len; ) { 250 for (i = 0; i < sizeof(dev->eedata); ) {
251 *p = i; 251 *p = i;
252 rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1); 252 rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1);
253 if (rc < 1) { 253 if (rc < 1) {
254 if (p == eedata) 254 if (p == dev->eedata)
255 goto noeeprom; 255 goto noeeprom;
256 else { 256 else {
257 printk(KERN_WARNING 257 printk(KERN_WARNING
258 "%s: i2c eeprom read error (err=%d)\n", 258 "%s: i2c eeprom read error (err=%d)\n",
259 dev->name, rc); 259 dev->name, rc);
260 } 260 }
261 return -1; 261 return -EINVAL;
262 } 262 }
263 dev->eedata_size++;
263 p++; 264 p++;
264 if (0 == (i % 16)) 265 if (0 == (i % 16))
265 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); 266 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
266 printk(" %02x", eedata[i]); 267 printk(" %02x", dev->eedata[i]);
267 if ((eedata[i] >= ' ') && (eedata[i] <= 'z')) 268 if ((dev->eedata[i] >= ' ') && (dev->eedata[i] <= 'z'))
268 bytes[i%16] = eedata[i]; 269 bytes[i%16] = dev->eedata[i];
269 else 270 else
270 bytes[i%16] = '.'; 271 bytes[i%16] = '.';
271 272
@@ -280,15 +281,15 @@ static int tm6000_i2c_eeprom(struct tm6000_core *dev,
280 bytes[i%16] = '\0'; 281 bytes[i%16] = '\0';
281 for (i %= 16; i < 16; i++) 282 for (i %= 16; i < 16; i++)
282 printk(" "); 283 printk(" ");
284 printk(" %s\n", bytes);
283 } 285 }
284 printk(" %s\n", bytes);
285 286
286 return 0; 287 return 0;
287 288
288noeeprom: 289noeeprom:
289 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", 290 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
290 dev->name, rc); 291 dev->name, rc);
291 return rc; 292 return -EINVAL;
292} 293}
293 294
294/* ----------------------------------------------------------- */ 295/* ----------------------------------------------------------- */
@@ -314,7 +315,6 @@ static const struct i2c_algorithm tm6000_algo = {
314 */ 315 */
315int tm6000_i2c_register(struct tm6000_core *dev) 316int tm6000_i2c_register(struct tm6000_core *dev)
316{ 317{
317 unsigned char eedata[256];
318 int rc; 318 int rc;
319 319
320 dev->i2c_adap.owner = THIS_MODULE; 320 dev->i2c_adap.owner = THIS_MODULE;
@@ -329,8 +329,7 @@ int tm6000_i2c_register(struct tm6000_core *dev)
329 329
330 dev->i2c_client.adapter = &dev->i2c_adap; 330 dev->i2c_client.adapter = &dev->i2c_adap;
331 strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE); 331 strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
332 332 tm6000_i2c_eeprom(dev);
333 tm6000_i2c_eeprom(dev, eedata, sizeof(eedata));
334 333
335 return 0; 334 return 0;
336} 335}
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index da3e51bde109..8b29d732ddcb 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -22,422 +22,26 @@
22#include "tm6000.h" 22#include "tm6000.h"
23#include "tm6000-regs.h" 23#include "tm6000-regs.h"
24 24
25static unsigned int tm6010_a_mode = 0;
26module_param(tm6010_a_mode, int, 0644);
27MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode");
28
25struct tm6000_reg_settings { 29struct tm6000_reg_settings {
26 unsigned char req; 30 unsigned char req;
27 unsigned char reg; 31 unsigned char reg;
28 unsigned char value; 32 unsigned char value;
29}; 33};
30 34
31enum tm6000_audio_std {
32 BG_NICAM,
33 BTSC,
34 BG_A2,
35 DK_NICAM,
36 EIAJ,
37 FM_RADIO,
38 I_NICAM,
39 KOREA_A2,
40 L_NICAM,
41};
42
43struct tm6000_std_tv_settings {
44 v4l2_std_id id;
45 enum tm6000_audio_std audio_default_std;
46
47 struct tm6000_reg_settings sif[12];
48 struct tm6000_reg_settings nosif[12];
49 struct tm6000_reg_settings common[26];
50};
51 35
52struct tm6000_std_settings { 36struct tm6000_std_settings {
53 v4l2_std_id id; 37 v4l2_std_id id;
54 enum tm6000_audio_std audio_default_std; 38 struct tm6000_reg_settings common[27];
55 struct tm6000_reg_settings common[37];
56};
57
58static struct tm6000_std_tv_settings tv_stds[] = {
59 {
60 .id = V4L2_STD_PAL_M,
61 .audio_default_std = BTSC,
62 .sif = {
63 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
64 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
65 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
66 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
67 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
68 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
69 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
70 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
71 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
72 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
73 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
74 {0, 0, 0},
75 },
76 .nosif = {
77 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
78 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
79 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
80 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
81 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
82 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
83 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
84 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
85 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
86 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
87 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
88 {0, 0, 0},
89 },
90 .common = {
91 {TM6010_REQ07_R3F_RESET, 0x01},
92 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
93 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
94 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
95 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
96 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
97 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
98 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
99 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
100 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
101 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
102 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
103 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
104 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
105 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
106 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20},
107 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
108 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
109 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
110 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
111 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
112
113 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
114 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
115
116 {TM6010_REQ07_R3F_RESET, 0x00},
117
118 {0, 0, 0},
119 },
120 }, {
121 .id = V4L2_STD_PAL_Nc,
122 .audio_default_std = BTSC,
123 .sif = {
124 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
125 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
126 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
127 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
128 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
129 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
130 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
131 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
132 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
133 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
134 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
135 {0, 0, 0},
136 },
137 .nosif = {
138 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
139 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
140 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
141 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
142 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
143 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
144 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
145 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
146 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
147 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
148 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
149 {0, 0, 0},
150 },
151 .common = {
152 {TM6010_REQ07_R3F_RESET, 0x01},
153 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
154 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
155 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
156 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
157 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
158 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
159 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
160 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
161 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
162 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
163 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
164 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
165 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
166 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
167 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
168 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
169 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
170 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
171 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
172 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
173
174 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
175 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
176
177 {TM6010_REQ07_R3F_RESET, 0x00},
178
179 {0, 0, 0},
180 },
181 }, {
182 .id = V4L2_STD_PAL,
183 .audio_default_std = BG_A2,
184 .sif = {
185 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
186 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
187 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
188 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
189 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
190 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
191 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
192 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
193 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
194 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
195 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
196 {0, 0, 0}
197 },
198 .nosif = {
199 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
200 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
201 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
202 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
203 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
204 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
205 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
206 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
207 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
208 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
209 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
210 {0, 0, 0},
211 },
212 .common = {
213 {TM6010_REQ07_R3F_RESET, 0x01},
214 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
215 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
216 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
217 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
218 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
219 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
220 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
221 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
222 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
223 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
224 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
225 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
226 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
227 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
228 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
229 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
230 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
231 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
232 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
233 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
234
235 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
236 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
237
238 {TM6010_REQ07_R3F_RESET, 0x00},
239
240 {0, 0, 0},
241 },
242 }, {
243 .id = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
244 .audio_default_std = BG_NICAM,
245 .sif = {
246 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
247 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
248 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
249 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
250 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
251 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
252 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
253 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
254 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
255 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
256 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
257 {0, 0, 0},
258 },
259 .nosif = {
260 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
261 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
262 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
263 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
264 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
265 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
266 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
267 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
268 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
269 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
270 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
271 {0, 0, 0},
272 },
273 .common = {
274 {TM6010_REQ07_R3F_RESET, 0x01},
275 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
276 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
277 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
278 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
279 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
280 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
281 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
282 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
283 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
284 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
285 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
286 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
287 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
288 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
289 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
290 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
291 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
292 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
293 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
294 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
295
296 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
297
298 {TM6010_REQ07_R3F_RESET, 0x00},
299 {0, 0, 0},
300 },
301 }, {
302 .id = V4L2_STD_SECAM_DK,
303 .audio_default_std = DK_NICAM,
304 .sif = {
305 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
306 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
307 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
308 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
309 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
310 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
311 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
312 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
313 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
314 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
315 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
316 {0, 0, 0},
317 },
318 .nosif = {
319 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
320 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
321 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
322 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
323 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
324 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
325 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
326 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
327 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
328 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
329 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
330 {0, 0, 0},
331 },
332 .common = {
333 {TM6010_REQ07_R3F_RESET, 0x01},
334 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
335 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
336 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
337 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
338 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
339 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
340 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
341 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
342 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
343 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
344 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
345 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
346 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
347 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
348 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
349 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
350 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
351 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
352 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
353 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
354
355 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
356
357 {TM6010_REQ07_R3F_RESET, 0x00},
358 {0, 0, 0},
359 },
360 }, {
361 .id = V4L2_STD_NTSC,
362 .audio_default_std = BTSC,
363 .sif = {
364 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
365 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
366 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
367 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
368 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
369 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
370 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
371 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
372 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
373 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
374 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
375 {0, 0, 0},
376 },
377 .nosif = {
378 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
379 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
380 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
381 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
382 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
383 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
384 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
385 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
386 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
387 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
388 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
389 {0, 0, 0},
390 },
391 .common = {
392 {TM6010_REQ07_R3F_RESET, 0x01},
393 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
394 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
395 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
396 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
397 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
398 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
399 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
400 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
401 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
402 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
403 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
404 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
405 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
406 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
407 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
408 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
409 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
410 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
411 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
412 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
413
414 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
415 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
416
417 {TM6010_REQ07_R3F_RESET, 0x00},
418
419 {0, 0, 0},
420 },
421 },
422}; 39};
423 40
424static struct tm6000_std_settings composite_stds[] = { 41static struct tm6000_std_settings composite_stds[] = {
425 { 42 {
426 .id = V4L2_STD_PAL_M, 43 .id = V4L2_STD_PAL_M,
427 .audio_default_std = BTSC,
428 .common = { 44 .common = {
429 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
430 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
431 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
432 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
433 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
434 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
435 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
436 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
437 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
438 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
439 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
440
441 {TM6010_REQ07_R3F_RESET, 0x01}, 45 {TM6010_REQ07_R3F_RESET, 0x01},
442 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04}, 46 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
443 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 47 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -467,20 +71,7 @@ static struct tm6000_std_settings composite_stds[] = {
467 }, 71 },
468 }, { 72 }, {
469 .id = V4L2_STD_PAL_Nc, 73 .id = V4L2_STD_PAL_Nc,
470 .audio_default_std = BTSC,
471 .common = { 74 .common = {
472 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
473 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
474 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
475 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
476 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
477 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
478 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
479 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
480 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
481 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
482 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
483
484 {TM6010_REQ07_R3F_RESET, 0x01}, 75 {TM6010_REQ07_R3F_RESET, 0x01},
485 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36}, 76 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
486 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 77 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -510,20 +101,7 @@ static struct tm6000_std_settings composite_stds[] = {
510 }, 101 },
511 }, { 102 }, {
512 .id = V4L2_STD_PAL, 103 .id = V4L2_STD_PAL,
513 .audio_default_std = BG_A2,
514 .common = { 104 .common = {
515 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
516 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
517 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
518 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
519 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
520 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
521 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
522 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
523 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
524 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
525 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
526
527 {TM6010_REQ07_R3F_RESET, 0x01}, 105 {TM6010_REQ07_R3F_RESET, 0x01},
528 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32}, 106 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
529 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 107 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -553,62 +131,7 @@ static struct tm6000_std_settings composite_stds[] = {
553 }, 131 },
554 }, { 132 }, {
555 .id = V4L2_STD_SECAM, 133 .id = V4L2_STD_SECAM,
556 .audio_default_std = BG_NICAM,
557 .common = {
558 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
559 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
560 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
561 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
562 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
563 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
564 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
565 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
566 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
567 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
568 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
569
570 {TM6010_REQ07_R3F_RESET, 0x01},
571 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
572 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
573 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
574 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
575 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
576 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
577 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
578 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
579 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
580 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
581 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
582 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
583 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
584 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
585 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
586 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
587 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
588 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
589 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
590 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
591
592 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
593 {TM6010_REQ07_R3F_RESET, 0x00},
594 {0, 0, 0},
595 },
596 }, {
597 .id = V4L2_STD_SECAM_DK,
598 .audio_default_std = DK_NICAM,
599 .common = { 134 .common = {
600 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
601 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
602 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
603 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
604 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
605 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
606 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
607 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
608 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
609 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
610 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
611
612 {TM6010_REQ07_R3F_RESET, 0x01}, 135 {TM6010_REQ07_R3F_RESET, 0x01},
613 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38}, 136 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
614 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 137 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -637,20 +160,7 @@ static struct tm6000_std_settings composite_stds[] = {
637 }, 160 },
638 }, { 161 }, {
639 .id = V4L2_STD_NTSC, 162 .id = V4L2_STD_NTSC,
640 .audio_default_std = BTSC,
641 .common = { 163 .common = {
642 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
643 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
644 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
645 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
646 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
647 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
648 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
649 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
650 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
651 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
652 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
653
654 {TM6010_REQ07_R3F_RESET, 0x01}, 164 {TM6010_REQ07_R3F_RESET, 0x01},
655 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00}, 165 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
656 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f}, 166 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
@@ -684,20 +194,7 @@ static struct tm6000_std_settings composite_stds[] = {
684static struct tm6000_std_settings svideo_stds[] = { 194static struct tm6000_std_settings svideo_stds[] = {
685 { 195 {
686 .id = V4L2_STD_PAL_M, 196 .id = V4L2_STD_PAL_M,
687 .audio_default_std = BTSC,
688 .common = { 197 .common = {
689 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
690 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
691 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
692 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
693 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
694 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
695 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
696 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
697 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
698 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
699 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
700
701 {TM6010_REQ07_R3F_RESET, 0x01}, 198 {TM6010_REQ07_R3F_RESET, 0x01},
702 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05}, 199 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05},
703 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 200 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -727,20 +224,7 @@ static struct tm6000_std_settings svideo_stds[] = {
727 }, 224 },
728 }, { 225 }, {
729 .id = V4L2_STD_PAL_Nc, 226 .id = V4L2_STD_PAL_Nc,
730 .audio_default_std = BTSC,
731 .common = { 227 .common = {
732 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
733 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
734 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
735 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
736 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
737 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
738 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
739 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
740 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
741 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
742 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
743
744 {TM6010_REQ07_R3F_RESET, 0x01}, 228 {TM6010_REQ07_R3F_RESET, 0x01},
745 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37}, 229 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37},
746 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 230 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -770,20 +254,7 @@ static struct tm6000_std_settings svideo_stds[] = {
770 }, 254 },
771 }, { 255 }, {
772 .id = V4L2_STD_PAL, 256 .id = V4L2_STD_PAL,
773 .audio_default_std = BG_A2,
774 .common = { 257 .common = {
775 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
776 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
777 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
778 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
779 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
780 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
781 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
782 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
783 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
784 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
785 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
786
787 {TM6010_REQ07_R3F_RESET, 0x01}, 258 {TM6010_REQ07_R3F_RESET, 0x01},
788 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33}, 259 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33},
789 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 260 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -813,62 +284,7 @@ static struct tm6000_std_settings svideo_stds[] = {
813 }, 284 },
814 }, { 285 }, {
815 .id = V4L2_STD_SECAM, 286 .id = V4L2_STD_SECAM,
816 .audio_default_std = BG_NICAM,
817 .common = {
818 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
819 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
820 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
821 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
822 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
823 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
824 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
825 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
826 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
827 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
828 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
829
830 {TM6010_REQ07_R3F_RESET, 0x01},
831 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39},
832 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
833 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
834 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
835 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
836 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
837 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
838 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
839 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
840 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
841 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
842 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
843 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
844 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
845 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a},
846 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
847 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
848 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
849 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
850 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
851
852 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
853 {TM6010_REQ07_R3F_RESET, 0x00},
854 {0, 0, 0},
855 },
856 }, {
857 .id = V4L2_STD_SECAM_DK,
858 .audio_default_std = DK_NICAM,
859 .common = { 287 .common = {
860 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
861 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
862 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
863 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
864 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
865 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
866 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
867 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
868 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
869 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
870 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
871
872 {TM6010_REQ07_R3F_RESET, 0x01}, 288 {TM6010_REQ07_R3F_RESET, 0x01},
873 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39}, 289 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39},
874 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, 290 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -897,20 +313,7 @@ static struct tm6000_std_settings svideo_stds[] = {
897 }, 313 },
898 }, { 314 }, {
899 .id = V4L2_STD_NTSC, 315 .id = V4L2_STD_NTSC,
900 .audio_default_std = BTSC,
901 .common = { 316 .common = {
902 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
903 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
904 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
905 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
906 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
907 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
908 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
909 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
910 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
911 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
912 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
913
914 {TM6010_REQ07_R3F_RESET, 0x01}, 317 {TM6010_REQ07_R3F_RESET, 0x01},
915 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01}, 318 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01},
916 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f}, 319 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
@@ -943,13 +346,11 @@ static struct tm6000_std_settings svideo_stds[] = {
943}; 346};
944 347
945 348
946static int tm6000_set_audio_std(struct tm6000_core *dev, 349static int tm6000_set_audio_std(struct tm6000_core *dev)
947 enum tm6000_audio_std std)
948{ 350{
949 uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */ 351 uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */
950 uint8_t areg_05 = 0x09; /* Auto 4.5 = M Japan, Auto 6.5 = DK */ 352 uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
951 uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */ 353 uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */
952 uint8_t mono_flag = 0; /* No mono */
953 uint8_t nicam_flag = 0; /* No NICAM */ 354 uint8_t nicam_flag = 0; /* No NICAM */
954 355
955 if (dev->radio) { 356 if (dev->radio) {
@@ -958,81 +359,99 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
958 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00); 359 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
959 tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80); 360 tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
960 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c); 361 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
961 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00); 362 /* set mono or stereo */
363 if (dev->amode == V4L2_TUNER_MODE_MONO)
364 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
365 else if (dev->amode == V4L2_TUNER_MODE_STEREO)
366 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x02);
962 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18); 367 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
963 tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a); 368 tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
964 tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40); 369 tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
965 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc); 370 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
966 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); 371 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
967 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); 372 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
968 return 0; 373 return 0;
969 } 374 }
970 375
971 switch (std) { 376 switch (tm6010_a_mode) {
972#if 0 377 /* auto */
973 case DK_MONO: 378 case 0:
974 mono_flag = 1; 379 switch (dev->norm) {
975 break; 380 case V4L2_STD_NTSC_M_KR:
976 case DK_A2_1: 381 areg_05 |= 0x00;
977 break; 382 break;
978 case DK_A2_3: 383 case V4L2_STD_NTSC_M_JP:
979 areg_05 = 0x0b; 384 areg_05 |= 0x40;
980 break; 385 break;
981 case BG_MONO: 386 case V4L2_STD_NTSC_M:
982 mono_flag = 1; 387 case V4L2_STD_PAL_M:
983 areg_05 = 0x05; 388 case V4L2_STD_PAL_N:
984 break; 389 areg_05 |= 0x20;
985#endif 390 break;
986 case BG_NICAM: 391 case V4L2_STD_PAL_Nc:
987 areg_05 = 0x07; 392 areg_05 |= 0x60;
988 nicam_flag = 1; 393 break;
989 break; 394 case V4L2_STD_SECAM_L:
990 case BTSC: 395 areg_05 |= 0x00;
991 areg_05 = 0x02; 396 break;
992 break; 397 case V4L2_STD_DK:
993 case BG_A2: 398 areg_05 |= 0x10;
994 areg_05 = 0x05; 399 break;
995 break; 400 }
996 case DK_NICAM:
997 areg_05 = 0x06;
998 nicam_flag = 1;
999 break;
1000 case EIAJ:
1001 areg_05 = 0x02;
1002 break;
1003 case I_NICAM:
1004 areg_05 = 0x08;
1005 nicam_flag = 1;
1006 break; 401 break;
1007 case KOREA_A2: 402 /* A2 */
1008 areg_05 = 0x04; 403 case 1:
404 switch (dev->norm) {
405 case V4L2_STD_B:
406 case V4L2_STD_GH:
407 areg_05 = 0x05;
408 break;
409 case V4L2_STD_DK:
410 areg_05 = 0x09;
411 break;
412 }
1009 break; 413 break;
1010 case L_NICAM: 414 /* NICAM */
1011 areg_02 = 0x02; /* GC1 Fixed gain +12dB */ 415 case 2:
1012 areg_05 = 0x0a; 416 switch (dev->norm) {
417 case V4L2_STD_B:
418 case V4L2_STD_GH:
419 areg_05 = 0x07;
420 break;
421 case V4L2_STD_DK:
422 areg_05 = 0x06;
423 break;
424 case V4L2_STD_PAL_I:
425 areg_05 = 0x08;
426 break;
427 case V4L2_STD_SECAM_L:
428 areg_05 = 0x0a;
429 areg_02 = 0x02;
430 break;
431 }
1013 nicam_flag = 1; 432 nicam_flag = 1;
1014 break; 433 break;
1015 default: 434 /* other */
1016 /* do nothink */ 435 case 3:
1017 break; 436 switch (dev->norm) {
1018 } 437 /* DK3_A2 */
1019 438 case V4L2_STD_DK:
1020#if 0 439 areg_05 = 0x0b;
1021 switch (tv_audio_mode) { 440 break;
1022 case TV_MONO: 441 /* Korea */
1023 areg_06 = (nicam_flag) ? 0x03 : 0x00; 442 case V4L2_STD_NTSC_M_KR:
1024 break; 443 areg_05 = 0x04;
1025 case TV_LANG_A: 444 break;
1026 areg_06 = 0x00; 445 /* EIAJ */
1027 break; 446 case V4L2_STD_NTSC_M_JP:
1028 case TV_LANG_B: 447 areg_05 = 0x03;
1029 areg_06 = 0x01; 448 break;
449 default:
450 areg_05 = 0x02;
451 break;
452 }
1030 break; 453 break;
1031 } 454 }
1032#endif
1033
1034 if (mono_flag)
1035 areg_06 = 0x00;
1036 455
1037 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); 456 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
1038 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02); 457 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02);
@@ -1066,9 +485,6 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
1066 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); 485 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
1067 tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00); 486 tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00);
1068 tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00); 487 tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00);
1069 tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
1070 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
1071 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
1072 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); 488 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
1073 489
1074 return 0; 490 return 0;
@@ -1095,10 +511,6 @@ static int tm6000_load_std(struct tm6000_core *dev,
1095 if (!set[i].req) 511 if (!set[i].req)
1096 return 0; 512 return 0;
1097 513
1098 if ((dev->dev_type != TM6010) &&
1099 (set[i].req == REQ_08_SET_GET_AVREG_BIT))
1100 continue;
1101
1102 rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value); 514 rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
1103 if (rc < 0) { 515 if (rc < 0) {
1104 printk(KERN_ERR "Error %i while setting " 516 printk(KERN_ERR "Error %i while setting "
@@ -1111,53 +523,126 @@ static int tm6000_load_std(struct tm6000_core *dev,
1111 return 0; 523 return 0;
1112} 524}
1113 525
1114static int tm6000_set_tv(struct tm6000_core *dev, int pos) 526int tm6000_set_standard(struct tm6000_core *dev)
1115{
1116 int rc;
1117
1118 /* FIXME: This code is for tm6010 - not tested yet - doesn't work with
1119 tm5600
1120 */
1121
1122 /* FIXME: This is tuner-dependent */
1123 int nosif = 0;
1124
1125 if (nosif) {
1126 rc = tm6000_load_std(dev, tv_stds[pos].nosif,
1127 sizeof(tv_stds[pos].nosif));
1128 } else {
1129 rc = tm6000_load_std(dev, tv_stds[pos].sif,
1130 sizeof(tv_stds[pos].sif));
1131 }
1132 if (rc < 0)
1133 return rc;
1134 rc = tm6000_load_std(dev, tv_stds[pos].common,
1135 sizeof(tv_stds[pos].common));
1136
1137 tm6000_set_audio_std(dev, tv_stds[pos].audio_default_std);
1138
1139 return rc;
1140}
1141
1142int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm)
1143{ 527{
1144 int i, rc = 0; 528 int i, rc = 0;
529 u8 reg_07_fe = 0x8a;
530 u8 reg_08_f1 = 0xfc;
531 u8 reg_08_e2 = 0xf0;
532 u8 reg_08_e6 = 0x0f;
1145 533
1146 dev->norm = *norm;
1147 tm6000_get_std_res(dev); 534 tm6000_get_std_res(dev);
1148 535
1149 switch (dev->input) { 536 if (dev->radio) {
1150 case TM6000_INPUT_TV: 537 /* todo */
1151 for (i = 0; i < ARRAY_SIZE(tv_stds); i++) { 538 }
1152 if (*norm & tv_stds[i].id) { 539
1153 rc = tm6000_set_tv(dev, i); 540 if (dev->dev_type == TM6010) {
1154 goto ret; 541 switch (dev->vinput[dev->input].vmux) {
1155 } 542 case TM6000_VMUX_VIDEO_A:
543 tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4);
544 tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
545 tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
546 tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
547 tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
548 reg_07_fe |= 0x01;
549 break;
550 case TM6000_VMUX_VIDEO_B:
551 tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8);
552 tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
553 tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
554 tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
555 tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
556 reg_07_fe |= 0x01;
557 break;
558 case TM6000_VMUX_VIDEO_AB:
559 tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc);
560 tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8);
561 reg_08_e6 = 0x00;
562 tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2);
563 tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0);
564 tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
565 tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe0);
566 break;
567 default:
568 break;
1156 } 569 }
1157 return -EINVAL; 570 switch (dev->vinput[dev->input].amux) {
1158 case TM6000_INPUT_SVIDEO: 571 case TM6000_AMUX_ADC1:
572 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
573 0x00, 0x0f);
574 break;
575 case TM6000_AMUX_ADC2:
576 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
577 0x08, 0x0f);
578 break;
579 case TM6000_AMUX_SIF1:
580 reg_08_e2 |= 0x02;
581 reg_08_e6 = 0x08;
582 reg_07_fe |= 0x40;
583 reg_08_f1 |= 0x02;
584 tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
585 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
586 0x02, 0x0f);
587 break;
588 case TM6000_AMUX_SIF2:
589 reg_08_e2 |= 0x02;
590 reg_08_e6 = 0x08;
591 reg_07_fe |= 0x40;
592 reg_08_f1 |= 0x02;
593 tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7);
594 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
595 0x02, 0x0f);
596 break;
597 default:
598 break;
599 }
600 tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, reg_08_e2);
601 tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, reg_08_e6);
602 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1);
603 tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe);
604 } else {
605 switch (dev->vinput[dev->input].vmux) {
606 case TM6000_VMUX_VIDEO_A:
607 tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
608 tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
609 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
610 tm6000_set_reg(dev,
611 REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0);
612 break;
613 case TM6000_VMUX_VIDEO_B:
614 tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
615 tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
616 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
617 tm6000_set_reg(dev,
618 REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0);
619 break;
620 case TM6000_VMUX_VIDEO_AB:
621 tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
622 tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10);
623 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00);
624 tm6000_set_reg(dev,
625 REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 1);
626 break;
627 default:
628 break;
629 }
630 switch (dev->vinput[dev->input].amux) {
631 case TM6000_AMUX_ADC1:
632 tm6000_set_reg_mask(dev,
633 TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f);
634 break;
635 case TM6000_AMUX_ADC2:
636 tm6000_set_reg_mask(dev,
637 TM6000_REQ07_REB_VADC_AADC_MODE, 0x04, 0x0f);
638 break;
639 default:
640 break;
641 }
642 }
643 if (dev->vinput[dev->input].type == TM6000_INPUT_SVIDEO) {
1159 for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) { 644 for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
1160 if (*norm & svideo_stds[i].id) { 645 if (dev->norm & svideo_stds[i].id) {
1161 rc = tm6000_load_std(dev, svideo_stds[i].common, 646 rc = tm6000_load_std(dev, svideo_stds[i].common,
1162 sizeof(svideo_stds[i]. 647 sizeof(svideo_stds[i].
1163 common)); 648 common));
@@ -1165,14 +650,13 @@ int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm)
1165 } 650 }
1166 } 651 }
1167 return -EINVAL; 652 return -EINVAL;
1168 case TM6000_INPUT_COMPOSITE: 653 } else {
1169 for (i = 0; i < ARRAY_SIZE(composite_stds); i++) { 654 for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
1170 if (*norm & composite_stds[i].id) { 655 if (dev->norm & composite_stds[i].id) {
1171 rc = tm6000_load_std(dev, 656 rc = tm6000_load_std(dev,
1172 composite_stds[i].common, 657 composite_stds[i].common,
1173 sizeof(composite_stds[i]. 658 sizeof(composite_stds[i].
1174 common)); 659 common));
1175 tm6000_set_audio_std(dev, composite_stds[i].audio_default_std);
1176 goto ret; 660 goto ret;
1177 } 661 }
1178 } 662 }
@@ -1183,6 +667,11 @@ ret:
1183 if (rc < 0) 667 if (rc < 0)
1184 return rc; 668 return rc;
1185 669
670 if ((dev->dev_type == TM6010) &&
671 ((dev->vinput[dev->input].amux == TM6000_AMUX_SIF1) ||
672 (dev->vinput[dev->input].amux == TM6000_AMUX_SIF2)))
673 tm6000_set_audio_std(dev);
674
1186 msleep(40); 675 msleep(40);
1187 676
1188 677
diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
index a9e61d95a9b2..084c2a8904a3 100644
--- a/drivers/staging/tm6000/tm6000-usb-isoc.h
+++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
@@ -39,7 +39,7 @@ struct usb_isoc_ctl {
39 int pos, size, pktsize; 39 int pos, size, pktsize;
40 40
41 /* Last field: ODD or EVEN? */ 41 /* Last field: ODD or EVEN? */
42 int vfield; 42 int vfield, field;
43 43
44 /* Stores incomplete commands */ 44 /* Stores incomplete commands */
45 u32 tmp_buf; 45 u32 tmp_buf;
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 17db6684abbe..4264064a727e 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -34,6 +34,7 @@
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/videodev2.h> 35#include <linux/videodev2.h>
36#include <media/v4l2-ioctl.h> 36#include <media/v4l2-ioctl.h>
37#include <media/tuner.h>
37#include <linux/interrupt.h> 38#include <linux/interrupt.h>
38#include <linux/kthread.h> 39#include <linux/kthread.h>
39#include <linux/highmem.h> 40#include <linux/highmem.h>
@@ -228,7 +229,7 @@ static int copy_streams(u8 *data, unsigned long len,
228 unsigned long header = 0; 229 unsigned long header = 0;
229 int rc = 0; 230 int rc = 0;
230 unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0; 231 unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
231 struct tm6000_buffer *vbuf; 232 struct tm6000_buffer *vbuf = NULL;
232 char *voutp = NULL; 233 char *voutp = NULL;
233 unsigned int linewidth; 234 unsigned int linewidth;
234 235
@@ -318,7 +319,7 @@ static int copy_streams(u8 *data, unsigned long len,
318 if (pos + size > vbuf->vb.size) 319 if (pos + size > vbuf->vb.size)
319 cmd = TM6000_URB_MSG_ERR; 320 cmd = TM6000_URB_MSG_ERR;
320 dev->isoc_ctl.vfield = field; 321 dev->isoc_ctl.vfield = field;
321 } 322 }
322 break; 323 break;
323 case TM6000_URB_MSG_VBI: 324 case TM6000_URB_MSG_VBI:
324 break; 325 break;
@@ -333,6 +334,7 @@ static int copy_streams(u8 *data, unsigned long len,
333 size = dev->isoc_ctl.size; 334 size = dev->isoc_ctl.size;
334 pos = dev->isoc_ctl.pos; 335 pos = dev->isoc_ctl.pos;
335 pktsize = dev->isoc_ctl.pktsize; 336 pktsize = dev->isoc_ctl.pktsize;
337 field = dev->isoc_ctl.field;
336 } 338 }
337 cpysize = (endp - ptr > size) ? size : endp - ptr; 339 cpysize = (endp - ptr > size) ? size : endp - ptr;
338 if (cpysize) { 340 if (cpysize) {
@@ -343,24 +345,26 @@ static int copy_streams(u8 *data, unsigned long len,
343 if (vbuf) 345 if (vbuf)
344 memcpy(&voutp[pos], ptr, cpysize); 346 memcpy(&voutp[pos], ptr, cpysize);
345 break; 347 break;
346 case TM6000_URB_MSG_AUDIO: 348 case TM6000_URB_MSG_AUDIO: {
347 /* Need some code to copy audio buffer */ 349 int i;
348 if (dev->fourcc == V4L2_PIX_FMT_YUYV) { 350 for (i = 0; i < cpysize; i += 2)
349 /* Swap word bytes */ 351 swab16s((u16 *)(ptr + i));
350 int i;
351 352
352 for (i = 0; i < cpysize; i += 2)
353 swab16s((u16 *)(ptr + i));
354 }
355 tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize); 353 tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
356 break; 354 break;
355 }
357 case TM6000_URB_MSG_VBI: 356 case TM6000_URB_MSG_VBI:
358 /* Need some code to copy vbi buffer */ 357 /* Need some code to copy vbi buffer */
359 break; 358 break;
360 case TM6000_URB_MSG_PTS: 359 case TM6000_URB_MSG_PTS: {
361 /* Need some code to copy pts */ 360 /* Need some code to copy pts */
361 u32 pts;
362 pts = *(u32 *)ptr;
363 dprintk(dev, V4L2_DEBUG_ISOC, "field %d, PTS %x",
364 field, pts);
362 break; 365 break;
363 } 366 }
367 }
364 } 368 }
365 if (ptr + pktsize > endp) { 369 if (ptr + pktsize > endp) {
366 /* End of URB packet, but cmd processing is not 370 /* End of URB packet, but cmd processing is not
@@ -369,6 +373,7 @@ static int copy_streams(u8 *data, unsigned long len,
369 dev->isoc_ctl.pos = pos + cpysize; 373 dev->isoc_ctl.pos = pos + cpysize;
370 dev->isoc_ctl.size = size - cpysize; 374 dev->isoc_ctl.size = size - cpysize;
371 dev->isoc_ctl.cmd = cmd; 375 dev->isoc_ctl.cmd = cmd;
376 dev->isoc_ctl.field = field;
372 dev->isoc_ctl.pktsize = pktsize - (endp - ptr); 377 dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
373 ptr += endp - ptr; 378 ptr += endp - ptr;
374 } else { 379 } else {
@@ -883,14 +888,19 @@ static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh)
883static int vidioc_querycap(struct file *file, void *priv, 888static int vidioc_querycap(struct file *file, void *priv,
884 struct v4l2_capability *cap) 889 struct v4l2_capability *cap)
885{ 890{
891 struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
886 892
887 strlcpy(cap->driver, "tm6000", sizeof(cap->driver)); 893 strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
888 strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card)); 894 strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
889 cap->version = TM6000_VERSION; 895 cap->version = TM6000_VERSION;
890 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 896 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
891 V4L2_CAP_STREAMING | 897 V4L2_CAP_STREAMING |
892 V4L2_CAP_TUNER | 898 V4L2_CAP_AUDIO |
893 V4L2_CAP_READWRITE; 899 V4L2_CAP_READWRITE;
900
901 if (dev->tuner_type != TUNER_ABSENT)
902 cap->capabilities |= V4L2_CAP_TUNER;
903
894 return 0; 904 return 0;
895} 905}
896 906
@@ -1077,35 +1087,37 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
1077 return 0; 1087 return 0;
1078} 1088}
1079 1089
1090static const char *iname [] = {
1091 [TM6000_INPUT_TV] = "Television",
1092 [TM6000_INPUT_COMPOSITE1] = "Composite 1",
1093 [TM6000_INPUT_COMPOSITE2] = "Composite 2",
1094 [TM6000_INPUT_SVIDEO] = "S-Video",
1095};
1096
1080static int vidioc_enum_input(struct file *file, void *priv, 1097static int vidioc_enum_input(struct file *file, void *priv,
1081 struct v4l2_input *inp) 1098 struct v4l2_input *i)
1082{ 1099{
1083 struct tm6000_fh *fh = priv; 1100 struct tm6000_fh *fh = priv;
1084 struct tm6000_core *dev = fh->dev; 1101 struct tm6000_core *dev = fh->dev;
1102 unsigned int n;
1085 1103
1086 switch (inp->index) { 1104 n = i->index;
1087 case TM6000_INPUT_TV: 1105 if (n >= 3)
1088 inp->type = V4L2_INPUT_TYPE_TUNER;
1089 strcpy(inp->name, "Television");
1090 break;
1091 case TM6000_INPUT_COMPOSITE:
1092 if (dev->caps.has_input_comp) {
1093 inp->type = V4L2_INPUT_TYPE_CAMERA;
1094 strcpy(inp->name, "Composite");
1095 } else
1096 return -EINVAL;
1097 break;
1098 case TM6000_INPUT_SVIDEO:
1099 if (dev->caps.has_input_svid) {
1100 inp->type = V4L2_INPUT_TYPE_CAMERA;
1101 strcpy(inp->name, "S-Video");
1102 } else
1103 return -EINVAL;
1104 break;
1105 default:
1106 return -EINVAL; 1106 return -EINVAL;
1107 } 1107
1108 inp->std = TM6000_STD; 1108 if (!dev->vinput[n].type)
1109 return -EINVAL;
1110
1111 i->index = n;
1112
1113 if (dev->vinput[n].type == TM6000_INPUT_TV)
1114 i->type = V4L2_INPUT_TYPE_TUNER;
1115 else
1116 i->type = V4L2_INPUT_TYPE_CAMERA;
1117
1118 strcpy(i->name, iname[dev->vinput[n].type]);
1119
1120 i->std = TM6000_STD;
1109 1121
1110 return 0; 1122 return 0;
1111} 1123}
@@ -1119,38 +1131,26 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1119 1131
1120 return 0; 1132 return 0;
1121} 1133}
1134
1122static int vidioc_s_input(struct file *file, void *priv, unsigned int i) 1135static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1123{ 1136{
1124 struct tm6000_fh *fh = priv; 1137 struct tm6000_fh *fh = priv;
1125 struct tm6000_core *dev = fh->dev; 1138 struct tm6000_core *dev = fh->dev;
1126 int rc = 0; 1139 int rc = 0;
1127 char buf[1];
1128 1140
1129 switch (i) { 1141 if (i >= 3)
1130 case TM6000_INPUT_TV: 1142 return -EINVAL;
1131 dev->input = i; 1143 if (!dev->vinput[i].type)
1132 *buf = 0;
1133 break;
1134 case TM6000_INPUT_COMPOSITE:
1135 case TM6000_INPUT_SVIDEO:
1136 dev->input = i;
1137 *buf = 1;
1138 break;
1139 default:
1140 return -EINVAL; 1144 return -EINVAL;
1141 }
1142 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
1143 REQ_03_SET_GET_MCU_PIN, 0x03, 1, buf, 1);
1144 1145
1145 if (!rc) { 1146 dev->input = i;
1146 dev->input = i; 1147
1147 rc = vidioc_s_std(file, priv, &dev->vfd->current_norm); 1148 rc = vidioc_s_std(file, priv, &dev->vfd->current_norm);
1148 }
1149 1149
1150 return rc; 1150 return rc;
1151} 1151}
1152 1152
1153 /* --- controls ---------------------------------------------- */ 1153/* --- controls ---------------------------------------------- */
1154static int vidioc_queryctrl(struct file *file, void *priv, 1154static int vidioc_queryctrl(struct file *file, void *priv,
1155 struct v4l2_queryctrl *qc) 1155 struct v4l2_queryctrl *qc)
1156{ 1156{
@@ -1251,7 +1251,11 @@ static int vidioc_g_tuner(struct file *file, void *priv,
1251 t->type = V4L2_TUNER_ANALOG_TV; 1251 t->type = V4L2_TUNER_ANALOG_TV;
1252 t->capability = V4L2_TUNER_CAP_NORM; 1252 t->capability = V4L2_TUNER_CAP_NORM;
1253 t->rangehigh = 0xffffffffUL; 1253 t->rangehigh = 0xffffffffUL;
1254 t->rxsubchans = V4L2_TUNER_SUB_MONO; 1254 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
1255
1256 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
1257
1258 t->audmode = dev->amode;
1255 1259
1256 return 0; 1260 return 0;
1257} 1261}
@@ -1267,6 +1271,11 @@ static int vidioc_s_tuner(struct file *file, void *priv,
1267 if (0 != t->index) 1271 if (0 != t->index)
1268 return -EINVAL; 1272 return -EINVAL;
1269 1273
1274 dev->amode = t->audmode;
1275 dprintk(dev, 3, "audio mode: %x\n", t->audmode);
1276
1277 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
1278
1270 return 0; 1279 return 0;
1271} 1280}
1272 1281
@@ -1320,7 +1329,11 @@ static int radio_querycap(struct file *file, void *priv,
1320 le16_to_cpu(dev->udev->descriptor.idVendor), 1329 le16_to_cpu(dev->udev->descriptor.idVendor),
1321 le16_to_cpu(dev->udev->descriptor.idProduct)); 1330 le16_to_cpu(dev->udev->descriptor.idProduct));
1322 cap->version = dev->dev_type; 1331 cap->version = dev->dev_type;
1323 cap->capabilities = V4L2_CAP_TUNER; 1332 cap->capabilities = V4L2_CAP_TUNER |
1333 V4L2_CAP_AUDIO |
1334 V4L2_CAP_RADIO |
1335 V4L2_CAP_READWRITE |
1336 V4L2_CAP_STREAMING;
1324 1337
1325 return 0; 1338 return 0;
1326} 1339}
@@ -1337,17 +1350,10 @@ static int radio_g_tuner(struct file *file, void *priv,
1337 memset(t, 0, sizeof(*t)); 1350 memset(t, 0, sizeof(*t));
1338 strcpy(t->name, "Radio"); 1351 strcpy(t->name, "Radio");
1339 t->type = V4L2_TUNER_RADIO; 1352 t->type = V4L2_TUNER_RADIO;
1353 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
1340 1354
1341 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); 1355 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
1342 1356
1343 if ((dev->aradio == TM6000_AIP_LINE1) ||
1344 (dev->aradio == TM6000_AIP_LINE2)) {
1345 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1346 }
1347 else {
1348 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
1349 }
1350
1351 return 0; 1357 return 0;
1352} 1358}
1353 1359
@@ -1368,9 +1374,15 @@ static int radio_s_tuner(struct file *file, void *priv,
1368static int radio_enum_input(struct file *file, void *priv, 1374static int radio_enum_input(struct file *file, void *priv,
1369 struct v4l2_input *i) 1375 struct v4l2_input *i)
1370{ 1376{
1377 struct tm6000_fh *fh = priv;
1378 struct tm6000_core *dev = fh->dev;
1379
1371 if (i->index != 0) 1380 if (i->index != 0)
1372 return -EINVAL; 1381 return -EINVAL;
1373 1382
1383 if (!dev->rinput.type)
1384 return -EINVAL;
1385
1374 strcpy(i->name, "Radio"); 1386 strcpy(i->name, "Radio");
1375 i->type = V4L2_INPUT_TYPE_TUNER; 1387 i->type = V4L2_INPUT_TYPE_TUNER;
1376 1388
@@ -1379,7 +1391,14 @@ static int radio_enum_input(struct file *file, void *priv,
1379 1391
1380static int radio_g_input(struct file *filp, void *priv, unsigned int *i) 1392static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
1381{ 1393{
1382 *i = 0; 1394 struct tm6000_fh *fh = priv;
1395 struct tm6000_core *dev = fh->dev;
1396
1397 if (dev->input !=5)
1398 return -EINVAL;
1399
1400 *i = dev->input -5;
1401
1383 return 0; 1402 return 0;
1384} 1403}
1385 1404
@@ -1399,6 +1418,17 @@ static int radio_s_audio(struct file *file, void *priv,
1399 1418
1400static int radio_s_input(struct file *filp, void *priv, unsigned int i) 1419static int radio_s_input(struct file *filp, void *priv, unsigned int i)
1401{ 1420{
1421 struct tm6000_fh *fh = priv;
1422 struct tm6000_core *dev = fh->dev;
1423
1424 if (i)
1425 return -EINVAL;
1426
1427 if (!dev->rinput.type)
1428 return -EINVAL;
1429
1430 dev->input = i + 5;
1431
1402 return 0; 1432 return 0;
1403} 1433}
1404 1434
@@ -1512,16 +1542,12 @@ static int tm6000_open(struct file *file)
1512 1542
1513 if (fh->radio) { 1543 if (fh->radio) {
1514 dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n"); 1544 dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n");
1515 tm6000_set_audio_input(dev, dev->aradio); 1545 dev->input = 5;
1516 tm6000_set_volume(dev, dev->ctl_volume); 1546 tm6000_set_audio_rinput(dev);
1517 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio); 1547 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
1518 tm6000_prepare_isoc(dev); 1548 tm6000_prepare_isoc(dev);
1519 tm6000_start_thread(dev); 1549 tm6000_start_thread(dev);
1520 } 1550 }
1521 else {
1522 tm6000_set_audio_input(dev, dev->avideo);
1523 tm6000_set_volume(dev, dev->ctl_volume);
1524 }
1525 1551
1526 return 0; 1552 return 0;
1527} 1553}
@@ -1647,10 +1673,10 @@ static struct video_device tm6000_template = {
1647}; 1673};
1648 1674
1649static const struct v4l2_file_operations radio_fops = { 1675static const struct v4l2_file_operations radio_fops = {
1650 .owner = THIS_MODULE, 1676 .owner = THIS_MODULE,
1651 .open = tm6000_open, 1677 .open = tm6000_open,
1652 .release = tm6000_release, 1678 .release = tm6000_release,
1653 .ioctl = video_ioctl2, 1679 .unlocked_ioctl = video_ioctl2,
1654}; 1680};
1655 1681
1656static const struct v4l2_ioctl_ops radio_ioctl_ops = { 1682static const struct v4l2_ioctl_ops radio_ioctl_ops = {
@@ -1730,24 +1756,26 @@ int tm6000_v4l2_register(struct tm6000_core *dev)
1730 printk(KERN_INFO "%s: registered device %s\n", 1756 printk(KERN_INFO "%s: registered device %s\n",
1731 dev->name, video_device_node_name(dev->vfd)); 1757 dev->name, video_device_node_name(dev->vfd));
1732 1758
1733 dev->radio_dev = vdev_init(dev, &tm6000_radio_template, 1759 if (dev->caps.has_radio) {
1734 "radio"); 1760 dev->radio_dev = vdev_init(dev, &tm6000_radio_template,
1735 if (!dev->radio_dev) { 1761 "radio");
1736 printk(KERN_INFO "%s: can't register radio device\n", 1762 if (!dev->radio_dev) {
1737 dev->name); 1763 printk(KERN_INFO "%s: can't register radio device\n",
1738 return ret; /* FIXME release resource */ 1764 dev->name);
1739 } 1765 return ret; /* FIXME release resource */
1766 }
1740 1767
1741 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, 1768 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
1742 radio_nr); 1769 radio_nr);
1743 if (ret < 0) { 1770 if (ret < 0) {
1744 printk(KERN_INFO "%s: can't register radio device\n", 1771 printk(KERN_INFO "%s: can't register radio device\n",
1745 dev->name); 1772 dev->name);
1746 return ret; /* FIXME release resource */ 1773 return ret; /* FIXME release resource */
1747 } 1774 }
1748 1775
1749 printk(KERN_INFO "%s: registered device %s\n", 1776 printk(KERN_INFO "%s: registered device %s\n",
1750 dev->name, video_device_node_name(dev->radio_dev)); 1777 dev->name, video_device_node_name(dev->radio_dev));
1778 }
1751 1779
1752 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); 1780 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
1753 return ret; 1781 return ret;
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 99ae50e82b28..ae6369b9a90c 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -40,11 +40,24 @@
40#define TM6000_VERSION KERNEL_VERSION(0, 0, 2) 40#define TM6000_VERSION KERNEL_VERSION(0, 0, 2)
41 41
42/* Inputs */ 42/* Inputs */
43
44enum tm6000_itype { 43enum tm6000_itype {
45 TM6000_INPUT_TV = 0, 44 TM6000_INPUT_TV = 1,
46 TM6000_INPUT_COMPOSITE, 45 TM6000_INPUT_COMPOSITE1,
46 TM6000_INPUT_COMPOSITE2,
47 TM6000_INPUT_SVIDEO, 47 TM6000_INPUT_SVIDEO,
48 TM6000_INPUT_DVB,
49 TM6000_INPUT_RADIO,
50};
51
52enum tm6000_mux {
53 TM6000_VMUX_VIDEO_A = 1,
54 TM6000_VMUX_VIDEO_B,
55 TM6000_VMUX_VIDEO_AB,
56 TM6000_AMUX_ADC1,
57 TM6000_AMUX_ADC2,
58 TM6000_AMUX_SIF1,
59 TM6000_AMUX_SIF2,
60 TM6000_AMUX_I2S,
48}; 61};
49 62
50enum tm6000_devtype { 63enum tm6000_devtype {
@@ -53,12 +66,12 @@ enum tm6000_devtype {
53 TM6010, 66 TM6010,
54}; 67};
55 68
56enum tm6000_inaudio { 69struct tm6000_input {
57 TM6000_AIP_UNK = 0, 70 enum tm6000_itype type;
58 TM6000_AIP_SIF1, 71 enum tm6000_mux vmux;
59 TM6000_AIP_SIF2, 72 enum tm6000_mux amux;
60 TM6000_AIP_LINE1, 73 unsigned int v_gpio;
61 TM6000_AIP_LINE2, 74 unsigned int a_gpio;
62}; 75};
63 76
64/* ------------------------------------------------------------------ 77/* ------------------------------------------------------------------
@@ -129,8 +142,7 @@ struct tm6000_capabilities {
129 unsigned int has_zl10353:1; 142 unsigned int has_zl10353:1;
130 unsigned int has_eeprom:1; 143 unsigned int has_eeprom:1;
131 unsigned int has_remote:1; 144 unsigned int has_remote:1;
132 unsigned int has_input_comp:1; 145 unsigned int has_radio:1;
133 unsigned int has_input_svid:1;
134}; 146};
135 147
136struct tm6000_dvb { 148struct tm6000_dvb {
@@ -167,6 +179,8 @@ struct tm6000_core {
167 int model; /* index in the device_data struct */ 179 int model; /* index in the device_data struct */
168 int devno; /* marks the number of this device */ 180 int devno; /* marks the number of this device */
169 enum tm6000_devtype dev_type; /* type of device */ 181 enum tm6000_devtype dev_type; /* type of device */
182 unsigned char eedata[256]; /* Eeprom data */
183 unsigned eedata_size; /* Size of the eeprom info */
170 184
171 v4l2_std_id norm; /* Current norm */ 185 v4l2_std_id norm; /* Current norm */
172 int width, height; /* Selected resolution */ 186 int width, height; /* Selected resolution */
@@ -211,6 +225,9 @@ struct tm6000_core {
211 struct v4l2_device v4l2_dev; 225 struct v4l2_device v4l2_dev;
212 226
213 int input; 227 int input;
228 struct tm6000_input vinput[3]; /* video input */
229 struct tm6000_input rinput; /* radio input */
230
214 int freq; 231 int freq;
215 unsigned int fourcc; 232 unsigned int fourcc;
216 233
@@ -218,6 +235,7 @@ struct tm6000_core {
218 235
219 int ctl_mute; /* audio */ 236 int ctl_mute; /* audio */
220 int ctl_volume; 237 int ctl_volume;
238 int amode;
221 239
222 /* DVB-T support */ 240 /* DVB-T support */
223 struct tm6000_dvb *dvb; 241 struct tm6000_dvb *dvb;
@@ -226,8 +244,6 @@ struct tm6000_core {
226 struct snd_tm6000_card *adev; 244 struct snd_tm6000_card *adev;
227 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ 245 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
228 atomic_t stream_started; /* stream should be running if true */ 246 atomic_t stream_started; /* stream should be running if true */
229 enum tm6000_inaudio avideo;
230 enum tm6000_inaudio aradio;
231 247
232 struct tm6000_IR *ir; 248 struct tm6000_IR *ir;
233 249
@@ -302,7 +318,7 @@ int tm6000_init(struct tm6000_core *dev);
302int tm6000_init_analog_mode(struct tm6000_core *dev); 318int tm6000_init_analog_mode(struct tm6000_core *dev);
303int tm6000_init_digital_mode(struct tm6000_core *dev); 319int tm6000_init_digital_mode(struct tm6000_core *dev);
304int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate); 320int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
305int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp); 321int tm6000_set_audio_rinput(struct tm6000_core *dev);
306int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute); 322int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute);
307void tm6000_set_volume(struct tm6000_core *dev, int vol); 323void tm6000_set_volume(struct tm6000_core *dev, int vol);
308 324
@@ -323,7 +339,7 @@ int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
323 339
324/* In tm6000-stds.c */ 340/* In tm6000-stds.c */
325void tm6000_get_std_res(struct tm6000_core *dev); 341void tm6000_get_std_res(struct tm6000_core *dev);
326int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id *norm); 342int tm6000_set_standard(struct tm6000_core *dev);
327 343
328/* In tm6000-i2c.c */ 344/* In tm6000-i2c.c */
329int tm6000_i2c_register(struct tm6000_core *dev); 345int tm6000_i2c_register(struct tm6000_core *dev);