aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/video4linux/CARDLIST.tuner1
-rw-r--r--drivers/media/common/tuners/Kconfig10
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/tuner-types.c4
-rw-r--r--drivers/media/common/tuners/xc4000.c1083
-rw-r--r--drivers/media/common/tuners/xc4000.h61
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c68
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/video/tuner-core.c14
-rw-r--r--include/media/tuner.h2
10 files changed, 1245 insertions, 0 deletions
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 562d7fa20f6d..6323b7a20719 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -78,6 +78,7 @@ tuner=77 - TCL tuner MF02GIP-5N-E
78tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner 78tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
79tuner=79 - Philips PAL/SECAM multi (FM1216 MK5) 79tuner=79 - Philips PAL/SECAM multi (FM1216 MK5)
80tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough 80tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
81tuner=81 - Xceive 4000 tuner
81tuner=81 - Partsnic (Daewoo) PTI-5NF05 82tuner=81 - Partsnic (Daewoo) PTI-5NF05
82tuner=82 - Philips CU1216L 83tuner=82 - Philips CU1216L
83tuner=83 - NXP TDA18271 84tuner=83 - NXP TDA18271
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 22d3ca36370e..996302ae210e 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -23,6 +23,7 @@ config MEDIA_TUNER
23 depends on VIDEO_MEDIA && I2C 23 depends on VIDEO_MEDIA && I2C
24 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE 24 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
25 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE 25 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
26 select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
26 select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE 27 select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
27 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE 28 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
28 select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE 29 select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
@@ -152,6 +153,15 @@ config MEDIA_TUNER_XC5000
152 This device is only used inside a SiP called together with a 153 This device is only used inside a SiP called together with a
153 demodulator for now. 154 demodulator for now.
154 155
156config MEDIA_TUNER_XC4000
157 tristate "Xceive XC4000 silicon tuner"
158 depends on VIDEO_MEDIA && I2C
159 default m if MEDIA_TUNER_CUSTOMISE
160 help
161 A driver for the silicon tuner XC4000 from Xceive.
162 This device is only used inside a SiP called together with a
163 demodulator for now.
164
155config MEDIA_TUNER_MXL5005S 165config MEDIA_TUNER_MXL5005S
156 tristate "MaxLinear MSL5005S silicon tuner" 166 tristate "MaxLinear MSL5005S silicon tuner"
157 depends on VIDEO_MEDIA && I2C 167 depends on VIDEO_MEDIA && I2C
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 2cb4f5327843..20d24fca2cfb 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o
16obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o 16obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
17obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o 17obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
18obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o 18obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
19obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
19obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o 20obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
20obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o 21obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
21obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o 22obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index afba6dc5e080..94a603a60842 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1805,6 +1805,10 @@ struct tunertype tuners[] = {
1805 .name = "Xceive 5000 tuner", 1805 .name = "Xceive 5000 tuner",
1806 /* see xc5000.c for details */ 1806 /* see xc5000.c for details */
1807 }, 1807 },
1808 [TUNER_XC4000] = { /* Xceive 4000 */
1809 .name = "Xceive 4000 tuner",
1810 /* see xc4000.c for details */
1811 },
1808 [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */ 1812 [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
1809 .name = "TCL tuner MF02GIP-5N-E", 1813 .name = "TCL tuner MF02GIP-5N-E",
1810 .params = tuner_tcl_mf02gip_5n_params, 1814 .params = tuner_tcl_mf02gip_5n_params,
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
new file mode 100644
index 000000000000..68f5e2beee1e
--- /dev/null
+++ b/drivers/media/common/tuners/xc4000.c
@@ -0,0 +1,1083 @@
1/*
2 * Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 * Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/videodev2.h>
28#include <linux/delay.h>
29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h>
31
32#include "dvb_frontend.h"
33
34#include "xc4000.h"
35#include "tuner-i2c.h"
36
37static int debug;
38module_param(debug, int, 0644);
39MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
40
41static int no_poweroff;
42module_param(no_poweroff, int, 0644);
43MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
44 "\t\t1 keep device energized and with tuner ready all the times.\n"
45 "\t\tFaster, but consumes more power and keeps the device hotter");
46
47static DEFINE_MUTEX(xc4000_list_mutex);
48static LIST_HEAD(hybrid_tuner_instance_list);
49
50#define dprintk(level, fmt, arg...) if (debug >= level) \
51 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
52
53#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.26.fw"
54#define XC4000_DEFAULT_FIRMWARE_SIZE 8236
55
56struct xc4000_priv {
57 struct tuner_i2c_props i2c_props;
58 struct list_head hybrid_tuner_instance_list;
59
60 u32 if_khz;
61 u32 freq_hz;
62 u32 bandwidth;
63 u8 video_standard;
64 u8 rf_mode;
65};
66
67/* Misc Defines */
68#define MAX_TV_STANDARD 23
69#define XC_MAX_I2C_WRITE_LENGTH 64
70
71/* Signal Types */
72#define XC_RF_MODE_AIR 0
73#define XC_RF_MODE_CABLE 1
74
75/* Result codes */
76#define XC_RESULT_SUCCESS 0
77#define XC_RESULT_RESET_FAILURE 1
78#define XC_RESULT_I2C_WRITE_FAILURE 2
79#define XC_RESULT_I2C_READ_FAILURE 3
80#define XC_RESULT_OUT_OF_RANGE 5
81
82/* Product id */
83#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
84#define XC_PRODUCT_ID_FW_LOADED 0x0FA0 /* WAS: 0x1388*/
85
86/* Registers */
87#define XREG_INIT 0x00
88#define XREG_VIDEO_MODE 0x01
89#define XREG_AUDIO_MODE 0x02
90#define XREG_RF_FREQ 0x03
91#define XREG_D_CODE 0x04
92#define XREG_IF_OUT 0x05 /* ?? */
93#define XREG_SEEK_MODE 0x07 /* WAS: 0x06 */
94#define XREG_POWER_DOWN 0x08 /* WAS: 0x0A Obsolete */
95#define XREG_SIGNALSOURCE 0x0A /* WAS: 0x0D 0=Air, 1=Cable */
96//#define XREG_SMOOTHEDCVBS 0x0E
97//#define XREG_XTALFREQ 0x0F
98//#define XREG_FINERFREQ 0x10
99//#define XREG_DDIMODE 0x11
100
101#define XREG_ADC_ENV 0x00
102#define XREG_QUALITY 0x01
103#define XREG_FRAME_LINES 0x02
104#define XREG_HSYNC_FREQ 0x03
105#define XREG_LOCK 0x04
106#define XREG_FREQ_ERROR 0x05
107#define XREG_SNR 0x06
108#define XREG_VERSION 0x07
109#define XREG_PRODUCT_ID 0x08
110//#define XREG_BUSY 0x09
111//#define XREG_BUILD 0x0D
112
113/*
114 Basic firmware description. This will remain with
115 the driver for documentation purposes.
116
117 This represents an I2C firmware file encoded as a
118 string of unsigned char. Format is as follows:
119
120 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
121 char[1 ]=len0_LSB -> length of first write transaction
122 char[2 ]=data0 -> first byte to be sent
123 char[3 ]=data1
124 char[4 ]=data2
125 char[ ]=...
126 char[M ]=dataN -> last byte to be sent
127 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
128 char[M+2]=len1_LSB -> length of second write transaction
129 char[M+3]=data0
130 char[M+4]=data1
131 ...
132 etc.
133
134 The [len] value should be interpreted as follows:
135
136 len= len_MSB _ len_LSB
137 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
138 len=0000_0000_0000_0000 : Reset command: Do hardware reset
139 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
140 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
141
142 For the RESET and WAIT commands, the two following bytes will contain
143 immediately the length of the following transaction.
144
145*/
146struct XC_TV_STANDARD {
147 char *Name;
148 u16 AudioMode;
149 u16 VideoMode;
150};
151
152/* Tuner standards */
153#define MN_NTSC_PAL_BTSC 0
154#define MN_NTSC_PAL_A2 1
155#define MN_NTSC_PAL_EIAJ 2
156#define MN_NTSC_PAL_Mono 3
157#define BG_PAL_A2 4
158#define BG_PAL_NICAM 5
159#define BG_PAL_MONO 6
160#define I_PAL_NICAM 7
161#define I_PAL_NICAM_MONO 8
162#define DK_PAL_A2 9
163#define DK_PAL_NICAM 10
164#define DK_PAL_MONO 11
165#define DK_SECAM_A2DK1 12
166#define DK_SECAM_A2LDK3 13
167#define DK_SECAM_A2MONO 14
168#define L_SECAM_NICAM 15
169#define LC_SECAM_NICAM 16
170#define DTV6 17
171#define DTV8 18
172#define DTV7_8 19
173#define DTV7 20
174#define FM_Radio_INPUT2 21
175#define FM_Radio_INPUT1 22
176
177/* WAS :
178static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
179 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
180 {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
181 {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
182 {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
183 {"B/G-PAL-A2", 0x0A00, 0x8049},
184 {"B/G-PAL-NICAM", 0x0C04, 0x8049},
185 {"B/G-PAL-MONO", 0x0878, 0x8059},
186 {"I-PAL-NICAM", 0x1080, 0x8009},
187 {"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
188 {"D/K-PAL-A2", 0x1600, 0x8009},
189 {"D/K-PAL-NICAM", 0x0E80, 0x8009},
190 {"D/K-PAL-MONO", 0x1478, 0x8009},
191 {"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
192 {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
193 {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
194 {"L-SECAM-NICAM", 0x8E82, 0x0009},
195 {"L'-SECAM-NICAM", 0x8E82, 0x4009},
196 {"DTV6", 0x00C0, 0x8002},
197 {"DTV8", 0x00C0, 0x800B},
198 {"DTV7/8", 0x00C0, 0x801B},
199 {"DTV7", 0x00C0, 0x8007},
200 {"FM Radio-INPUT2", 0x9802, 0x9002},
201 {"FM Radio-INPUT1", 0x0208, 0x9002}
202};*/
203
204static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
205 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x8020},
206 {"M/N-NTSC/PAL-A2", 0x0000, 0x8020},
207 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x8020},
208 {"M/N-NTSC/PAL-Mono", 0x0078, 0x8020},
209 {"B/G-PAL-A2", 0x0000, 0x8059},
210 {"B/G-PAL-NICAM", 0x0004, 0x8059},
211 {"B/G-PAL-MONO", 0x0078, 0x8059},
212 {"I-PAL-NICAM", 0x0080, 0x8049},
213 {"I-PAL-NICAM-MONO", 0x0078, 0x8049},
214 {"D/K-PAL-A2", 0x0000, 0x8049},
215 {"D/K-PAL-NICAM", 0x0080, 0x8049},
216 {"D/K-PAL-MONO", 0x0078, 0x8049},
217 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049},
218 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049},
219 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049},
220 {"L-SECAM-NICAM", 0x8080, 0x0009},
221 {"L'-SECAM-NICAM", 0x8080, 0x4009},
222 {"DTV6", 0x00C0, 0x8002},
223 {"DTV8", 0x00C0, 0x800B},
224 {"DTV7/8", 0x00C0, 0x801B},
225 {"DTV7", 0x00C0, 0x8007},
226 {"FM Radio-INPUT2", 0x0008, 0x9800},
227 {"FM Radio-INPUT1", 0x0008, 0x9000}
228};
229
230static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
231static int xc4000_is_firmware_loaded(struct dvb_frontend *fe);
232static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
233static int xc4000_TunerReset(struct dvb_frontend *fe);
234
235static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
236{
237 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
238 .flags = 0, .buf = buf, .len = len };
239
240 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
241 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n", len);
242 return XC_RESULT_I2C_WRITE_FAILURE;
243 }
244 return XC_RESULT_SUCCESS;
245}
246
247/* This routine is never used because the only time we read data from the
248 i2c bus is when we read registers, and we want that to be an atomic i2c
249 transaction in case we are on a multi-master bus */
250static int xc_read_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
251{
252 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
253 .flags = I2C_M_RD, .buf = buf, .len = len };
254
255 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
256 printk(KERN_ERR "xc4000 I2C read failed (len=%i)\n", len);
257 return -EREMOTEIO;
258 }
259 return 0;
260}
261
262static void xc_wait(int wait_ms)
263{
264 msleep(wait_ms);
265}
266
267static int xc4000_TunerReset(struct dvb_frontend *fe)
268{
269 struct xc4000_priv *priv = fe->tuner_priv;
270 int ret;
271
272 dprintk(1, "%s()\n", __func__);
273
274 if (fe->callback) {
275 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
276 fe->dvb->priv :
277 priv->i2c_props.adap->algo_data,
278 DVB_FRONTEND_COMPONENT_TUNER,
279 XC4000_TUNER_RESET, 0);
280 if (ret) {
281 printk(KERN_ERR "xc4000: reset failed\n");
282 return XC_RESULT_RESET_FAILURE;
283 }
284 } else {
285 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
286 return XC_RESULT_RESET_FAILURE;
287 }
288 return XC_RESULT_SUCCESS;
289}
290
291static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
292{
293 u8 buf[4];
294// int WatchDogTimer = 100;
295 int result;
296
297 buf[0] = (regAddr >> 8) & 0xFF;
298 buf[1] = regAddr & 0xFF;
299 buf[2] = (i2cData >> 8) & 0xFF;
300 buf[3] = i2cData & 0xFF;
301 result = xc_send_i2c_data(priv, buf, 4);
302//WAS THERE
303// if (result == XC_RESULT_SUCCESS) {
304// /* wait for busy flag to clear */
305// while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
306// buf[0] = 0;
307// buf[1] = XREG_BUSY;
308//
309// result = xc_send_i2c_data(priv, buf, 2);
310// if (result == XC_RESULT_SUCCESS) {
311// result = xc_read_i2c_data(priv, buf, 2);
312// if (result == XC_RESULT_SUCCESS) {
313// if ((buf[0] == 0) && (buf[1] == 0)) {
314// /* busy flag cleared */
315// break;
316// } else {
317// xc_wait(5); /* wait 5 ms */
318// WatchDogTimer--;
319// }
320// }
321// }
322// }
323// }
324// if (WatchDogTimer < 0)
325// result = XC_RESULT_I2C_WRITE_FAILURE;
326
327 return result;
328}
329
330static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
331{
332 struct xc4000_priv *priv = fe->tuner_priv;
333
334 int i, nbytes_to_send, result;
335 unsigned int len, pos, index;
336 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
337
338 index = 0;
339 while ((i2c_sequence[index] != 0xFF) ||
340 (i2c_sequence[index + 1] != 0xFF)) {
341 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
342 if (len == 0x0000) {
343 /* RESET command */
344 result = xc4000_TunerReset(fe);
345 index += 2;
346 if (result != XC_RESULT_SUCCESS)
347 return result;
348 } else if (len & 0x8000) {
349 /* WAIT command */
350 xc_wait(len & 0x7FFF);
351 index += 2;
352 } else {
353 /* Send i2c data whilst ensuring individual transactions
354 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
355 */
356 index += 2;
357 buf[0] = i2c_sequence[index];
358 buf[1] = i2c_sequence[index + 1];
359 pos = 2;
360 while (pos < len) {
361 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
362 nbytes_to_send =
363 XC_MAX_I2C_WRITE_LENGTH;
364 else
365 nbytes_to_send = (len - pos + 2);
366 for (i = 2; i < nbytes_to_send; i++) {
367 buf[i] = i2c_sequence[index + pos +
368 i - 2];
369 }
370 result = xc_send_i2c_data(priv, buf,
371 nbytes_to_send);
372
373 if (result != XC_RESULT_SUCCESS)
374 return result;
375
376 pos += nbytes_to_send - 2;
377 }
378 index += len;
379 }
380 }
381 return XC_RESULT_SUCCESS;
382}
383
384static int xc_initialize(struct xc4000_priv *priv)
385{
386 dprintk(1, "%s()\n", __func__);
387 return xc_write_reg(priv, XREG_INIT, 0);
388}
389
390static int xc_SetTVStandard(struct xc4000_priv *priv,
391 u16 VideoMode, u16 AudioMode)
392{
393 int ret;
394 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
395 dprintk(1, "%s() Standard = %s\n",
396 __func__,
397 XC4000_Standard[priv->video_standard].Name);
398
399 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
400 if (ret == XC_RESULT_SUCCESS)
401 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
402
403 return ret;
404}
405
406static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
407{
408 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
409 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
410
411 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
412 rf_mode = XC_RF_MODE_CABLE;
413 printk(KERN_ERR
414 "%s(), Invalid mode, defaulting to CABLE",
415 __func__);
416 }
417 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
418}
419
420static const struct dvb_tuner_ops xc4000_tuner_ops;
421
422static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
423{
424 u16 freq_code;
425
426 dprintk(1, "%s(%u)\n", __func__, freq_hz);
427
428 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
429 (freq_hz < xc4000_tuner_ops.info.frequency_min))
430 return XC_RESULT_OUT_OF_RANGE;
431
432 freq_code = (u16)(freq_hz / 15625);
433
434 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
435 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
436 only be used for fast scanning for channel lock) */
437 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
438}
439
440
441static int xc_set_IF_frequency(struct xc4000_priv *priv, u32 freq_khz)
442{
443 u32 freq_code = (freq_khz * 1024)/1000;
444 dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
445 __func__, freq_khz, freq_code);
446
447 return xc_write_reg(priv, XREG_IF_OUT, freq_code);
448}
449
450
451static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
452{
453 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
454}
455
456static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
457{
458 int result;
459 u16 regData;
460 u32 tmp;
461
462 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
463 if (result != XC_RESULT_SUCCESS)
464 return result;
465
466 tmp = (u32)regData;
467 (*freq_error_hz) = (tmp * 15625) / 1000;
468 return result;
469}
470
471static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
472{
473 return xc4000_readreg(priv, XREG_LOCK, lock_status);
474}
475
476static int xc_get_version(struct xc4000_priv *priv,
477 u8 *hw_majorversion, u8 *hw_minorversion,
478 u8 *fw_majorversion, u8 *fw_minorversion)
479{
480 u16 data;
481 int result;
482
483 result = xc4000_readreg(priv, XREG_VERSION, &data);
484 if (result != XC_RESULT_SUCCESS)
485 return result;
486
487 (*hw_majorversion) = (data >> 12) & 0x0F;
488 (*hw_minorversion) = (data >> 8) & 0x0F;
489 (*fw_majorversion) = (data >> 4) & 0x0F;
490 (*fw_minorversion) = data & 0x0F;
491
492 return 0;
493}
494
495/* WAS THERE
496static int xc_get_buildversion(struct xc4000_priv *priv, u16 *buildrev)
497{
498 return xc4000_readreg(priv, XREG_BUILD, buildrev);
499}*/
500
501static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
502{
503 u16 regData;
504 int result;
505
506 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
507 if (result != XC_RESULT_SUCCESS)
508 return result;
509
510 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
511 return result;
512}
513
514static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
515{
516 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
517}
518
519static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
520{
521 return xc4000_readreg(priv, XREG_QUALITY, quality);
522}
523
524static u16 WaitForLock(struct xc4000_priv *priv)
525{
526 u16 lockState = 0;
527 int watchDogCount = 40;
528
529 while ((lockState == 0) && (watchDogCount > 0)) {
530 xc_get_lock_status(priv, &lockState);
531 if (lockState != 1) {
532 xc_wait(5);
533 watchDogCount--;
534 }
535 }
536 return lockState;
537}
538
539#define XC_TUNE_ANALOG 0
540#define XC_TUNE_DIGITAL 1
541static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
542{
543 int found = 0;
544
545 dprintk(1, "%s(%u)\n", __func__, freq_hz);
546
547 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
548 return 0;
549
550 if (mode == XC_TUNE_ANALOG) {
551 if (WaitForLock(priv) == 1)
552 found = 1;
553 }
554
555 return found;
556}
557
558static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
559{
560 u8 buf[2] = { reg >> 8, reg & 0xff };
561 u8 bval[2] = { 0, 0 };
562 struct i2c_msg msg[2] = {
563 { .addr = priv->i2c_props.addr,
564 .flags = 0, .buf = &buf[0], .len = 2 },
565 { .addr = priv->i2c_props.addr,
566 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
567 };
568
569 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
570 printk(KERN_WARNING "xc4000: I2C read failed\n");
571 return -EREMOTEIO;
572 }
573
574 *val = (bval[0] << 8) | bval[1];
575 return XC_RESULT_SUCCESS;
576}
577
578static int xc4000_fwupload(struct dvb_frontend *fe)
579{
580 struct xc4000_priv *priv = fe->tuner_priv;
581 const struct firmware *fw;
582 int ret;
583
584 /* request the firmware, this will block and timeout */
585 printk(KERN_INFO "xc4000: waiting for firmware upload (%s)...\n",
586 XC4000_DEFAULT_FIRMWARE);
587
588 ret = request_firmware(&fw, XC4000_DEFAULT_FIRMWARE,
589 priv->i2c_props.adap->dev.parent);
590 if (ret) {
591 printk(KERN_ERR "xc4000: Upload failed. (file not found?)\n");
592 ret = XC_RESULT_RESET_FAILURE;
593 goto out;
594 } else {
595 printk(KERN_DEBUG "xc4000: firmware read %Zu bytes.\n",
596 fw->size);
597 ret = XC_RESULT_SUCCESS;
598 }
599
600 if (fw->size != XC4000_DEFAULT_FIRMWARE_SIZE) {
601 printk(KERN_ERR "xc4000: firmware incorrect size\n");
602 ret = XC_RESULT_RESET_FAILURE;
603 } else {
604 printk(KERN_INFO "xc4000: firmware uploading...\n");
605 ret = xc_load_i2c_sequence(fe, fw->data);
606 printk(KERN_INFO "xc4000: firmware upload complete...\n");
607 }
608
609out:
610 release_firmware(fw);
611 return ret;
612}
613
614static void xc_debug_dump(struct xc4000_priv *priv)
615{
616 u16 adc_envelope;
617 u32 freq_error_hz = 0;
618 u16 lock_status;
619 u32 hsync_freq_hz = 0;
620 u16 frame_lines;
621 u16 quality;
622 u8 hw_majorversion = 0, hw_minorversion = 0;
623 u8 fw_majorversion = 0, fw_minorversion = 0;
624// u16 fw_buildversion = 0;
625
626 /* Wait for stats to stabilize.
627 * Frame Lines needs two frame times after initial lock
628 * before it is valid.
629 */
630 xc_wait(100);
631
632 xc_get_ADC_Envelope(priv, &adc_envelope);
633 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
634
635 xc_get_frequency_error(priv, &freq_error_hz);
636 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
637
638 xc_get_lock_status(priv, &lock_status);
639 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
640 lock_status);
641
642 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
643 &fw_majorversion, &fw_minorversion);
644// WAS:
645// xc_get_buildversion(priv, &fw_buildversion);
646// dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
647// hw_majorversion, hw_minorversion,
648// fw_majorversion, fw_minorversion, fw_buildversion);
649// NOW:
650 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
651 hw_majorversion, hw_minorversion,
652 fw_majorversion, fw_minorversion);
653
654 xc_get_hsync_freq(priv, &hsync_freq_hz);
655 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
656
657 xc_get_frame_lines(priv, &frame_lines);
658 dprintk(1, "*** Frame lines = %d\n", frame_lines);
659
660 xc_get_quality(priv, &quality);
661 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
662}
663
664static int xc4000_set_params(struct dvb_frontend *fe,
665 struct dvb_frontend_parameters *params)
666{
667 struct xc4000_priv *priv = fe->tuner_priv;
668 int ret;
669
670 if (xc4000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
671 xc_load_fw_and_init_tuner(fe);
672
673 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
674
675 if (fe->ops.info.type == FE_ATSC) {
676 dprintk(1, "%s() ATSC\n", __func__);
677 switch (params->u.vsb.modulation) {
678 case VSB_8:
679 case VSB_16:
680 dprintk(1, "%s() VSB modulation\n", __func__);
681 priv->rf_mode = XC_RF_MODE_AIR;
682 priv->freq_hz = params->frequency - 1750000;
683 priv->bandwidth = BANDWIDTH_6_MHZ;
684 priv->video_standard = DTV6;
685 break;
686 case QAM_64:
687 case QAM_256:
688 case QAM_AUTO:
689 dprintk(1, "%s() QAM modulation\n", __func__);
690 priv->rf_mode = XC_RF_MODE_CABLE;
691 priv->freq_hz = params->frequency - 1750000;
692 priv->bandwidth = BANDWIDTH_6_MHZ;
693 priv->video_standard = DTV6;
694 break;
695 default:
696 return -EINVAL;
697 }
698 } else if (fe->ops.info.type == FE_OFDM) {
699 dprintk(1, "%s() OFDM\n", __func__);
700 switch (params->u.ofdm.bandwidth) {
701 case BANDWIDTH_6_MHZ:
702 priv->bandwidth = BANDWIDTH_6_MHZ;
703 priv->video_standard = DTV6;
704 priv->freq_hz = params->frequency - 1750000;
705 break;
706 case BANDWIDTH_7_MHZ:
707 printk(KERN_ERR "xc4000 bandwidth 7MHz not supported\n");
708 return -EINVAL;
709 case BANDWIDTH_8_MHZ:
710 priv->bandwidth = BANDWIDTH_8_MHZ;
711 priv->video_standard = DTV8;
712 priv->freq_hz = params->frequency - 2750000;
713 break;
714 default:
715 printk(KERN_ERR "xc4000 bandwidth not set!\n");
716 return -EINVAL;
717 }
718 priv->rf_mode = XC_RF_MODE_AIR;
719 } else {
720 printk(KERN_ERR "xc4000 modulation type not supported!\n");
721 return -EINVAL;
722 }
723
724 dprintk(1, "%s() frequency=%d (compensated)\n",
725 __func__, priv->freq_hz);
726
727 ret = xc_SetSignalSource(priv, priv->rf_mode);
728 if (ret != XC_RESULT_SUCCESS) {
729 printk(KERN_ERR
730 "xc4000: xc_SetSignalSource(%d) failed\n",
731 priv->rf_mode);
732 return -EREMOTEIO;
733 }
734
735 ret = xc_SetTVStandard(priv,
736 XC4000_Standard[priv->video_standard].VideoMode,
737 XC4000_Standard[priv->video_standard].AudioMode);
738 if (ret != XC_RESULT_SUCCESS) {
739 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
740 return -EREMOTEIO;
741 }
742
743 ret = xc_set_IF_frequency(priv, priv->if_khz);
744 if (ret != XC_RESULT_SUCCESS) {
745 printk(KERN_ERR "xc4000: xc_Set_IF_frequency(%d) failed\n",
746 priv->if_khz);
747 return -EIO;
748 }
749
750 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
751
752 if (debug)
753 xc_debug_dump(priv);
754
755 return 0;
756}
757
758static int xc4000_is_firmware_loaded(struct dvb_frontend *fe)
759{
760 struct xc4000_priv *priv = fe->tuner_priv;
761 int ret;
762 u16 id;
763
764 ret = xc4000_readreg(priv, XREG_PRODUCT_ID, &id);
765 if (ret == XC_RESULT_SUCCESS) {
766 if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
767 ret = XC_RESULT_RESET_FAILURE;
768 else
769 ret = XC_RESULT_SUCCESS;
770 }
771
772 dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
773 ret == XC_RESULT_SUCCESS ? "True" : "False", id);
774 return ret;
775}
776
777static int xc4000_set_analog_params(struct dvb_frontend *fe,
778 struct analog_parameters *params)
779{
780 struct xc4000_priv *priv = fe->tuner_priv;
781 int ret;
782
783 if (xc4000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
784 xc_load_fw_and_init_tuner(fe);
785
786 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
787 __func__, params->frequency);
788
789 /* Fix me: it could be air. */
790 priv->rf_mode = params->mode;
791 if (params->mode > XC_RF_MODE_CABLE)
792 priv->rf_mode = XC_RF_MODE_CABLE;
793
794 /* params->frequency is in units of 62.5khz */
795 priv->freq_hz = params->frequency * 62500;
796
797 /* FIX ME: Some video standards may have several possible audio
798 standards. We simply default to one of them here.
799 */
800 if (params->std & V4L2_STD_MN) {
801 /* default to BTSC audio standard */
802 priv->video_standard = MN_NTSC_PAL_BTSC;
803 goto tune_channel;
804 }
805
806 if (params->std & V4L2_STD_PAL_BG) {
807 /* default to NICAM audio standard */
808 priv->video_standard = BG_PAL_NICAM;
809 goto tune_channel;
810 }
811
812 if (params->std & V4L2_STD_PAL_I) {
813 /* default to NICAM audio standard */
814 priv->video_standard = I_PAL_NICAM;
815 goto tune_channel;
816 }
817
818 if (params->std & V4L2_STD_PAL_DK) {
819 /* default to NICAM audio standard */
820 priv->video_standard = DK_PAL_NICAM;
821 goto tune_channel;
822 }
823
824 if (params->std & V4L2_STD_SECAM_DK) {
825 /* default to A2 DK1 audio standard */
826 priv->video_standard = DK_SECAM_A2DK1;
827 goto tune_channel;
828 }
829
830 if (params->std & V4L2_STD_SECAM_L) {
831 priv->video_standard = L_SECAM_NICAM;
832 goto tune_channel;
833 }
834
835 if (params->std & V4L2_STD_SECAM_LC) {
836 priv->video_standard = LC_SECAM_NICAM;
837 goto tune_channel;
838 }
839
840tune_channel:
841 ret = xc_SetSignalSource(priv, priv->rf_mode);
842 if (ret != XC_RESULT_SUCCESS) {
843 printk(KERN_ERR
844 "xc4000: xc_SetSignalSource(%d) failed\n",
845 priv->rf_mode);
846 return -EREMOTEIO;
847 }
848
849 ret = xc_SetTVStandard(priv,
850 XC4000_Standard[priv->video_standard].VideoMode,
851 XC4000_Standard[priv->video_standard].AudioMode);
852 if (ret != XC_RESULT_SUCCESS) {
853 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
854 return -EREMOTEIO;
855 }
856
857 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
858
859 if (debug)
860 xc_debug_dump(priv);
861
862 return 0;
863}
864
865static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
866{
867 struct xc4000_priv *priv = fe->tuner_priv;
868 dprintk(1, "%s()\n", __func__);
869 *freq = priv->freq_hz;
870 return 0;
871}
872
873static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
874{
875 struct xc4000_priv *priv = fe->tuner_priv;
876 dprintk(1, "%s()\n", __func__);
877
878 *bw = priv->bandwidth;
879 return 0;
880}
881
882static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
883{
884 struct xc4000_priv *priv = fe->tuner_priv;
885 u16 lock_status = 0;
886
887 xc_get_lock_status(priv, &lock_status);
888
889 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
890
891 *status = lock_status;
892
893 return 0;
894}
895
896static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
897{
898 struct xc4000_priv *priv = fe->tuner_priv;
899 int ret = 0;
900
901 if (xc4000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
902 ret = xc4000_fwupload(fe);
903 if (ret != XC_RESULT_SUCCESS)
904 return ret;
905 }
906
907 /* Start the tuner self-calibration process */
908 ret |= xc_initialize(priv);
909
910 /* Wait for calibration to complete.
911 * We could continue but XC4000 will clock stretch subsequent
912 * I2C transactions until calibration is complete. This way we
913 * don't have to rely on clock stretching working.
914 */
915 xc_wait(100);
916
917 /* Default to "CABLE" mode */
918 ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
919
920 return ret;
921}
922
923static int xc4000_sleep(struct dvb_frontend *fe)
924{
925 int ret;
926
927 dprintk(1, "%s()\n", __func__);
928
929 /* Avoid firmware reload on slow devices */
930 if (no_poweroff)
931 return 0;
932
933 /* According to Xceive technical support, the "powerdown" register
934 was removed in newer versions of the firmware. The "supported"
935 way to sleep the tuner is to pull the reset pin low for 10ms */
936 ret = xc4000_TunerReset(fe);
937 if (ret != XC_RESULT_SUCCESS) {
938 printk(KERN_ERR
939 "xc4000: %s() unable to shutdown tuner\n",
940 __func__);
941 return -EREMOTEIO;
942 } else
943 return XC_RESULT_SUCCESS;
944}
945
946static int xc4000_init(struct dvb_frontend *fe)
947{
948 struct xc4000_priv *priv = fe->tuner_priv;
949 dprintk(1, "%s()\n", __func__);
950
951 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
952 printk(KERN_ERR "xc4000: Unable to initialise tuner\n");
953 return -EREMOTEIO;
954 }
955
956 if (debug)
957 xc_debug_dump(priv);
958
959 return 0;
960}
961
962static int xc4000_release(struct dvb_frontend *fe)
963{
964 struct xc4000_priv *priv = fe->tuner_priv;
965
966 dprintk(1, "%s()\n", __func__);
967
968 mutex_lock(&xc4000_list_mutex);
969
970 if (priv)
971 hybrid_tuner_release_state(priv);
972
973 mutex_unlock(&xc4000_list_mutex);
974
975 fe->tuner_priv = NULL;
976
977 return 0;
978}
979
980static const struct dvb_tuner_ops xc4000_tuner_ops = {
981 .info = {
982 .name = "Xceive XC4000",
983 .frequency_min = 1000000,
984 .frequency_max = 1023000000,
985 .frequency_step = 50000,
986 },
987
988 .release = xc4000_release,
989 .init = xc4000_init,
990 .sleep = xc4000_sleep,
991
992 .set_params = xc4000_set_params,
993 .set_analog_params = xc4000_set_analog_params,
994 .get_frequency = xc4000_get_frequency,
995 .get_bandwidth = xc4000_get_bandwidth,
996 .get_status = xc4000_get_status
997};
998
999struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1000 struct i2c_adapter *i2c,
1001 struct xc4000_config *cfg)
1002{
1003 struct xc4000_priv *priv = NULL;
1004 int instance;
1005 u16 id = 0;
1006
1007 dprintk(1, "%s(%d-%04x)\n", __func__,
1008 i2c ? i2c_adapter_id(i2c) : -1,
1009 cfg ? cfg->i2c_address : -1);
1010
1011 mutex_lock(&xc4000_list_mutex);
1012
1013 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1014 hybrid_tuner_instance_list,
1015 i2c, cfg->i2c_address, "xc4000");
1016 switch (instance) {
1017 case 0:
1018 goto fail;
1019 break;
1020 case 1:
1021 /* new tuner instance */
1022 priv->bandwidth = BANDWIDTH_6_MHZ;
1023 fe->tuner_priv = priv;
1024 break;
1025 default:
1026 /* existing tuner instance */
1027 fe->tuner_priv = priv;
1028 break;
1029 }
1030
1031 if (priv->if_khz == 0) {
1032 /* If the IF hasn't been set yet, use the value provided by
1033 the caller (occurs in hybrid devices where the analog
1034 call to xc4000_attach occurs before the digital side) */
1035 priv->if_khz = cfg->if_khz;
1036 }
1037
1038 /* Check if firmware has been loaded. It is possible that another
1039 instance of the driver has loaded the firmware.
1040 */
1041
1042 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
1043 goto fail;
1044
1045 switch (id) {
1046 case XC_PRODUCT_ID_FW_LOADED:
1047 printk(KERN_INFO
1048 "xc4000: Successfully identified at address 0x%02x\n",
1049 cfg->i2c_address);
1050 printk(KERN_INFO
1051 "xc4000: Firmware has been loaded previously\n");
1052 break;
1053 case XC_PRODUCT_ID_FW_NOT_LOADED:
1054 printk(KERN_INFO
1055 "xc4000: Successfully identified at address 0x%02x\n",
1056 cfg->i2c_address);
1057 printk(KERN_INFO
1058 "xc4000: Firmware has not been loaded previously\n");
1059 break;
1060 default:
1061 printk(KERN_ERR
1062 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1063 cfg->i2c_address, id);
1064 goto fail;
1065 }
1066
1067 mutex_unlock(&xc4000_list_mutex);
1068
1069 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1070 sizeof(struct dvb_tuner_ops));
1071
1072 return fe;
1073fail:
1074 mutex_unlock(&xc4000_list_mutex);
1075
1076 xc4000_release(fe);
1077 return NULL;
1078}
1079EXPORT_SYMBOL(xc4000_attach);
1080
1081MODULE_AUTHOR("Steven Toth, Davide Ferri");
1082MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1083MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/xc4000.h b/drivers/media/common/tuners/xc4000.h
new file mode 100644
index 000000000000..2bbbe9d6480b
--- /dev/null
+++ b/drivers/media/common/tuners/xc4000.h
@@ -0,0 +1,61 @@
1/*
2 * Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
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 __XC4000_H__
23#define __XC4000_H__
24
25#include <linux/firmware.h>
26
27struct dvb_frontend;
28struct i2c_adapter;
29
30struct xc4000_config {
31 u8 i2c_address;
32 u32 if_khz;
33};
34
35/* xc4000 callback command */
36#define XC4000_TUNER_RESET 0
37
38/* For each bridge framework, when it attaches either analog or digital,
39 * it has to store a reference back to its _core equivalent structure,
40 * so that it can service the hardware by steering gpio's etc.
41 * Each bridge implementation is different so cast devptr accordingly.
42 * The xc4000 driver cares not for this value, other than ensuring
43 * it's passed back to a bridge during tuner_callback().
44 */
45
46#if defined(CONFIG_MEDIA_TUNER_XC4000) || \
47 (defined(CONFIG_MEDIA_TUNER_XC4000_MODULE) && defined(MODULE))
48extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
49 struct i2c_adapter *i2c,
50 struct xc4000_config *cfg);
51#else
52static inline struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
53 struct i2c_adapter *i2c,
54 struct xc4000_config *cfg)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59#endif
60
61#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index c519ad5eb731..a79c4ea9d7ed 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -17,6 +17,7 @@
17#include "mt2266.h" 17#include "mt2266.h"
18#include "tuner-xc2028.h" 18#include "tuner-xc2028.h"
19#include "xc5000.h" 19#include "xc5000.h"
20#include "xc4000.h"
20#include "s5h1411.h" 21#include "s5h1411.h"
21#include "dib0070.h" 22#include "dib0070.h"
22#include "dib0090.h" 23#include "dib0090.h"
@@ -2655,6 +2656,41 @@ static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
2655 == NULL ? -ENODEV : 0; 2656 == NULL ? -ENODEV : 0;
2656} 2657}
2657 2658
2659static int dib0700_xc4000_tuner_callback(void *priv, int component,
2660 int command, int arg)
2661{
2662 struct dvb_usb_adapter *adap = priv;
2663
2664 if (command == XC4000_TUNER_RESET) {
2665 /* Reset the tuner */
2666 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
2667 msleep(10);
2668 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
2669 msleep(10);
2670 } else {
2671 err("xc4000: unknown tuner callback command: %d\n", command);
2672 return -EINVAL;
2673 }
2674
2675 return 0;
2676}
2677
2678static struct xc4000_config s5h1411_xc4000_tunerconfig = {
2679 .i2c_address = 0x64,
2680 .if_khz = 5380,
2681};
2682
2683static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
2684{
2685 err("xc4000: xc4000_tuner_attach");
2686 /* FIXME: generalize & move to common area */
2687 adap->fe->callback = dib0700_xc4000_tuner_callback;
2688
2689 return dvb_attach(xc4000_attach, adap->fe, &adap->dev->i2c_adap,
2690 &s5h1411_xc4000_tunerconfig)
2691 == NULL ? -ENODEV : 0;
2692}
2693
2658static struct lgdt3305_config hcw_lgdt3305_config = { 2694static struct lgdt3305_config hcw_lgdt3305_config = {
2659 .i2c_addr = 0x0e, 2695 .i2c_addr = 0x0e,
2660 .mpeg_mode = LGDT3305_MPEG_PARALLEL, 2696 .mpeg_mode = LGDT3305_MPEG_PARALLEL,
@@ -2802,6 +2838,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
2802 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) }, 2838 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
2803 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) }, 2839 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
2804/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, 2840/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
2841 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) },
2805 { 0 } /* Terminating entry */ 2842 { 0 } /* Terminating entry */
2806}; 2843};
2807MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 2844MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -3772,6 +3809,37 @@ struct dvb_usb_device_properties dib0700_devices[] = {
3772 RC_TYPE_NEC, 3809 RC_TYPE_NEC,
3773 .change_protocol = dib0700_change_protocol, 3810 .change_protocol = dib0700_change_protocol,
3774 }, 3811 },
3812 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3813 .num_adapters = 1,
3814 .adapter = {
3815 {
3816 .frontend_attach = stk7700ph_frontend_attach,
3817 .tuner_attach = xc4000_tuner_attach,
3818
3819 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3820
3821 .size_of_priv = sizeof(struct
3822 dib0700_adapter_state),
3823 },
3824 },
3825
3826 .num_device_descs = 1,
3827 .devices = {
3828 { "Pinnacle PCTV 340e HD Pro USB Stick",
3829 { &dib0700_usb_id_table[76], NULL },
3830 { NULL },
3831 },
3832 },
3833 .rc.core = {
3834 .rc_interval = DEFAULT_RC_INTERVAL,
3835 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3836 .module_name = "dib0700",
3837 .rc_query = dib0700_rc_query_old_firmware,
3838 .allowed_protos = RC_TYPE_RC5 |
3839 RC_TYPE_RC6 |
3840 RC_TYPE_NEC,
3841 .change_protocol = dib0700_change_protocol,
3842 },
3775 }, 3843 },
3776}; 3844};
3777 3845
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 21b15495d2d7..9b40f12cfd22 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -228,6 +228,7 @@
228#define USB_PID_PINNACLE_PCTV72E 0x0236 228#define USB_PID_PINNACLE_PCTV72E 0x0236
229#define USB_PID_PINNACLE_PCTV73E 0x0237 229#define USB_PID_PINNACLE_PCTV73E 0x0237
230#define USB_PID_PINNACLE_PCTV310E 0x3211 230#define USB_PID_PINNACLE_PCTV310E 0x3211
231#define USB_PID_PINNACLE_PCTV340E 0x023d
231#define USB_PID_PINNACLE_PCTV801E 0x023a 232#define USB_PID_PINNACLE_PCTV801E 0x023a
232#define USB_PID_PINNACLE_PCTV801E_SE 0x023b 233#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
233#define USB_PID_PINNACLE_PCTV73A 0x0243 234#define USB_PID_PINNACLE_PCTV73A 0x0243
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index a03945ab9f08..850b45d042ff 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -39,6 +39,7 @@
39#include "tda9887.h" 39#include "tda9887.h"
40#include "xc5000.h" 40#include "xc5000.h"
41#include "tda18271.h" 41#include "tda18271.h"
42#include "xc4000.h"
42 43
43#define UNSET (-1U) 44#define UNSET (-1U)
44 45
@@ -391,6 +392,19 @@ static void set_type(struct i2c_client *c, unsigned int type,
391 tune_now = 0; 392 tune_now = 0;
392 break; 393 break;
393 } 394 }
395 case TUNER_XC4000:
396 {
397 struct xc4000_config xc4000_cfg = {
398 .i2c_address = t->i2c->addr,
399 /* if_khz will be set when the digital dvb_attach() occurs */
400 .if_khz = 0,
401 };
402 if (!dvb_attach(xc4000_attach,
403 &t->fe, t->i2c->adapter, &xc4000_cfg))
404 goto attach_failed;
405 tune_now = 0;
406 break;
407 }
394 default: 408 default:
395 if (!dvb_attach(simple_tuner_attach, &t->fe, 409 if (!dvb_attach(simple_tuner_attach, &t->fe,
396 t->i2c->adapter, t->i2c->addr, t->type)) 410 t->i2c->adapter, t->i2c->addr, t->type))
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 963e33471835..89c290b69a5c 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -127,6 +127,8 @@
127#define TUNER_PHILIPS_FMD1216MEX_MK3 78 127#define TUNER_PHILIPS_FMD1216MEX_MK3 78
128#define TUNER_PHILIPS_FM1216MK5 79 128#define TUNER_PHILIPS_FM1216MK5 79
129#define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */ 129#define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */
130#define TUNER_XC4000 81 /* Xceive Silicon Tuner */
131
130#define TUNER_PARTSNIC_PTI_5NF05 81 132#define TUNER_PARTSNIC_PTI_5NF05 81
131#define TUNER_PHILIPS_CU1216L 82 133#define TUNER_PHILIPS_CU1216L 82
132#define TUNER_NXP_TDA18271 83 134#define TUNER_NXP_TDA18271 83