blob: b04c73bab83cbd8093280c9260e0ab250fe3b0c4 [file] [log] [blame]
Davide Ferri8d009a02009-06-23 22:34:06 -03001/*
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>
Istvan Varga56149422011-06-03 12:23:33 -030031#include <linux/mutex.h>
Devin Heitmueller11091a32009-07-20 00:54:57 -030032#include <asm/unaligned.h>
Davide Ferri8d009a02009-06-23 22:34:06 -030033
34#include "dvb_frontend.h"
35
36#include "xc4000.h"
37#include "tuner-i2c.h"
Devin Heitmueller11091a32009-07-20 00:54:57 -030038#include "tuner-xc2028-types.h"
Davide Ferri8d009a02009-06-23 22:34:06 -030039
Devin Heitmueller4922cec2009-12-27 17:50:43 -030040static int debug;
Davide Ferri8d009a02009-06-23 22:34:06 -030041module_param(debug, int, 0644);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -030042MODULE_PARM_DESC(debug, "\n\t\tDebugging level (0 to 2, default: 0 (off)).");
Davide Ferri8d009a02009-06-23 22:34:06 -030043
44static int no_poweroff;
45module_param(no_poweroff, int, 0644);
Istvan Varga5272f6b2011-06-04 12:03:03 -030046MODULE_PARM_DESC(no_poweroff, "\n\t\t1: keep device energized and with tuner "
47 "ready all the times.\n"
48 "\t\tFaster, but consumes more power and keeps the device hotter.\n"
49 "\t\t2: powers device off when not used.\n"
50 "\t\t0 (default): use device-specific default mode.");
Davide Ferri8d009a02009-06-23 22:34:06 -030051
Istvan Varga923137a2011-06-04 12:15:51 -030052#define XC4000_AUDIO_STD_B 1
53#define XC4000_AUDIO_STD_A2 2
54#define XC4000_AUDIO_STD_K3 4
55#define XC4000_AUDIO_STD_L 8
56#define XC4000_AUDIO_STD_INPUT1 16
57#define XC4000_AUDIO_STD_MONO 32
58
59static int audio_std;
60module_param(audio_std, int, 0644);
61MODULE_PARM_DESC(audio_std, "\n\t\tAudio standard. XC4000 audio decoder "
62 "explicitly needs to know\n"
63 "\t\twhat audio standard is needed for some video standards with\n"
64 "\t\taudio A2 or NICAM.\n"
65 "\t\tThe valid settings are a sum of:\n"
66 "\t\t 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n"
67 "\t\t 2: use A2 instead of NICAM or BTSC\n"
68 "\t\t 4: use SECAM/K3 instead of K1\n"
69 "\t\t 8: use PAL-D/K audio for SECAM-D/K\n"
70 "\t\t16: use FM radio input 1 instead of input 2\n"
71 "\t\t32: use mono audio (the lower three bits are ignored)");
72
Istvan Vargafa285bc2011-06-04 11:48:16 -030073#define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
74
75static char firmware_name[30];
76module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
77MODULE_PARM_DESC(firmware_name, "\n\t\tFirmware file name. Allows overriding "
78 "the default firmware\n"
79 "\t\tname.");
80
Davide Ferri8d009a02009-06-23 22:34:06 -030081static DEFINE_MUTEX(xc4000_list_mutex);
82static LIST_HEAD(hybrid_tuner_instance_list);
83
84#define dprintk(level, fmt, arg...) if (debug >= level) \
85 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
86
Devin Heitmueller11091a32009-07-20 00:54:57 -030087/* struct for storing firmware table */
88struct firmware_description {
89 unsigned int type;
90 v4l2_std_id id;
91 __u16 int_freq;
92 unsigned char *ptr;
93 unsigned int size;
94};
95
96struct firmware_properties {
97 unsigned int type;
98 v4l2_std_id id;
99 v4l2_std_id std_req;
100 __u16 int_freq;
101 unsigned int scode_table;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300102 int scode_nr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300103};
Davide Ferri8d009a02009-06-23 22:34:06 -0300104
105struct xc4000_priv {
106 struct tuner_i2c_props i2c_props;
107 struct list_head hybrid_tuner_instance_list;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300108 struct firmware_description *firm;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300109 int firm_size;
110 __u16 firm_version;
111 u32 if_khz;
112 u32 freq_hz;
113 u32 bandwidth;
114 u8 video_standard;
115 u8 rf_mode;
Istvan Varga0b402132011-06-03 09:38:04 -0300116 u8 card_type;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300117 u8 ignore_i2c_write_errors;
118 /* struct xc2028_ctrl ctrl; */
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300119 struct firmware_properties cur_fw;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300120 __u16 hwmodel;
121 __u16 hwvers;
Istvan Varga56149422011-06-03 12:23:33 -0300122 struct mutex lock;
Davide Ferri8d009a02009-06-23 22:34:06 -0300123};
124
125/* Misc Defines */
Istvan Varga49110852011-06-03 10:55:24 -0300126#define MAX_TV_STANDARD 24
Davide Ferri8d009a02009-06-23 22:34:06 -0300127#define XC_MAX_I2C_WRITE_LENGTH 64
Istvan Varga5272f6b2011-06-04 12:03:03 -0300128#define XC_POWERED_DOWN 0x80000000U
Davide Ferri8d009a02009-06-23 22:34:06 -0300129
130/* Signal Types */
131#define XC_RF_MODE_AIR 0
132#define XC_RF_MODE_CABLE 1
133
134/* Result codes */
135#define XC_RESULT_SUCCESS 0
136#define XC_RESULT_RESET_FAILURE 1
137#define XC_RESULT_I2C_WRITE_FAILURE 2
138#define XC_RESULT_I2C_READ_FAILURE 3
139#define XC_RESULT_OUT_OF_RANGE 5
140
141/* Product id */
142#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300143#define XC_PRODUCT_ID_FW_LOADED 0x0FA0
Davide Ferri8d009a02009-06-23 22:34:06 -0300144
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300145/* Registers (Write-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300146#define XREG_INIT 0x00
147#define XREG_VIDEO_MODE 0x01
148#define XREG_AUDIO_MODE 0x02
149#define XREG_RF_FREQ 0x03
150#define XREG_D_CODE 0x04
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300151#define XREG_DIRECTSITTING_MODE 0x05
152#define XREG_SEEK_MODE 0x06
153#define XREG_POWER_DOWN 0x08
154#define XREG_SIGNALSOURCE 0x0A
Istvan Varga30f544e2011-06-04 12:12:42 -0300155#define XREG_SMOOTHEDCVBS 0x0E
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300156#define XREG_AMPLITUDE 0x10
Davide Ferri8d009a02009-06-23 22:34:06 -0300157
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300158/* Registers (Read-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300159#define XREG_ADC_ENV 0x00
160#define XREG_QUALITY 0x01
161#define XREG_FRAME_LINES 0x02
162#define XREG_HSYNC_FREQ 0x03
163#define XREG_LOCK 0x04
164#define XREG_FREQ_ERROR 0x05
165#define XREG_SNR 0x06
166#define XREG_VERSION 0x07
167#define XREG_PRODUCT_ID 0x08
Davide Ferri8d009a02009-06-23 22:34:06 -0300168
169/*
170 Basic firmware description. This will remain with
171 the driver for documentation purposes.
172
173 This represents an I2C firmware file encoded as a
174 string of unsigned char. Format is as follows:
175
176 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
177 char[1 ]=len0_LSB -> length of first write transaction
178 char[2 ]=data0 -> first byte to be sent
179 char[3 ]=data1
180 char[4 ]=data2
181 char[ ]=...
182 char[M ]=dataN -> last byte to be sent
183 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
184 char[M+2]=len1_LSB -> length of second write transaction
185 char[M+3]=data0
186 char[M+4]=data1
187 ...
188 etc.
189
190 The [len] value should be interpreted as follows:
191
192 len= len_MSB _ len_LSB
193 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
194 len=0000_0000_0000_0000 : Reset command: Do hardware reset
195 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
196 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
197
198 For the RESET and WAIT commands, the two following bytes will contain
199 immediately the length of the following transaction.
Davide Ferri8d009a02009-06-23 22:34:06 -0300200*/
Istvan Vargafbe4a292011-06-03 10:11:48 -0300201
Davide Ferri8d009a02009-06-23 22:34:06 -0300202struct XC_TV_STANDARD {
Istvan Vargafbe4a292011-06-03 10:11:48 -0300203 const char *Name;
204 u16 AudioMode;
205 u16 VideoMode;
Istvan Varga49110852011-06-03 10:55:24 -0300206 u16 int_freq;
Davide Ferri8d009a02009-06-23 22:34:06 -0300207};
208
209/* Tuner standards */
Devin Heitmuellered23db32009-10-05 01:27:14 -0300210#define XC4000_MN_NTSC_PAL_BTSC 0
211#define XC4000_MN_NTSC_PAL_A2 1
212#define XC4000_MN_NTSC_PAL_EIAJ 2
213#define XC4000_MN_NTSC_PAL_Mono 3
214#define XC4000_BG_PAL_A2 4
215#define XC4000_BG_PAL_NICAM 5
216#define XC4000_BG_PAL_MONO 6
217#define XC4000_I_PAL_NICAM 7
218#define XC4000_I_PAL_NICAM_MONO 8
219#define XC4000_DK_PAL_A2 9
220#define XC4000_DK_PAL_NICAM 10
221#define XC4000_DK_PAL_MONO 11
222#define XC4000_DK_SECAM_A2DK1 12
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300223#define XC4000_DK_SECAM_A2LDK3 13
224#define XC4000_DK_SECAM_A2MONO 14
Istvan Varga49110852011-06-03 10:55:24 -0300225#define XC4000_DK_SECAM_NICAM 15
226#define XC4000_L_SECAM_NICAM 16
227#define XC4000_LC_SECAM_NICAM 17
228#define XC4000_DTV6 18
229#define XC4000_DTV8 19
230#define XC4000_DTV7_8 20
231#define XC4000_DTV7 21
232#define XC4000_FM_Radio_INPUT2 22
233#define XC4000_FM_Radio_INPUT1 23
Davide Ferri8d009a02009-06-23 22:34:06 -0300234
Davide Ferri8d009a02009-06-23 22:34:06 -0300235static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
Istvan Varga49110852011-06-03 10:55:24 -0300236 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
237 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
238 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
239 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
240 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
241 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
242 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
243 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
244 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
245 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
246 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
247 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
248 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
249 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
250 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
251 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
252 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
253 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
254 {"DTV6", 0x00C0, 0x8002, 0},
255 {"DTV8", 0x00C0, 0x800B, 0},
256 {"DTV7/8", 0x00C0, 0x801B, 0},
257 {"DTV7", 0x00C0, 0x8007, 0},
258 {"FM Radio-INPUT2", 0x0008, 0x9800,10700},
259 {"FM Radio-INPUT1", 0x0008, 0x9000,10700}
Davide Ferri8d009a02009-06-23 22:34:06 -0300260};
261
Davide Ferri8d009a02009-06-23 22:34:06 -0300262static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
263static int xc4000_TunerReset(struct dvb_frontend *fe);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300264static void xc_debug_dump(struct xc4000_priv *priv);
Davide Ferri8d009a02009-06-23 22:34:06 -0300265
266static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
267{
268 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
269 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300270 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300271 if (priv->ignore_i2c_write_errors == 0) {
272 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
273 len);
274 if (len == 4) {
275 printk("bytes %02x %02x %02x %02x\n", buf[0],
276 buf[1], buf[2], buf[3]);
277 }
278 return XC_RESULT_I2C_WRITE_FAILURE;
279 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300280 }
281 return XC_RESULT_SUCCESS;
282}
283
Davide Ferri8d009a02009-06-23 22:34:06 -0300284static void xc_wait(int wait_ms)
285{
286 msleep(wait_ms);
287}
288
289static int xc4000_TunerReset(struct dvb_frontend *fe)
290{
291 struct xc4000_priv *priv = fe->tuner_priv;
292 int ret;
293
294 dprintk(1, "%s()\n", __func__);
295
296 if (fe->callback) {
297 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
298 fe->dvb->priv :
299 priv->i2c_props.adap->algo_data,
300 DVB_FRONTEND_COMPONENT_TUNER,
301 XC4000_TUNER_RESET, 0);
302 if (ret) {
303 printk(KERN_ERR "xc4000: reset failed\n");
304 return XC_RESULT_RESET_FAILURE;
305 }
306 } else {
307 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
308 return XC_RESULT_RESET_FAILURE;
309 }
310 return XC_RESULT_SUCCESS;
311}
312
313static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
314{
315 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300316 int result;
317
318 buf[0] = (regAddr >> 8) & 0xFF;
319 buf[1] = regAddr & 0xFF;
320 buf[2] = (i2cData >> 8) & 0xFF;
321 buf[3] = i2cData & 0xFF;
322 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300323
324 return result;
325}
326
327static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
328{
329 struct xc4000_priv *priv = fe->tuner_priv;
330
331 int i, nbytes_to_send, result;
332 unsigned int len, pos, index;
333 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
334
335 index = 0;
336 while ((i2c_sequence[index] != 0xFF) ||
337 (i2c_sequence[index + 1] != 0xFF)) {
338 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
339 if (len == 0x0000) {
340 /* RESET command */
Davide Ferri8d009a02009-06-23 22:34:06 -0300341 index += 2;
Istvan Varga8f76afe2011-06-04 12:21:17 -0300342#if 0 /* not needed, as already called by check_firmware() */
343 result = xc4000_TunerReset(fe);
Davide Ferri8d009a02009-06-23 22:34:06 -0300344 if (result != XC_RESULT_SUCCESS)
345 return result;
Istvan Varga8f76afe2011-06-04 12:21:17 -0300346#endif
Davide Ferri8d009a02009-06-23 22:34:06 -0300347 } else if (len & 0x8000) {
348 /* WAIT command */
349 xc_wait(len & 0x7FFF);
350 index += 2;
351 } else {
352 /* Send i2c data whilst ensuring individual transactions
353 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
354 */
355 index += 2;
356 buf[0] = i2c_sequence[index];
357 buf[1] = i2c_sequence[index + 1];
358 pos = 2;
359 while (pos < len) {
360 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
361 nbytes_to_send =
362 XC_MAX_I2C_WRITE_LENGTH;
363 else
364 nbytes_to_send = (len - pos + 2);
365 for (i = 2; i < nbytes_to_send; i++) {
366 buf[i] = i2c_sequence[index + pos +
367 i - 2];
368 }
369 result = xc_send_i2c_data(priv, buf,
370 nbytes_to_send);
371
372 if (result != XC_RESULT_SUCCESS)
373 return result;
374
375 pos += nbytes_to_send - 2;
376 }
377 index += len;
378 }
379 }
380 return XC_RESULT_SUCCESS;
381}
382
Davide Ferri8d009a02009-06-23 22:34:06 -0300383static int xc_SetTVStandard(struct xc4000_priv *priv,
384 u16 VideoMode, u16 AudioMode)
385{
386 int ret;
387 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
388 dprintk(1, "%s() Standard = %s\n",
389 __func__,
390 XC4000_Standard[priv->video_standard].Name);
391
Devin Heitmueller799ed112009-10-04 23:09:18 -0300392 /* Don't complain when the request fails because of i2c stretching */
393 priv->ignore_i2c_write_errors = 1;
394
Davide Ferri8d009a02009-06-23 22:34:06 -0300395 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
396 if (ret == XC_RESULT_SUCCESS)
397 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
398
Devin Heitmueller799ed112009-10-04 23:09:18 -0300399 priv->ignore_i2c_write_errors = 0;
400
Davide Ferri8d009a02009-06-23 22:34:06 -0300401 return ret;
402}
403
404static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
405{
406 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
407 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
408
409 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
410 rf_mode = XC_RF_MODE_CABLE;
411 printk(KERN_ERR
412 "%s(), Invalid mode, defaulting to CABLE",
413 __func__);
414 }
415 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
416}
417
418static const struct dvb_tuner_ops xc4000_tuner_ops;
419
420static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
421{
422 u16 freq_code;
423
424 dprintk(1, "%s(%u)\n", __func__, freq_hz);
425
426 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
427 (freq_hz < xc4000_tuner_ops.info.frequency_min))
428 return XC_RESULT_OUT_OF_RANGE;
429
430 freq_code = (u16)(freq_hz / 15625);
431
432 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
433 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
434 only be used for fast scanning for channel lock) */
435 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
436}
437
Davide Ferri8d009a02009-06-23 22:34:06 -0300438static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
439{
440 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
441}
442
443static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
444{
445 int result;
446 u16 regData;
447 u32 tmp;
448
449 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
450 if (result != XC_RESULT_SUCCESS)
451 return result;
452
Istvan Varga1368ceb2011-06-03 12:27:30 -0300453 tmp = (u32)regData & 0xFFFFU;
454 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
455 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300456 return result;
457}
458
459static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
460{
461 return xc4000_readreg(priv, XREG_LOCK, lock_status);
462}
463
464static int xc_get_version(struct xc4000_priv *priv,
465 u8 *hw_majorversion, u8 *hw_minorversion,
466 u8 *fw_majorversion, u8 *fw_minorversion)
467{
468 u16 data;
469 int result;
470
471 result = xc4000_readreg(priv, XREG_VERSION, &data);
472 if (result != XC_RESULT_SUCCESS)
473 return result;
474
475 (*hw_majorversion) = (data >> 12) & 0x0F;
476 (*hw_minorversion) = (data >> 8) & 0x0F;
477 (*fw_majorversion) = (data >> 4) & 0x0F;
478 (*fw_minorversion) = data & 0x0F;
479
480 return 0;
481}
482
Davide Ferri8d009a02009-06-23 22:34:06 -0300483static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
484{
485 u16 regData;
486 int result;
487
488 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
489 if (result != XC_RESULT_SUCCESS)
490 return result;
491
492 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
493 return result;
494}
495
496static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
497{
498 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
499}
500
501static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
502{
503 return xc4000_readreg(priv, XREG_QUALITY, quality);
504}
505
506static u16 WaitForLock(struct xc4000_priv *priv)
507{
508 u16 lockState = 0;
509 int watchDogCount = 40;
510
511 while ((lockState == 0) && (watchDogCount > 0)) {
512 xc_get_lock_status(priv, &lockState);
513 if (lockState != 1) {
514 xc_wait(5);
515 watchDogCount--;
516 }
517 }
518 return lockState;
519}
520
Istvan Vargae75873c2011-06-04 12:18:41 -0300521static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
Davide Ferri8d009a02009-06-23 22:34:06 -0300522{
Istvan Vargae75873c2011-06-04 12:18:41 -0300523 int found = 1;
524 int result;
Davide Ferri8d009a02009-06-23 22:34:06 -0300525
526 dprintk(1, "%s(%u)\n", __func__, freq_hz);
527
Devin Heitmueller799ed112009-10-04 23:09:18 -0300528 /* Don't complain when the request fails because of i2c stretching */
529 priv->ignore_i2c_write_errors = 1;
530 result = xc_set_RF_frequency(priv, freq_hz);
531 priv->ignore_i2c_write_errors = 0;
532
533 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300534 return 0;
535
Istvan Vargae75873c2011-06-04 12:18:41 -0300536 /* wait for lock only in analog TV mode */
537 if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
538 if (WaitForLock(priv) != 1)
539 found = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300540 }
541
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300542 /* Wait for stats to stabilize.
543 * Frame Lines needs two frame times after initial lock
544 * before it is valid.
545 */
546 xc_wait(debug ? 100 : 10);
547
548 if (debug)
549 xc_debug_dump(priv);
550
Davide Ferri8d009a02009-06-23 22:34:06 -0300551 return found;
552}
553
554static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
555{
556 u8 buf[2] = { reg >> 8, reg & 0xff };
557 u8 bval[2] = { 0, 0 };
558 struct i2c_msg msg[2] = {
559 { .addr = priv->i2c_props.addr,
560 .flags = 0, .buf = &buf[0], .len = 2 },
561 { .addr = priv->i2c_props.addr,
562 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
563 };
564
565 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
566 printk(KERN_WARNING "xc4000: I2C read failed\n");
567 return -EREMOTEIO;
568 }
569
570 *val = (bval[0] << 8) | bval[1];
571 return XC_RESULT_SUCCESS;
572}
573
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300574#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300575static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
576{
577 if (type & BASE)
578 printk("BASE ");
579 if (type & INIT1)
580 printk("INIT1 ");
581 if (type & F8MHZ)
582 printk("F8MHZ ");
583 if (type & MTS)
584 printk("MTS ");
585 if (type & D2620)
586 printk("D2620 ");
587 if (type & D2633)
588 printk("D2633 ");
589 if (type & DTV6)
590 printk("DTV6 ");
591 if (type & QAM)
592 printk("QAM ");
593 if (type & DTV7)
594 printk("DTV7 ");
595 if (type & DTV78)
596 printk("DTV78 ");
597 if (type & DTV8)
598 printk("DTV8 ");
599 if (type & FM)
600 printk("FM ");
601 if (type & INPUT1)
602 printk("INPUT1 ");
603 if (type & LCD)
604 printk("LCD ");
605 if (type & NOGD)
606 printk("NOGD ");
607 if (type & MONO)
608 printk("MONO ");
609 if (type & ATSC)
610 printk("ATSC ");
611 if (type & IF)
612 printk("IF ");
613 if (type & LG60)
614 printk("LG60 ");
615 if (type & ATI638)
616 printk("ATI638 ");
617 if (type & OREN538)
618 printk("OREN538 ");
619 if (type & OREN36)
620 printk("OREN36 ");
621 if (type & TOYOTA388)
622 printk("TOYOTA388 ");
623 if (type & TOYOTA794)
624 printk("TOYOTA794 ");
625 if (type & DIBCOM52)
626 printk("DIBCOM52 ");
627 if (type & ZARLINK456)
628 printk("ZARLINK456 ");
629 if (type & CHINA)
630 printk("CHINA ");
631 if (type & F6MHZ)
632 printk("F6MHZ ");
633 if (type & INPUT2)
634 printk("INPUT2 ");
635 if (type & SCODE)
636 printk("SCODE ");
637 if (type & HAS_IF)
638 printk("HAS_IF_%d ", int_freq);
639}
640
Devin Heitmueller11091a32009-07-20 00:54:57 -0300641static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
642 v4l2_std_id *id)
643{
644 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300645 int i, best_i = -1;
646 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300647
Devin Heitmueller11091a32009-07-20 00:54:57 -0300648 if (!priv->firm) {
649 printk("Error! firmware not loaded\n");
650 return -EINVAL;
651 }
652
653 if (((type & ~SCODE) == 0) && (*id == 0))
654 *id = V4L2_STD_PAL;
655
Devin Heitmueller11091a32009-07-20 00:54:57 -0300656 /* Seek for generic video standard match */
657 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300658 v4l2_std_id id_diff_mask =
659 (priv->firm[i].id ^ (*id)) & (*id);
660 unsigned int type_diff_mask =
661 (priv->firm[i].type ^ type)
662 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
663 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300664
Istvan Varga3db95702011-06-04 11:52:34 -0300665 if (type_diff_mask
666 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300667 continue;
668
Istvan Varga3db95702011-06-04 11:52:34 -0300669 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
670 if (!nr_diffs) /* Supports all the requested standards */
671 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300672
Istvan Varga3db95702011-06-04 11:52:34 -0300673 if (nr_diffs < best_nr_diffs) {
674 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300675 best_i = i;
676 }
677 }
678
Istvan Varga3db95702011-06-04 11:52:34 -0300679 /* FIXME: Would make sense to seek for type "hint" match ? */
680 if (best_i < 0) {
681 i = -ENOENT;
682 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300683 }
684
Istvan Varga3db95702011-06-04 11:52:34 -0300685 if (best_nr_diffs > 0U) {
686 printk("Selecting best matching firmware (%u bits differ) for "
687 "type=", best_nr_diffs);
688 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
689 i = best_i;
690 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300691
692found:
693 *id = priv->firm[i].id;
694
695ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300696 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300697 printk("%s firmware for type=", (i < 0) ? "Can't find" :
698 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300699 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300700 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
701 }
702 return i;
703}
704
705static int load_firmware(struct dvb_frontend *fe, unsigned int type,
706 v4l2_std_id *id)
707{
708 struct xc4000_priv *priv = fe->tuner_priv;
709 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300710 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300711
Devin Heitmueller11091a32009-07-20 00:54:57 -0300712 pos = seek_firmware(fe, type, id);
713 if (pos < 0)
714 return pos;
715
Devin Heitmueller11091a32009-07-20 00:54:57 -0300716 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300717
Devin Heitmueller799ed112009-10-04 23:09:18 -0300718 /* Don't complain when the request fails because of i2c stretching */
719 priv->ignore_i2c_write_errors = 1;
720
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300721 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300722
Devin Heitmueller799ed112009-10-04 23:09:18 -0300723 priv->ignore_i2c_write_errors = 0;
724
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300725 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300726}
727
Davide Ferri8d009a02009-06-23 22:34:06 -0300728static int xc4000_fwupload(struct dvb_frontend *fe)
729{
730 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300731 const struct firmware *fw = NULL;
732 const unsigned char *p, *endp;
733 int rc = 0;
734 int n, n_array;
735 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300736 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300737
Istvan Vargafa285bc2011-06-04 11:48:16 -0300738 if (firmware_name[0] != '\0')
739 fname = firmware_name;
740 else
741 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300742
743 printk("Reading firmware %s\n", fname);
744 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
745 if (rc < 0) {
746 if (rc == -ENOENT)
747 printk("Error: firmware %s not found.\n",
748 fname);
749 else
750 printk("Error %d while requesting firmware %s \n",
751 rc, fname);
752
753 return rc;
754 }
755 p = fw->data;
756 endp = p + fw->size;
757
758 if (fw->size < sizeof(name) - 1 + 2 + 2) {
759 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300760 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300761 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300762 }
763
Devin Heitmueller11091a32009-07-20 00:54:57 -0300764 memcpy(name, p, sizeof(name) - 1);
765 name[sizeof(name) - 1] = 0;
766 p += sizeof(name) - 1;
767
768 priv->firm_version = get_unaligned_le16(p);
769 p += 2;
770
771 n_array = get_unaligned_le16(p);
772 p += 2;
773
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300774 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
775 n_array, fname, name,
776 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300777
778 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
779 if (priv->firm == NULL) {
780 printk("Not enough memory to load firmware file.\n");
781 rc = -ENOMEM;
782 goto err;
783 }
784 priv->firm_size = n_array;
785
786 n = -1;
787 while (p < endp) {
788 __u32 type, size;
789 v4l2_std_id id;
790 __u16 int_freq = 0;
791
792 n++;
793 if (n >= n_array) {
794 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300795 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300796 goto corrupt;
797 }
798
799 /* Checks if there's enough bytes to read */
800 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
801 goto header;
802
803 type = get_unaligned_le32(p);
804 p += sizeof(type);
805
806 id = get_unaligned_le64(p);
807 p += sizeof(id);
808
809 if (type & HAS_IF) {
810 int_freq = get_unaligned_le16(p);
811 p += sizeof(int_freq);
812 if (endp - p < sizeof(size))
813 goto header;
814 }
815
816 size = get_unaligned_le32(p);
817 p += sizeof(size);
818
819 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300820 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300821 "(size=%d, expected %d)\n",
822 type, (unsigned long long)id,
823 (unsigned)(endp - p), size);
824 goto corrupt;
825 }
826
827 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
828 if (priv->firm[n].ptr == NULL) {
829 printk("Not enough memory to load firmware file.\n");
830 rc = -ENOMEM;
831 goto err;
832 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300833
Devin Heitmueller11091a32009-07-20 00:54:57 -0300834 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300835 printk("Reading firmware type ");
836 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300837 printk("(%x), id %llx, size=%d.\n",
838 type, (unsigned long long)id, size);
839 }
840
841 memcpy(priv->firm[n].ptr, p, size);
842 priv->firm[n].type = type;
843 priv->firm[n].id = id;
844 priv->firm[n].size = size;
845 priv->firm[n].int_freq = int_freq;
846
847 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300848 }
849
Devin Heitmueller11091a32009-07-20 00:54:57 -0300850 if (n + 1 != priv->firm_size) {
851 printk("Firmware file is incomplete!\n");
852 goto corrupt;
853 }
854
855 goto done;
856
857header:
858 printk("Firmware header is incomplete!\n");
859corrupt:
860 rc = -EINVAL;
861 printk("Error: firmware file is corrupted!\n");
862
863err:
864 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300865
866done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300867 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300868 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300869 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300870
871 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300872}
873
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300874static int load_scode(struct dvb_frontend *fe, unsigned int type,
875 v4l2_std_id *id, __u16 int_freq, int scode)
876{
877 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300878 int pos, rc;
879 unsigned char *p;
880 u8 scode_buf[13];
881 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300882
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300883 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300884
885 if (!int_freq) {
886 pos = seek_firmware(fe, type, id);
887 if (pos < 0)
888 return pos;
889 } else {
890 for (pos = 0; pos < priv->firm_size; pos++) {
891 if ((priv->firm[pos].int_freq == int_freq) &&
892 (priv->firm[pos].type & HAS_IF))
893 break;
894 }
895 if (pos == priv->firm_size)
896 return -ENOENT;
897 }
898
899 p = priv->firm[pos].ptr;
900
Istvan Vargaffce6262011-06-04 11:56:18 -0300901 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
902 return -EINVAL;
903 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300904
905 tuner_info("Loading SCODE for type=");
906 dump_firm_type_and_int_freq(priv->firm[pos].type,
907 priv->firm[pos].int_freq);
908 printk("(%x), id %016llx.\n", priv->firm[pos].type,
909 (unsigned long long)*id);
910
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300911 scode_buf[0] = 0x00;
912 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300913
914 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300915 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
916 if (rc < 0) {
917 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300918 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300919 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300920
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300921 rc = xc_send_i2c_data(priv, scode_buf, 13);
922 if (rc != XC_RESULT_SUCCESS) {
923 /* Even if the send failed, make sure we set back to indirect
924 mode */
925 printk("Failed to set scode %d\n", rc);
926 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300927
928 /* Switch back to indirect-mode */
929 memset(indirect_mode, 0, sizeof(indirect_mode));
930 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300931 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
932 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300933
934 return 0;
935}
936
937static int check_firmware(struct dvb_frontend *fe, unsigned int type,
938 v4l2_std_id std, __u16 int_freq)
939{
940 struct xc4000_priv *priv = fe->tuner_priv;
941 struct firmware_properties new_fw;
942 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300943 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300944 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300945 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300946
947 dprintk(1, "%s called\n", __func__);
948
949 if (!priv->firm) {
950 rc = xc4000_fwupload(fe);
951 if (rc < 0)
952 return rc;
953 }
954
955#ifdef DJH_DEBUG
956 if (priv->ctrl.mts && !(type & FM))
957 type |= MTS;
958#endif
959
960retry:
961 new_fw.type = type;
962 new_fw.id = std;
963 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300964 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300965 new_fw.scode_nr = 0;
966 new_fw.int_freq = int_freq;
967
968 dprintk(1, "checking firmware, user requested type=");
969 if (debug) {
970 dump_firm_type(new_fw.type);
971 printk("(%x), id %016llx, ", new_fw.type,
972 (unsigned long long)new_fw.std_req);
973 if (!int_freq) {
974 printk("scode_tbl ");
975#ifdef DJH_DEBUG
976 dump_firm_type(priv->ctrl.scode_table);
977 printk("(%x), ", priv->ctrl.scode_table);
978#endif
979 } else
980 printk("int_freq %d, ", new_fw.int_freq);
981 printk("scode_nr %d\n", new_fw.scode_nr);
982 }
983
984 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300985 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300986 dprintk(1, "BASE firmware not changed.\n");
987 goto skip_base;
988 }
989
990 /* Updating BASE - forget about all currently loaded firmware */
991 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
992
993 /* Reset is needed before loading firmware */
994 rc = xc4000_TunerReset(fe);
995 if (rc < 0)
996 goto fail;
997
998 /* BASE firmwares are all std0 */
999 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -03001000 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001001 if (rc < 0) {
1002 printk("Error %d while loading base firmware\n", rc);
1003 goto fail;
1004 }
1005
1006 /* Load INIT1, if needed */
1007 dprintk(1, "Load init1 firmware, if exists\n");
1008
Istvan Varga595a83f2011-06-04 11:59:54 -03001009 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001010 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -03001011 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001012 if (rc < 0 && rc != -ENOENT) {
1013 tuner_err("Error %d while loading init1 firmware\n",
1014 rc);
1015 goto fail;
1016 }
1017
1018skip_base:
1019 /*
1020 * No need to reload standard specific firmware if base firmware
1021 * was not reloaded and requested video standards have not changed.
1022 */
1023 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1024 priv->cur_fw.std_req == std) {
1025 dprintk(1, "Std-specific firmware already loaded.\n");
1026 goto skip_std_specific;
1027 }
1028
1029 /* Reloading std-specific firmware forces a SCODE update */
1030 priv->cur_fw.scode_table = 0;
1031
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001032 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001033 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001034
1035 if (rc < 0)
1036 goto fail;
1037
1038skip_std_specific:
1039 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1040 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1041 dprintk(1, "SCODE firmware already loaded.\n");
1042 goto check_device;
1043 }
1044
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001045 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001046 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1047 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001048 if (rc != XC_RESULT_SUCCESS)
1049 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001050
1051check_device:
1052 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1053
Devin Heitmueller799ed112009-10-04 23:09:18 -03001054 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001055 &fw_minor) != XC_RESULT_SUCCESS) {
1056 printk("Unable to read tuner registers.\n");
1057 goto fail;
1058 }
1059
1060 dprintk(1, "Device is Xceive %d version %d.%d, "
1061 "firmware version %d.%d\n",
1062 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1063
1064 /* Check firmware version against what we downloaded. */
1065#ifdef DJH_DEBUG
1066 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1067 printk("Incorrect readback of firmware version %x.\n",
1068 (version & 0xff));
1069 goto fail;
1070 }
1071#endif
1072
1073 /* Check that the tuner hardware model remains consistent over time. */
1074 if (priv->hwmodel == 0 && hwmodel == 4000) {
1075 priv->hwmodel = hwmodel;
1076 priv->hwvers = version & 0xff00;
1077 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1078 priv->hwvers != (version & 0xff00)) {
1079 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001080 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001081 goto fail;
1082 }
1083
1084 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1085
1086 /*
1087 * By setting BASE in cur_fw.type only after successfully loading all
1088 * firmwares, we can:
1089 * 1. Identify that BASE firmware with type=0 has been loaded;
1090 * 2. Tell whether BASE firmware was just changed the next time through.
1091 */
1092 priv->cur_fw.type |= BASE;
1093
1094 return 0;
1095
1096fail:
1097 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1098 if (!is_retry) {
1099 msleep(50);
1100 is_retry = 1;
1101 dprintk(1, "Retrying firmware load\n");
1102 goto retry;
1103 }
1104
1105 if (rc == -ENOENT)
1106 rc = -EINVAL;
1107 return rc;
1108}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001109
Davide Ferri8d009a02009-06-23 22:34:06 -03001110static void xc_debug_dump(struct xc4000_priv *priv)
1111{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001112 u16 adc_envelope;
1113 u32 freq_error_hz = 0;
1114 u16 lock_status;
1115 u32 hsync_freq_hz = 0;
1116 u16 frame_lines;
1117 u16 quality;
1118 u8 hw_majorversion = 0, hw_minorversion = 0;
1119 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001120
Istvan Vargafbe4a292011-06-03 10:11:48 -03001121 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001122 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1123
1124 xc_get_frequency_error(priv, &freq_error_hz);
1125 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1126
Istvan Vargafbe4a292011-06-03 10:11:48 -03001127 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001128 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1129 lock_status);
1130
Istvan Vargafbe4a292011-06-03 10:11:48 -03001131 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1132 &fw_majorversion, &fw_minorversion);
Davide Ferri8d009a02009-06-23 22:34:06 -03001133 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1134 hw_majorversion, hw_minorversion,
1135 fw_majorversion, fw_minorversion);
1136
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001137 if (priv->video_standard < XC4000_DTV6) {
1138 xc_get_hsync_freq(priv, &hsync_freq_hz);
1139 dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
1140 hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001141
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001142 xc_get_frame_lines(priv, &frame_lines);
1143 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1144 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001145
Istvan Vargafbe4a292011-06-03 10:11:48 -03001146 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001147 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1148}
1149
1150static int xc4000_set_params(struct dvb_frontend *fe,
1151 struct dvb_frontend_parameters *params)
1152{
1153 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001154 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001155 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001156
Davide Ferri8d009a02009-06-23 22:34:06 -03001157 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1158
Istvan Varga56149422011-06-03 12:23:33 -03001159 mutex_lock(&priv->lock);
1160
Davide Ferri8d009a02009-06-23 22:34:06 -03001161 if (fe->ops.info.type == FE_ATSC) {
1162 dprintk(1, "%s() ATSC\n", __func__);
1163 switch (params->u.vsb.modulation) {
1164 case VSB_8:
1165 case VSB_16:
1166 dprintk(1, "%s() VSB modulation\n", __func__);
1167 priv->rf_mode = XC_RF_MODE_AIR;
1168 priv->freq_hz = params->frequency - 1750000;
1169 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001170 priv->video_standard = XC4000_DTV6;
1171 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001172 break;
1173 case QAM_64:
1174 case QAM_256:
1175 case QAM_AUTO:
1176 dprintk(1, "%s() QAM modulation\n", __func__);
1177 priv->rf_mode = XC_RF_MODE_CABLE;
1178 priv->freq_hz = params->frequency - 1750000;
1179 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001180 priv->video_standard = XC4000_DTV6;
1181 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001182 break;
1183 default:
Istvan Varga56149422011-06-03 12:23:33 -03001184 ret = -EINVAL;
1185 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001186 }
1187 } else if (fe->ops.info.type == FE_OFDM) {
1188 dprintk(1, "%s() OFDM\n", __func__);
1189 switch (params->u.ofdm.bandwidth) {
1190 case BANDWIDTH_6_MHZ:
1191 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001192 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001193 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001194 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001195 break;
1196 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001197 priv->bandwidth = BANDWIDTH_7_MHZ;
1198 priv->video_standard = XC4000_DTV7;
1199 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001200 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001201 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001202 case BANDWIDTH_8_MHZ:
1203 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001204 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001205 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001206 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001207 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001208 case BANDWIDTH_AUTO:
1209 if (params->frequency < 400000000) {
1210 priv->bandwidth = BANDWIDTH_7_MHZ;
1211 priv->freq_hz = params->frequency - 2250000;
1212 } else {
1213 priv->bandwidth = BANDWIDTH_8_MHZ;
1214 priv->freq_hz = params->frequency - 2750000;
1215 }
1216 priv->video_standard = XC4000_DTV7_8;
1217 type = DTV78;
1218 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001219 default:
1220 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001221 ret = -EINVAL;
1222 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001223 }
1224 priv->rf_mode = XC_RF_MODE_AIR;
1225 } else {
1226 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001227 ret = -EINVAL;
1228 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001229 }
1230
1231 dprintk(1, "%s() frequency=%d (compensated)\n",
1232 __func__, priv->freq_hz);
1233
Devin Heitmuellered23db32009-10-05 01:27:14 -03001234 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001235 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1236 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001237
Davide Ferri8d009a02009-06-23 22:34:06 -03001238 ret = xc_SetSignalSource(priv, priv->rf_mode);
1239 if (ret != XC_RESULT_SUCCESS) {
1240 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001241 "xc4000: xc_SetSignalSource(%d) failed\n",
1242 priv->rf_mode);
1243 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001244 } else {
1245 u16 video_mode, audio_mode;
1246 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1247 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1248 if (type == DTV6 && priv->firm_version != 0x0102)
1249 video_mode |= 0x0001;
1250 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1251 if (ret != XC_RESULT_SUCCESS) {
1252 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1253 /* DJH - do not return when it fails... */
1254 /* goto fail; */
1255 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001256 }
1257
Istvan Varga30f544e2011-06-04 12:12:42 -03001258 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1259 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1260 ret = 0;
1261 if (xc_write_reg(priv, XREG_AMPLITUDE,
1262 (priv->firm_version == 0x0102 ? 132 : 134))
1263 != 0)
1264 ret = -EREMOTEIO;
1265 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1266 ret = -EREMOTEIO;
1267 if (ret != 0) {
1268 printk(KERN_ERR "xc4000: setting registers failed\n");
1269 /* goto fail; */
1270 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001271 }
Istvan Varga30f544e2011-06-04 12:12:42 -03001272
Istvan Vargae75873c2011-06-04 12:18:41 -03001273 xc_tune_channel(priv, priv->freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001274
Istvan Varga56149422011-06-03 12:23:33 -03001275 ret = 0;
1276
1277fail:
1278 mutex_unlock(&priv->lock);
1279
1280 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001281}
1282
Davide Ferri8d009a02009-06-23 22:34:06 -03001283static int xc4000_set_analog_params(struct dvb_frontend *fe,
1284 struct analog_parameters *params)
1285{
1286 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga818a1772011-06-04 12:17:22 -03001287 unsigned int type = 0;
Istvan Varga56149422011-06-03 12:23:33 -03001288 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001289
Istvan Varga818a1772011-06-04 12:17:22 -03001290 if (params->mode == V4L2_TUNER_RADIO) {
1291 dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
1292 __func__, params->frequency);
1293
1294 mutex_lock(&priv->lock);
1295
1296 params->std = 0;
1297 priv->freq_hz = params->frequency * 125L / 2;
1298
1299 if (audio_std & XC4000_AUDIO_STD_INPUT1) {
1300 priv->video_standard = XC4000_FM_Radio_INPUT1;
1301 type = FM | INPUT1;
1302 } else {
1303 priv->video_standard = XC4000_FM_Radio_INPUT2;
1304 type = FM | INPUT2;
1305 }
1306
1307 goto tune_channel;
1308 }
1309
Davide Ferri8d009a02009-06-23 22:34:06 -03001310 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1311 __func__, params->frequency);
1312
Istvan Varga56149422011-06-03 12:23:33 -03001313 mutex_lock(&priv->lock);
1314
Davide Ferri8d009a02009-06-23 22:34:06 -03001315 /* params->frequency is in units of 62.5khz */
1316 priv->freq_hz = params->frequency * 62500;
1317
Istvan Varga818a1772011-06-04 12:17:22 -03001318 params->std &= V4L2_STD_ALL;
1319 /* if std is not defined, choose one */
1320 if (!params->std)
1321 params->std = V4L2_STD_PAL_BG;
1322
1323 if (audio_std & XC4000_AUDIO_STD_MONO)
1324 type = MONO;
1325
Davide Ferri8d009a02009-06-23 22:34:06 -03001326 if (params->std & V4L2_STD_MN) {
Istvan Varga818a1772011-06-04 12:17:22 -03001327 params->std = V4L2_STD_MN;
1328 if (audio_std & XC4000_AUDIO_STD_MONO) {
1329 priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
1330 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1331 params->std |= V4L2_STD_A2;
1332 priv->video_standard = XC4000_MN_NTSC_PAL_A2;
1333 } else {
1334 params->std |= V4L2_STD_BTSC;
1335 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
1336 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001337 goto tune_channel;
1338 }
1339
1340 if (params->std & V4L2_STD_PAL_BG) {
Istvan Varga818a1772011-06-04 12:17:22 -03001341 params->std = V4L2_STD_PAL_BG;
1342 if (audio_std & XC4000_AUDIO_STD_MONO) {
1343 priv->video_standard = XC4000_BG_PAL_MONO;
1344 } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
1345 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1346 params->std |= V4L2_STD_NICAM_A;
1347 priv->video_standard = XC4000_BG_PAL_NICAM;
1348 } else {
1349 params->std |= V4L2_STD_NICAM_B;
1350 priv->video_standard = XC4000_BG_PAL_NICAM;
1351 }
1352 } else {
1353 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1354 params->std |= V4L2_STD_A2_A;
1355 priv->video_standard = XC4000_BG_PAL_A2;
1356 } else {
1357 params->std |= V4L2_STD_A2_B;
1358 priv->video_standard = XC4000_BG_PAL_A2;
1359 }
1360 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001361 goto tune_channel;
1362 }
1363
1364 if (params->std & V4L2_STD_PAL_I) {
1365 /* default to NICAM audio standard */
Istvan Varga818a1772011-06-04 12:17:22 -03001366 params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
1367 if (audio_std & XC4000_AUDIO_STD_MONO) {
1368 priv->video_standard = XC4000_I_PAL_NICAM_MONO;
1369 } else {
1370 priv->video_standard = XC4000_I_PAL_NICAM;
1371 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001372 goto tune_channel;
1373 }
1374
1375 if (params->std & V4L2_STD_PAL_DK) {
Istvan Varga818a1772011-06-04 12:17:22 -03001376 params->std = V4L2_STD_PAL_DK;
1377 if (audio_std & XC4000_AUDIO_STD_MONO) {
1378 priv->video_standard = XC4000_DK_PAL_MONO;
1379 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1380 params->std |= V4L2_STD_A2;
1381 priv->video_standard = XC4000_DK_PAL_A2;
1382 } else {
1383 params->std |= V4L2_STD_NICAM;
1384 priv->video_standard = XC4000_DK_PAL_NICAM;
1385 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001386 goto tune_channel;
1387 }
1388
1389 if (params->std & V4L2_STD_SECAM_DK) {
Istvan Varga818a1772011-06-04 12:17:22 -03001390 /* default to A2 audio standard */
1391 params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
1392 if (audio_std & XC4000_AUDIO_STD_L) {
1393 type = 0;
1394 priv->video_standard = XC4000_DK_SECAM_NICAM;
1395 } else if (audio_std & XC4000_AUDIO_STD_MONO) {
1396 priv->video_standard = XC4000_DK_SECAM_A2MONO;
1397 } else if (audio_std & XC4000_AUDIO_STD_K3) {
1398 params->std |= V4L2_STD_SECAM_K3;
1399 priv->video_standard = XC4000_DK_SECAM_A2LDK3;
1400 } else {
1401 priv->video_standard = XC4000_DK_SECAM_A2DK1;
1402 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001403 goto tune_channel;
1404 }
1405
1406 if (params->std & V4L2_STD_SECAM_L) {
Istvan Varga818a1772011-06-04 12:17:22 -03001407 /* default to NICAM audio standard */
1408 type = 0;
1409 params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001410 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001411 goto tune_channel;
1412 }
1413
1414 if (params->std & V4L2_STD_SECAM_LC) {
Istvan Varga818a1772011-06-04 12:17:22 -03001415 /* default to NICAM audio standard */
1416 type = 0;
1417 params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001418 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001419 goto tune_channel;
1420 }
1421
1422tune_channel:
Istvan Varga818a1772011-06-04 12:17:22 -03001423 /* Fix me: it could be air. */
1424 priv->rf_mode = XC_RF_MODE_CABLE;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001425
Istvan Varga818a1772011-06-04 12:17:22 -03001426 if (check_firmware(fe, type, params->std,
1427 XC4000_Standard[priv->video_standard].int_freq)
1428 != XC_RESULT_SUCCESS) {
Istvan Varga56149422011-06-03 12:23:33 -03001429 goto fail;
Istvan Varga818a1772011-06-04 12:17:22 -03001430 }
Devin Heitmuellered23db32009-10-05 01:27:14 -03001431
Davide Ferri8d009a02009-06-23 22:34:06 -03001432 ret = xc_SetSignalSource(priv, priv->rf_mode);
1433 if (ret != XC_RESULT_SUCCESS) {
1434 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001435 "xc4000: xc_SetSignalSource(%d) failed\n",
1436 priv->rf_mode);
1437 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001438 } else {
1439 u16 video_mode, audio_mode;
1440 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1441 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1442 if (priv->video_standard < XC4000_BG_PAL_A2) {
1443 if (0 /*type & NOGD*/)
1444 video_mode &= 0xFF7F;
1445 } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
1446 if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
1447 priv->firm_version == 0x0102)
1448 video_mode &= 0xFEFF;
Istvan Varga923137a2011-06-04 12:15:51 -03001449 if (audio_std & XC4000_AUDIO_STD_B)
1450 video_mode |= 0x0080;
Istvan Varga30f544e2011-06-04 12:12:42 -03001451 }
1452 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1453 if (ret != XC_RESULT_SUCCESS) {
1454 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1455 goto fail;
1456 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001457 }
1458
Istvan Varga30f544e2011-06-04 12:12:42 -03001459 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1460 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1461 ret = 0;
1462 if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
1463 ret = -EREMOTEIO;
1464 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1465 ret = -EREMOTEIO;
1466 if (ret != 0) {
1467 printk(KERN_ERR "xc4000: setting registers failed\n");
1468 goto fail;
1469 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001470 }
1471
Istvan Vargae75873c2011-06-04 12:18:41 -03001472 xc_tune_channel(priv, priv->freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001473
Istvan Varga56149422011-06-03 12:23:33 -03001474 ret = 0;
1475
1476fail:
1477 mutex_unlock(&priv->lock);
1478
1479 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001480}
1481
1482static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1483{
1484 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001485
Davide Ferri8d009a02009-06-23 22:34:06 -03001486 *freq = priv->freq_hz;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001487
1488 if (debug) {
1489 mutex_lock(&priv->lock);
1490 if ((priv->cur_fw.type
1491 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1492 u16 snr = 0;
1493 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1494 mutex_unlock(&priv->lock);
1495 dprintk(1, "%s() freq = %u, SNR = %d\n",
1496 __func__, *freq, snr);
1497 return 0;
1498 }
1499 }
1500 mutex_unlock(&priv->lock);
1501 }
1502
1503 dprintk(1, "%s()\n", __func__);
1504
Davide Ferri8d009a02009-06-23 22:34:06 -03001505 return 0;
1506}
1507
1508static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1509{
1510 struct xc4000_priv *priv = fe->tuner_priv;
1511 dprintk(1, "%s()\n", __func__);
1512
1513 *bw = priv->bandwidth;
1514 return 0;
1515}
1516
1517static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1518{
1519 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001520 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001521
Istvan Varga56149422011-06-03 12:23:33 -03001522 mutex_lock(&priv->lock);
1523
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001524 if (priv->cur_fw.type & BASE)
1525 xc_get_lock_status(priv, &lock_status);
1526
1527 *status = (lock_status == 1 ?
1528 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1529 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1530 *status &= (~TUNER_STATUS_STEREO);
Davide Ferri8d009a02009-06-23 22:34:06 -03001531
Istvan Varga56149422011-06-03 12:23:33 -03001532 mutex_unlock(&priv->lock);
1533
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001534 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001535
1536 return 0;
1537}
1538
Davide Ferri8d009a02009-06-23 22:34:06 -03001539static int xc4000_sleep(struct dvb_frontend *fe)
1540{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001541 struct xc4000_priv *priv = fe->tuner_priv;
1542 int ret = XC_RESULT_SUCCESS;
1543
1544 dprintk(1, "%s()\n", __func__);
1545
1546 mutex_lock(&priv->lock);
1547
1548 /* Avoid firmware reload on slow devices */
1549 if ((no_poweroff == 2 ||
1550 (no_poweroff == 0 &&
1551 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1552 (priv->cur_fw.type & BASE) != 0) {
1553 /* force reset and firmware reload */
1554 priv->cur_fw.type = XC_POWERED_DOWN;
1555
1556 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1557 != XC_RESULT_SUCCESS) {
1558 printk(KERN_ERR
1559 "xc4000: %s() unable to shutdown tuner\n",
1560 __func__);
1561 ret = -EREMOTEIO;
1562 }
1563 xc_wait(20);
1564 }
1565
1566 mutex_unlock(&priv->lock);
1567
1568 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001569}
1570
1571static int xc4000_init(struct dvb_frontend *fe)
1572{
Davide Ferri8d009a02009-06-23 22:34:06 -03001573 dprintk(1, "%s()\n", __func__);
1574
Davide Ferri8d009a02009-06-23 22:34:06 -03001575 return 0;
1576}
1577
1578static int xc4000_release(struct dvb_frontend *fe)
1579{
1580 struct xc4000_priv *priv = fe->tuner_priv;
1581
1582 dprintk(1, "%s()\n", __func__);
1583
1584 mutex_lock(&xc4000_list_mutex);
1585
1586 if (priv)
1587 hybrid_tuner_release_state(priv);
1588
1589 mutex_unlock(&xc4000_list_mutex);
1590
1591 fe->tuner_priv = NULL;
1592
1593 return 0;
1594}
1595
1596static const struct dvb_tuner_ops xc4000_tuner_ops = {
1597 .info = {
1598 .name = "Xceive XC4000",
1599 .frequency_min = 1000000,
1600 .frequency_max = 1023000000,
1601 .frequency_step = 50000,
1602 },
1603
1604 .release = xc4000_release,
1605 .init = xc4000_init,
1606 .sleep = xc4000_sleep,
1607
1608 .set_params = xc4000_set_params,
1609 .set_analog_params = xc4000_set_analog_params,
1610 .get_frequency = xc4000_get_frequency,
1611 .get_bandwidth = xc4000_get_bandwidth,
1612 .get_status = xc4000_get_status
1613};
1614
1615struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1616 struct i2c_adapter *i2c,
1617 struct xc4000_config *cfg)
1618{
1619 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001620 int instance;
1621 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001622
Istvan Varga0b402132011-06-03 09:38:04 -03001623 if (cfg->card_type != XC4000_CARD_GENERIC) {
1624 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1625 cfg->i2c_address = 0x61;
1626 cfg->if_khz = 4560;
1627 } else { /* default to PCTV 340E */
1628 cfg->i2c_address = 0x61;
1629 cfg->if_khz = 5400;
1630 }
1631 }
1632
Davide Ferri8d009a02009-06-23 22:34:06 -03001633 dprintk(1, "%s(%d-%04x)\n", __func__,
1634 i2c ? i2c_adapter_id(i2c) : -1,
1635 cfg ? cfg->i2c_address : -1);
1636
1637 mutex_lock(&xc4000_list_mutex);
1638
1639 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1640 hybrid_tuner_instance_list,
1641 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001642 if (cfg->card_type != XC4000_CARD_GENERIC)
1643 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001644 switch (instance) {
1645 case 0:
1646 goto fail;
1647 break;
1648 case 1:
1649 /* new tuner instance */
1650 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001651 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001652 fe->tuner_priv = priv;
1653 break;
1654 default:
1655 /* existing tuner instance */
1656 fe->tuner_priv = priv;
1657 break;
1658 }
1659
Istvan Varga0b402132011-06-03 09:38:04 -03001660 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001661 /* If the IF hasn't been set yet, use the value provided by
1662 the caller (occurs in hybrid devices where the analog
1663 call to xc4000_attach occurs before the digital side) */
1664 priv->if_khz = cfg->if_khz;
1665 }
1666
1667 /* Check if firmware has been loaded. It is possible that another
1668 instance of the driver has loaded the firmware.
1669 */
1670
Istvan Varga027fd362011-06-04 12:04:51 -03001671 if (instance == 1) {
1672 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1673 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001674 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001675 } else {
1676 id = ((priv->cur_fw.type & BASE) != 0 ?
1677 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1678 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001679
1680 switch (id) {
1681 case XC_PRODUCT_ID_FW_LOADED:
1682 printk(KERN_INFO
1683 "xc4000: Successfully identified at address 0x%02x\n",
1684 cfg->i2c_address);
1685 printk(KERN_INFO
1686 "xc4000: Firmware has been loaded previously\n");
1687 break;
1688 case XC_PRODUCT_ID_FW_NOT_LOADED:
1689 printk(KERN_INFO
1690 "xc4000: Successfully identified at address 0x%02x\n",
1691 cfg->i2c_address);
1692 printk(KERN_INFO
1693 "xc4000: Firmware has not been loaded previously\n");
1694 break;
1695 default:
1696 printk(KERN_ERR
1697 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1698 cfg->i2c_address, id);
1699 goto fail;
1700 }
1701
1702 mutex_unlock(&xc4000_list_mutex);
1703
1704 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1705 sizeof(struct dvb_tuner_ops));
1706
Istvan Varga027fd362011-06-04 12:04:51 -03001707 if (instance == 1) {
1708 int ret;
1709 mutex_lock(&priv->lock);
1710 ret = xc4000_fwupload(fe);
1711 mutex_unlock(&priv->lock);
1712 if (ret != XC_RESULT_SUCCESS)
1713 goto fail2;
1714 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001715
Davide Ferri8d009a02009-06-23 22:34:06 -03001716 return fe;
1717fail:
1718 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001719fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001720 xc4000_release(fe);
1721 return NULL;
1722}
1723EXPORT_SYMBOL(xc4000_attach);
1724
1725MODULE_AUTHOR("Steven Toth, Davide Ferri");
1726MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1727MODULE_LICENSE("GPL");