blob: 160ca26286cc4b843a3ba2c205d1bbe785ef9c68 [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
Istvan Varga7db98fe2011-06-04 12:25:19 -0300143#define XC_PRODUCT_ID_XC4000 0x0FA0
144#define XC_PRODUCT_ID_XC4100 0x1004
Davide Ferri8d009a02009-06-23 22:34:06 -0300145
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300146/* Registers (Write-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300147#define XREG_INIT 0x00
148#define XREG_VIDEO_MODE 0x01
149#define XREG_AUDIO_MODE 0x02
150#define XREG_RF_FREQ 0x03
151#define XREG_D_CODE 0x04
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300152#define XREG_DIRECTSITTING_MODE 0x05
153#define XREG_SEEK_MODE 0x06
154#define XREG_POWER_DOWN 0x08
155#define XREG_SIGNALSOURCE 0x0A
Istvan Varga30f544e2011-06-04 12:12:42 -0300156#define XREG_SMOOTHEDCVBS 0x0E
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300157#define XREG_AMPLITUDE 0x10
Davide Ferri8d009a02009-06-23 22:34:06 -0300158
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300159/* Registers (Read-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300160#define XREG_ADC_ENV 0x00
161#define XREG_QUALITY 0x01
162#define XREG_FRAME_LINES 0x02
163#define XREG_HSYNC_FREQ 0x03
164#define XREG_LOCK 0x04
165#define XREG_FREQ_ERROR 0x05
166#define XREG_SNR 0x06
167#define XREG_VERSION 0x07
168#define XREG_PRODUCT_ID 0x08
Davide Ferri8d009a02009-06-23 22:34:06 -0300169
170/*
171 Basic firmware description. This will remain with
172 the driver for documentation purposes.
173
174 This represents an I2C firmware file encoded as a
175 string of unsigned char. Format is as follows:
176
177 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
178 char[1 ]=len0_LSB -> length of first write transaction
179 char[2 ]=data0 -> first byte to be sent
180 char[3 ]=data1
181 char[4 ]=data2
182 char[ ]=...
183 char[M ]=dataN -> last byte to be sent
184 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
185 char[M+2]=len1_LSB -> length of second write transaction
186 char[M+3]=data0
187 char[M+4]=data1
188 ...
189 etc.
190
191 The [len] value should be interpreted as follows:
192
193 len= len_MSB _ len_LSB
194 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
195 len=0000_0000_0000_0000 : Reset command: Do hardware reset
196 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
197 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
198
199 For the RESET and WAIT commands, the two following bytes will contain
200 immediately the length of the following transaction.
Davide Ferri8d009a02009-06-23 22:34:06 -0300201*/
Istvan Vargafbe4a292011-06-03 10:11:48 -0300202
Davide Ferri8d009a02009-06-23 22:34:06 -0300203struct XC_TV_STANDARD {
Istvan Vargafbe4a292011-06-03 10:11:48 -0300204 const char *Name;
205 u16 AudioMode;
206 u16 VideoMode;
Istvan Varga49110852011-06-03 10:55:24 -0300207 u16 int_freq;
Davide Ferri8d009a02009-06-23 22:34:06 -0300208};
209
210/* Tuner standards */
Devin Heitmuellered23db32009-10-05 01:27:14 -0300211#define XC4000_MN_NTSC_PAL_BTSC 0
212#define XC4000_MN_NTSC_PAL_A2 1
213#define XC4000_MN_NTSC_PAL_EIAJ 2
214#define XC4000_MN_NTSC_PAL_Mono 3
215#define XC4000_BG_PAL_A2 4
216#define XC4000_BG_PAL_NICAM 5
217#define XC4000_BG_PAL_MONO 6
218#define XC4000_I_PAL_NICAM 7
219#define XC4000_I_PAL_NICAM_MONO 8
220#define XC4000_DK_PAL_A2 9
221#define XC4000_DK_PAL_NICAM 10
222#define XC4000_DK_PAL_MONO 11
223#define XC4000_DK_SECAM_A2DK1 12
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300224#define XC4000_DK_SECAM_A2LDK3 13
225#define XC4000_DK_SECAM_A2MONO 14
Istvan Varga49110852011-06-03 10:55:24 -0300226#define XC4000_DK_SECAM_NICAM 15
227#define XC4000_L_SECAM_NICAM 16
228#define XC4000_LC_SECAM_NICAM 17
229#define XC4000_DTV6 18
230#define XC4000_DTV8 19
231#define XC4000_DTV7_8 20
232#define XC4000_DTV7 21
233#define XC4000_FM_Radio_INPUT2 22
234#define XC4000_FM_Radio_INPUT1 23
Davide Ferri8d009a02009-06-23 22:34:06 -0300235
Davide Ferri8d009a02009-06-23 22:34:06 -0300236static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
Istvan Varga49110852011-06-03 10:55:24 -0300237 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
238 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
239 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
240 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
241 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
242 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
243 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
244 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
245 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
246 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
247 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
248 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
249 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
250 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
251 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
252 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
253 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
254 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
255 {"DTV6", 0x00C0, 0x8002, 0},
256 {"DTV8", 0x00C0, 0x800B, 0},
257 {"DTV7/8", 0x00C0, 0x801B, 0},
258 {"DTV7", 0x00C0, 0x8007, 0},
259 {"FM Radio-INPUT2", 0x0008, 0x9800,10700},
260 {"FM Radio-INPUT1", 0x0008, 0x9000,10700}
Davide Ferri8d009a02009-06-23 22:34:06 -0300261};
262
Davide Ferri8d009a02009-06-23 22:34:06 -0300263static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
264static int xc4000_TunerReset(struct dvb_frontend *fe);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300265static void xc_debug_dump(struct xc4000_priv *priv);
Davide Ferri8d009a02009-06-23 22:34:06 -0300266
267static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
268{
269 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
270 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300271 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300272 if (priv->ignore_i2c_write_errors == 0) {
273 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
274 len);
275 if (len == 4) {
276 printk("bytes %02x %02x %02x %02x\n", buf[0],
277 buf[1], buf[2], buf[3]);
278 }
279 return XC_RESULT_I2C_WRITE_FAILURE;
280 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300281 }
282 return XC_RESULT_SUCCESS;
283}
284
Davide Ferri8d009a02009-06-23 22:34:06 -0300285static void xc_wait(int wait_ms)
286{
287 msleep(wait_ms);
288}
289
290static int xc4000_TunerReset(struct dvb_frontend *fe)
291{
292 struct xc4000_priv *priv = fe->tuner_priv;
293 int ret;
294
295 dprintk(1, "%s()\n", __func__);
296
297 if (fe->callback) {
298 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
299 fe->dvb->priv :
300 priv->i2c_props.adap->algo_data,
301 DVB_FRONTEND_COMPONENT_TUNER,
302 XC4000_TUNER_RESET, 0);
303 if (ret) {
304 printk(KERN_ERR "xc4000: reset failed\n");
305 return XC_RESULT_RESET_FAILURE;
306 }
307 } else {
308 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
309 return XC_RESULT_RESET_FAILURE;
310 }
311 return XC_RESULT_SUCCESS;
312}
313
314static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
315{
316 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300317 int result;
318
319 buf[0] = (regAddr >> 8) & 0xFF;
320 buf[1] = regAddr & 0xFF;
321 buf[2] = (i2cData >> 8) & 0xFF;
322 buf[3] = i2cData & 0xFF;
323 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300324
325 return result;
326}
327
328static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
329{
330 struct xc4000_priv *priv = fe->tuner_priv;
331
332 int i, nbytes_to_send, result;
333 unsigned int len, pos, index;
334 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
335
336 index = 0;
337 while ((i2c_sequence[index] != 0xFF) ||
338 (i2c_sequence[index + 1] != 0xFF)) {
339 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
340 if (len == 0x0000) {
341 /* RESET command */
Davide Ferri8d009a02009-06-23 22:34:06 -0300342 index += 2;
Istvan Varga8f76afe2011-06-04 12:21:17 -0300343#if 0 /* not needed, as already called by check_firmware() */
344 result = xc4000_TunerReset(fe);
Davide Ferri8d009a02009-06-23 22:34:06 -0300345 if (result != XC_RESULT_SUCCESS)
346 return result;
Istvan Varga8f76afe2011-06-04 12:21:17 -0300347#endif
Davide Ferri8d009a02009-06-23 22:34:06 -0300348 } 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
Davide Ferri8d009a02009-06-23 22:34:06 -0300384static int xc_SetTVStandard(struct xc4000_priv *priv,
385 u16 VideoMode, u16 AudioMode)
386{
387 int ret;
388 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
389 dprintk(1, "%s() Standard = %s\n",
390 __func__,
391 XC4000_Standard[priv->video_standard].Name);
392
Devin Heitmueller799ed112009-10-04 23:09:18 -0300393 /* Don't complain when the request fails because of i2c stretching */
394 priv->ignore_i2c_write_errors = 1;
395
Davide Ferri8d009a02009-06-23 22:34:06 -0300396 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
397 if (ret == XC_RESULT_SUCCESS)
398 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
399
Devin Heitmueller799ed112009-10-04 23:09:18 -0300400 priv->ignore_i2c_write_errors = 0;
401
Davide Ferri8d009a02009-06-23 22:34:06 -0300402 return ret;
403}
404
405static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
406{
407 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
408 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
409
410 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
411 rf_mode = XC_RF_MODE_CABLE;
412 printk(KERN_ERR
413 "%s(), Invalid mode, defaulting to CABLE",
414 __func__);
415 }
416 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
417}
418
419static const struct dvb_tuner_ops xc4000_tuner_ops;
420
421static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
422{
423 u16 freq_code;
424
425 dprintk(1, "%s(%u)\n", __func__, freq_hz);
426
427 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
428 (freq_hz < xc4000_tuner_ops.info.frequency_min))
429 return XC_RESULT_OUT_OF_RANGE;
430
431 freq_code = (u16)(freq_hz / 15625);
432
433 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
434 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
435 only be used for fast scanning for channel lock) */
436 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
437}
438
Davide Ferri8d009a02009-06-23 22:34:06 -0300439static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
440{
441 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
442}
443
444static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
445{
446 int result;
447 u16 regData;
448 u32 tmp;
449
450 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
451 if (result != XC_RESULT_SUCCESS)
452 return result;
453
Istvan Varga1368ceb2011-06-03 12:27:30 -0300454 tmp = (u32)regData & 0xFFFFU;
455 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
456 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300457 return result;
458}
459
460static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
461{
462 return xc4000_readreg(priv, XREG_LOCK, lock_status);
463}
464
465static int xc_get_version(struct xc4000_priv *priv,
466 u8 *hw_majorversion, u8 *hw_minorversion,
467 u8 *fw_majorversion, u8 *fw_minorversion)
468{
469 u16 data;
470 int result;
471
472 result = xc4000_readreg(priv, XREG_VERSION, &data);
473 if (result != XC_RESULT_SUCCESS)
474 return result;
475
476 (*hw_majorversion) = (data >> 12) & 0x0F;
477 (*hw_minorversion) = (data >> 8) & 0x0F;
478 (*fw_majorversion) = (data >> 4) & 0x0F;
479 (*fw_minorversion) = data & 0x0F;
480
481 return 0;
482}
483
Davide Ferri8d009a02009-06-23 22:34:06 -0300484static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
485{
486 u16 regData;
487 int result;
488
489 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
490 if (result != XC_RESULT_SUCCESS)
491 return result;
492
493 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
494 return result;
495}
496
497static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
498{
499 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
500}
501
502static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
503{
504 return xc4000_readreg(priv, XREG_QUALITY, quality);
505}
506
507static u16 WaitForLock(struct xc4000_priv *priv)
508{
509 u16 lockState = 0;
510 int watchDogCount = 40;
511
512 while ((lockState == 0) && (watchDogCount > 0)) {
513 xc_get_lock_status(priv, &lockState);
514 if (lockState != 1) {
515 xc_wait(5);
516 watchDogCount--;
517 }
518 }
519 return lockState;
520}
521
Istvan Vargae75873c2011-06-04 12:18:41 -0300522static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
Davide Ferri8d009a02009-06-23 22:34:06 -0300523{
Istvan Vargae75873c2011-06-04 12:18:41 -0300524 int found = 1;
525 int result;
Davide Ferri8d009a02009-06-23 22:34:06 -0300526
527 dprintk(1, "%s(%u)\n", __func__, freq_hz);
528
Devin Heitmueller799ed112009-10-04 23:09:18 -0300529 /* Don't complain when the request fails because of i2c stretching */
530 priv->ignore_i2c_write_errors = 1;
531 result = xc_set_RF_frequency(priv, freq_hz);
532 priv->ignore_i2c_write_errors = 0;
533
534 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300535 return 0;
536
Istvan Vargae75873c2011-06-04 12:18:41 -0300537 /* wait for lock only in analog TV mode */
538 if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
539 if (WaitForLock(priv) != 1)
540 found = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300541 }
542
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300543 /* Wait for stats to stabilize.
544 * Frame Lines needs two frame times after initial lock
545 * before it is valid.
546 */
547 xc_wait(debug ? 100 : 10);
548
549 if (debug)
550 xc_debug_dump(priv);
551
Davide Ferri8d009a02009-06-23 22:34:06 -0300552 return found;
553}
554
555static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
556{
557 u8 buf[2] = { reg >> 8, reg & 0xff };
558 u8 bval[2] = { 0, 0 };
559 struct i2c_msg msg[2] = {
560 { .addr = priv->i2c_props.addr,
561 .flags = 0, .buf = &buf[0], .len = 2 },
562 { .addr = priv->i2c_props.addr,
563 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
564 };
565
566 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
567 printk(KERN_WARNING "xc4000: I2C read failed\n");
568 return -EREMOTEIO;
569 }
570
571 *val = (bval[0] << 8) | bval[1];
572 return XC_RESULT_SUCCESS;
573}
574
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300575#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300576static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
577{
578 if (type & BASE)
579 printk("BASE ");
580 if (type & INIT1)
581 printk("INIT1 ");
582 if (type & F8MHZ)
583 printk("F8MHZ ");
584 if (type & MTS)
585 printk("MTS ");
586 if (type & D2620)
587 printk("D2620 ");
588 if (type & D2633)
589 printk("D2633 ");
590 if (type & DTV6)
591 printk("DTV6 ");
592 if (type & QAM)
593 printk("QAM ");
594 if (type & DTV7)
595 printk("DTV7 ");
596 if (type & DTV78)
597 printk("DTV78 ");
598 if (type & DTV8)
599 printk("DTV8 ");
600 if (type & FM)
601 printk("FM ");
602 if (type & INPUT1)
603 printk("INPUT1 ");
604 if (type & LCD)
605 printk("LCD ");
606 if (type & NOGD)
607 printk("NOGD ");
608 if (type & MONO)
609 printk("MONO ");
610 if (type & ATSC)
611 printk("ATSC ");
612 if (type & IF)
613 printk("IF ");
614 if (type & LG60)
615 printk("LG60 ");
616 if (type & ATI638)
617 printk("ATI638 ");
618 if (type & OREN538)
619 printk("OREN538 ");
620 if (type & OREN36)
621 printk("OREN36 ");
622 if (type & TOYOTA388)
623 printk("TOYOTA388 ");
624 if (type & TOYOTA794)
625 printk("TOYOTA794 ");
626 if (type & DIBCOM52)
627 printk("DIBCOM52 ");
628 if (type & ZARLINK456)
629 printk("ZARLINK456 ");
630 if (type & CHINA)
631 printk("CHINA ");
632 if (type & F6MHZ)
633 printk("F6MHZ ");
634 if (type & INPUT2)
635 printk("INPUT2 ");
636 if (type & SCODE)
637 printk("SCODE ");
638 if (type & HAS_IF)
639 printk("HAS_IF_%d ", int_freq);
640}
641
Devin Heitmueller11091a32009-07-20 00:54:57 -0300642static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
643 v4l2_std_id *id)
644{
645 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300646 int i, best_i = -1;
647 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300648
Devin Heitmueller11091a32009-07-20 00:54:57 -0300649 if (!priv->firm) {
650 printk("Error! firmware not loaded\n");
651 return -EINVAL;
652 }
653
654 if (((type & ~SCODE) == 0) && (*id == 0))
655 *id = V4L2_STD_PAL;
656
Devin Heitmueller11091a32009-07-20 00:54:57 -0300657 /* Seek for generic video standard match */
658 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300659 v4l2_std_id id_diff_mask =
660 (priv->firm[i].id ^ (*id)) & (*id);
661 unsigned int type_diff_mask =
662 (priv->firm[i].type ^ type)
663 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
664 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300665
Istvan Varga3db95702011-06-04 11:52:34 -0300666 if (type_diff_mask
667 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300668 continue;
669
Istvan Varga3db95702011-06-04 11:52:34 -0300670 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
671 if (!nr_diffs) /* Supports all the requested standards */
672 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300673
Istvan Varga3db95702011-06-04 11:52:34 -0300674 if (nr_diffs < best_nr_diffs) {
675 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300676 best_i = i;
677 }
678 }
679
Istvan Varga3db95702011-06-04 11:52:34 -0300680 /* FIXME: Would make sense to seek for type "hint" match ? */
681 if (best_i < 0) {
682 i = -ENOENT;
683 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300684 }
685
Istvan Varga3db95702011-06-04 11:52:34 -0300686 if (best_nr_diffs > 0U) {
687 printk("Selecting best matching firmware (%u bits differ) for "
688 "type=", best_nr_diffs);
689 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
690 i = best_i;
691 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300692
693found:
694 *id = priv->firm[i].id;
695
696ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300697 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300698 printk("%s firmware for type=", (i < 0) ? "Can't find" :
699 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300700 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300701 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
702 }
703 return i;
704}
705
706static int load_firmware(struct dvb_frontend *fe, unsigned int type,
707 v4l2_std_id *id)
708{
709 struct xc4000_priv *priv = fe->tuner_priv;
710 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300711 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300712
Devin Heitmueller11091a32009-07-20 00:54:57 -0300713 pos = seek_firmware(fe, type, id);
714 if (pos < 0)
715 return pos;
716
Devin Heitmueller11091a32009-07-20 00:54:57 -0300717 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300718
Devin Heitmueller799ed112009-10-04 23:09:18 -0300719 /* Don't complain when the request fails because of i2c stretching */
720 priv->ignore_i2c_write_errors = 1;
721
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300722 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300723
Devin Heitmueller799ed112009-10-04 23:09:18 -0300724 priv->ignore_i2c_write_errors = 0;
725
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300726 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300727}
728
Davide Ferri8d009a02009-06-23 22:34:06 -0300729static int xc4000_fwupload(struct dvb_frontend *fe)
730{
731 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300732 const struct firmware *fw = NULL;
733 const unsigned char *p, *endp;
734 int rc = 0;
735 int n, n_array;
736 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300737 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300738
Istvan Vargafa285bc2011-06-04 11:48:16 -0300739 if (firmware_name[0] != '\0')
740 fname = firmware_name;
741 else
742 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300743
744 printk("Reading firmware %s\n", fname);
745 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
746 if (rc < 0) {
747 if (rc == -ENOENT)
748 printk("Error: firmware %s not found.\n",
749 fname);
750 else
751 printk("Error %d while requesting firmware %s \n",
752 rc, fname);
753
754 return rc;
755 }
756 p = fw->data;
757 endp = p + fw->size;
758
759 if (fw->size < sizeof(name) - 1 + 2 + 2) {
760 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300761 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300762 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300763 }
764
Devin Heitmueller11091a32009-07-20 00:54:57 -0300765 memcpy(name, p, sizeof(name) - 1);
766 name[sizeof(name) - 1] = 0;
767 p += sizeof(name) - 1;
768
769 priv->firm_version = get_unaligned_le16(p);
770 p += 2;
771
772 n_array = get_unaligned_le16(p);
773 p += 2;
774
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300775 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
776 n_array, fname, name,
777 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300778
779 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
780 if (priv->firm == NULL) {
781 printk("Not enough memory to load firmware file.\n");
782 rc = -ENOMEM;
783 goto err;
784 }
785 priv->firm_size = n_array;
786
787 n = -1;
788 while (p < endp) {
789 __u32 type, size;
790 v4l2_std_id id;
791 __u16 int_freq = 0;
792
793 n++;
794 if (n >= n_array) {
795 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300796 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300797 goto corrupt;
798 }
799
800 /* Checks if there's enough bytes to read */
801 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
802 goto header;
803
804 type = get_unaligned_le32(p);
805 p += sizeof(type);
806
807 id = get_unaligned_le64(p);
808 p += sizeof(id);
809
810 if (type & HAS_IF) {
811 int_freq = get_unaligned_le16(p);
812 p += sizeof(int_freq);
813 if (endp - p < sizeof(size))
814 goto header;
815 }
816
817 size = get_unaligned_le32(p);
818 p += sizeof(size);
819
820 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300821 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300822 "(size=%d, expected %d)\n",
823 type, (unsigned long long)id,
824 (unsigned)(endp - p), size);
825 goto corrupt;
826 }
827
828 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
829 if (priv->firm[n].ptr == NULL) {
830 printk("Not enough memory to load firmware file.\n");
831 rc = -ENOMEM;
832 goto err;
833 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300834
Devin Heitmueller11091a32009-07-20 00:54:57 -0300835 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300836 printk("Reading firmware type ");
837 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300838 printk("(%x), id %llx, size=%d.\n",
839 type, (unsigned long long)id, size);
840 }
841
842 memcpy(priv->firm[n].ptr, p, size);
843 priv->firm[n].type = type;
844 priv->firm[n].id = id;
845 priv->firm[n].size = size;
846 priv->firm[n].int_freq = int_freq;
847
848 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300849 }
850
Devin Heitmueller11091a32009-07-20 00:54:57 -0300851 if (n + 1 != priv->firm_size) {
852 printk("Firmware file is incomplete!\n");
853 goto corrupt;
854 }
855
856 goto done;
857
858header:
859 printk("Firmware header is incomplete!\n");
860corrupt:
861 rc = -EINVAL;
862 printk("Error: firmware file is corrupted!\n");
863
864err:
865 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300866
867done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300868 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300869 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300870 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300871
872 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300873}
874
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300875static int load_scode(struct dvb_frontend *fe, unsigned int type,
876 v4l2_std_id *id, __u16 int_freq, int scode)
877{
878 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300879 int pos, rc;
880 unsigned char *p;
881 u8 scode_buf[13];
882 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300883
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300884 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300885
886 if (!int_freq) {
887 pos = seek_firmware(fe, type, id);
888 if (pos < 0)
889 return pos;
890 } else {
891 for (pos = 0; pos < priv->firm_size; pos++) {
892 if ((priv->firm[pos].int_freq == int_freq) &&
893 (priv->firm[pos].type & HAS_IF))
894 break;
895 }
896 if (pos == priv->firm_size)
897 return -ENOENT;
898 }
899
900 p = priv->firm[pos].ptr;
901
Istvan Vargaffce6262011-06-04 11:56:18 -0300902 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
903 return -EINVAL;
904 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300905
906 tuner_info("Loading SCODE for type=");
907 dump_firm_type_and_int_freq(priv->firm[pos].type,
908 priv->firm[pos].int_freq);
909 printk("(%x), id %016llx.\n", priv->firm[pos].type,
910 (unsigned long long)*id);
911
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300912 scode_buf[0] = 0x00;
913 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300914
915 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300916 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
917 if (rc < 0) {
918 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300919 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300920 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300921
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300922 rc = xc_send_i2c_data(priv, scode_buf, 13);
923 if (rc != XC_RESULT_SUCCESS) {
924 /* Even if the send failed, make sure we set back to indirect
925 mode */
926 printk("Failed to set scode %d\n", rc);
927 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300928
929 /* Switch back to indirect-mode */
930 memset(indirect_mode, 0, sizeof(indirect_mode));
931 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300932 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
933 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300934
935 return 0;
936}
937
938static int check_firmware(struct dvb_frontend *fe, unsigned int type,
939 v4l2_std_id std, __u16 int_freq)
940{
941 struct xc4000_priv *priv = fe->tuner_priv;
942 struct firmware_properties new_fw;
943 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300944 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300945 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300946 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300947
948 dprintk(1, "%s called\n", __func__);
949
950 if (!priv->firm) {
951 rc = xc4000_fwupload(fe);
952 if (rc < 0)
953 return rc;
954 }
955
956#ifdef DJH_DEBUG
957 if (priv->ctrl.mts && !(type & FM))
958 type |= MTS;
959#endif
960
961retry:
962 new_fw.type = type;
963 new_fw.id = std;
964 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300965 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300966 new_fw.scode_nr = 0;
967 new_fw.int_freq = int_freq;
968
969 dprintk(1, "checking firmware, user requested type=");
970 if (debug) {
971 dump_firm_type(new_fw.type);
972 printk("(%x), id %016llx, ", new_fw.type,
973 (unsigned long long)new_fw.std_req);
974 if (!int_freq) {
975 printk("scode_tbl ");
976#ifdef DJH_DEBUG
977 dump_firm_type(priv->ctrl.scode_table);
978 printk("(%x), ", priv->ctrl.scode_table);
979#endif
980 } else
981 printk("int_freq %d, ", new_fw.int_freq);
982 printk("scode_nr %d\n", new_fw.scode_nr);
983 }
984
985 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300986 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300987 dprintk(1, "BASE firmware not changed.\n");
988 goto skip_base;
989 }
990
991 /* Updating BASE - forget about all currently loaded firmware */
992 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
993
994 /* Reset is needed before loading firmware */
995 rc = xc4000_TunerReset(fe);
996 if (rc < 0)
997 goto fail;
998
999 /* BASE firmwares are all std0 */
1000 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -03001001 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001002 if (rc < 0) {
1003 printk("Error %d while loading base firmware\n", rc);
1004 goto fail;
1005 }
1006
1007 /* Load INIT1, if needed */
1008 dprintk(1, "Load init1 firmware, if exists\n");
1009
Istvan Varga595a83f2011-06-04 11:59:54 -03001010 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001011 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -03001012 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001013 if (rc < 0 && rc != -ENOENT) {
1014 tuner_err("Error %d while loading init1 firmware\n",
1015 rc);
1016 goto fail;
1017 }
1018
1019skip_base:
1020 /*
1021 * No need to reload standard specific firmware if base firmware
1022 * was not reloaded and requested video standards have not changed.
1023 */
1024 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1025 priv->cur_fw.std_req == std) {
1026 dprintk(1, "Std-specific firmware already loaded.\n");
1027 goto skip_std_specific;
1028 }
1029
1030 /* Reloading std-specific firmware forces a SCODE update */
1031 priv->cur_fw.scode_table = 0;
1032
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001033 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001034 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001035
1036 if (rc < 0)
1037 goto fail;
1038
1039skip_std_specific:
1040 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1041 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1042 dprintk(1, "SCODE firmware already loaded.\n");
1043 goto check_device;
1044 }
1045
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001046 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001047 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1048 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001049 if (rc != XC_RESULT_SUCCESS)
1050 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001051
1052check_device:
1053 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1054
Devin Heitmueller799ed112009-10-04 23:09:18 -03001055 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001056 &fw_minor) != XC_RESULT_SUCCESS) {
1057 printk("Unable to read tuner registers.\n");
1058 goto fail;
1059 }
1060
1061 dprintk(1, "Device is Xceive %d version %d.%d, "
1062 "firmware version %d.%d\n",
1063 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1064
1065 /* Check firmware version against what we downloaded. */
1066#ifdef DJH_DEBUG
1067 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1068 printk("Incorrect readback of firmware version %x.\n",
1069 (version & 0xff));
1070 goto fail;
1071 }
1072#endif
1073
1074 /* Check that the tuner hardware model remains consistent over time. */
Istvan Varga7db98fe2011-06-04 12:25:19 -03001075 if (priv->hwmodel == 0 &&
1076 (hwmodel == XC_PRODUCT_ID_XC4000 ||
1077 hwmodel == XC_PRODUCT_ID_XC4100)) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001078 priv->hwmodel = hwmodel;
1079 priv->hwvers = version & 0xff00;
1080 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1081 priv->hwvers != (version & 0xff00)) {
1082 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001083 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001084 goto fail;
1085 }
1086
1087 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1088
1089 /*
1090 * By setting BASE in cur_fw.type only after successfully loading all
1091 * firmwares, we can:
1092 * 1. Identify that BASE firmware with type=0 has been loaded;
1093 * 2. Tell whether BASE firmware was just changed the next time through.
1094 */
1095 priv->cur_fw.type |= BASE;
1096
1097 return 0;
1098
1099fail:
1100 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1101 if (!is_retry) {
1102 msleep(50);
1103 is_retry = 1;
1104 dprintk(1, "Retrying firmware load\n");
1105 goto retry;
1106 }
1107
1108 if (rc == -ENOENT)
1109 rc = -EINVAL;
1110 return rc;
1111}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001112
Davide Ferri8d009a02009-06-23 22:34:06 -03001113static void xc_debug_dump(struct xc4000_priv *priv)
1114{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001115 u16 adc_envelope;
1116 u32 freq_error_hz = 0;
1117 u16 lock_status;
1118 u32 hsync_freq_hz = 0;
1119 u16 frame_lines;
1120 u16 quality;
1121 u8 hw_majorversion = 0, hw_minorversion = 0;
1122 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001123
Istvan Vargafbe4a292011-06-03 10:11:48 -03001124 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001125 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1126
1127 xc_get_frequency_error(priv, &freq_error_hz);
1128 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1129
Istvan Vargafbe4a292011-06-03 10:11:48 -03001130 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001131 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1132 lock_status);
1133
Istvan Vargafbe4a292011-06-03 10:11:48 -03001134 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1135 &fw_majorversion, &fw_minorversion);
Davide Ferri8d009a02009-06-23 22:34:06 -03001136 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1137 hw_majorversion, hw_minorversion,
1138 fw_majorversion, fw_minorversion);
1139
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001140 if (priv->video_standard < XC4000_DTV6) {
1141 xc_get_hsync_freq(priv, &hsync_freq_hz);
1142 dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
1143 hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001144
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001145 xc_get_frame_lines(priv, &frame_lines);
1146 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1147 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001148
Istvan Vargafbe4a292011-06-03 10:11:48 -03001149 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001150 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1151}
1152
1153static int xc4000_set_params(struct dvb_frontend *fe,
1154 struct dvb_frontend_parameters *params)
1155{
1156 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001157 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001158 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001159
Davide Ferri8d009a02009-06-23 22:34:06 -03001160 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1161
Istvan Varga56149422011-06-03 12:23:33 -03001162 mutex_lock(&priv->lock);
1163
Davide Ferri8d009a02009-06-23 22:34:06 -03001164 if (fe->ops.info.type == FE_ATSC) {
1165 dprintk(1, "%s() ATSC\n", __func__);
1166 switch (params->u.vsb.modulation) {
1167 case VSB_8:
1168 case VSB_16:
1169 dprintk(1, "%s() VSB modulation\n", __func__);
1170 priv->rf_mode = XC_RF_MODE_AIR;
1171 priv->freq_hz = params->frequency - 1750000;
1172 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001173 priv->video_standard = XC4000_DTV6;
1174 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001175 break;
1176 case QAM_64:
1177 case QAM_256:
1178 case QAM_AUTO:
1179 dprintk(1, "%s() QAM modulation\n", __func__);
1180 priv->rf_mode = XC_RF_MODE_CABLE;
1181 priv->freq_hz = params->frequency - 1750000;
1182 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001183 priv->video_standard = XC4000_DTV6;
1184 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001185 break;
1186 default:
Istvan Varga56149422011-06-03 12:23:33 -03001187 ret = -EINVAL;
1188 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001189 }
1190 } else if (fe->ops.info.type == FE_OFDM) {
1191 dprintk(1, "%s() OFDM\n", __func__);
1192 switch (params->u.ofdm.bandwidth) {
1193 case BANDWIDTH_6_MHZ:
1194 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001195 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001196 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001197 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001198 break;
1199 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001200 priv->bandwidth = BANDWIDTH_7_MHZ;
1201 priv->video_standard = XC4000_DTV7;
1202 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001203 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001204 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001205 case BANDWIDTH_8_MHZ:
1206 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001207 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001208 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001209 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001210 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001211 case BANDWIDTH_AUTO:
1212 if (params->frequency < 400000000) {
1213 priv->bandwidth = BANDWIDTH_7_MHZ;
1214 priv->freq_hz = params->frequency - 2250000;
1215 } else {
1216 priv->bandwidth = BANDWIDTH_8_MHZ;
1217 priv->freq_hz = params->frequency - 2750000;
1218 }
1219 priv->video_standard = XC4000_DTV7_8;
1220 type = DTV78;
1221 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001222 default:
1223 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001224 ret = -EINVAL;
1225 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001226 }
1227 priv->rf_mode = XC_RF_MODE_AIR;
1228 } else {
1229 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001230 ret = -EINVAL;
1231 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001232 }
1233
1234 dprintk(1, "%s() frequency=%d (compensated)\n",
1235 __func__, priv->freq_hz);
1236
Devin Heitmuellered23db32009-10-05 01:27:14 -03001237 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001238 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1239 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001240
Davide Ferri8d009a02009-06-23 22:34:06 -03001241 ret = xc_SetSignalSource(priv, priv->rf_mode);
1242 if (ret != XC_RESULT_SUCCESS) {
1243 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001244 "xc4000: xc_SetSignalSource(%d) failed\n",
1245 priv->rf_mode);
1246 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001247 } else {
1248 u16 video_mode, audio_mode;
1249 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1250 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1251 if (type == DTV6 && priv->firm_version != 0x0102)
1252 video_mode |= 0x0001;
1253 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1254 if (ret != XC_RESULT_SUCCESS) {
1255 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1256 /* DJH - do not return when it fails... */
1257 /* goto fail; */
1258 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001259 }
1260
Istvan Varga30f544e2011-06-04 12:12:42 -03001261 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1262 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1263 ret = 0;
1264 if (xc_write_reg(priv, XREG_AMPLITUDE,
1265 (priv->firm_version == 0x0102 ? 132 : 134))
1266 != 0)
1267 ret = -EREMOTEIO;
1268 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1269 ret = -EREMOTEIO;
1270 if (ret != 0) {
1271 printk(KERN_ERR "xc4000: setting registers failed\n");
1272 /* goto fail; */
1273 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001274 }
Istvan Varga30f544e2011-06-04 12:12:42 -03001275
Istvan Vargae75873c2011-06-04 12:18:41 -03001276 xc_tune_channel(priv, priv->freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001277
Istvan Varga56149422011-06-03 12:23:33 -03001278 ret = 0;
1279
1280fail:
1281 mutex_unlock(&priv->lock);
1282
1283 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001284}
1285
Davide Ferri8d009a02009-06-23 22:34:06 -03001286static int xc4000_set_analog_params(struct dvb_frontend *fe,
1287 struct analog_parameters *params)
1288{
1289 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga818a1772011-06-04 12:17:22 -03001290 unsigned int type = 0;
Istvan Varga56149422011-06-03 12:23:33 -03001291 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001292
Istvan Varga818a1772011-06-04 12:17:22 -03001293 if (params->mode == V4L2_TUNER_RADIO) {
1294 dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
1295 __func__, params->frequency);
1296
1297 mutex_lock(&priv->lock);
1298
1299 params->std = 0;
1300 priv->freq_hz = params->frequency * 125L / 2;
1301
1302 if (audio_std & XC4000_AUDIO_STD_INPUT1) {
1303 priv->video_standard = XC4000_FM_Radio_INPUT1;
1304 type = FM | INPUT1;
1305 } else {
1306 priv->video_standard = XC4000_FM_Radio_INPUT2;
1307 type = FM | INPUT2;
1308 }
1309
1310 goto tune_channel;
1311 }
1312
Davide Ferri8d009a02009-06-23 22:34:06 -03001313 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1314 __func__, params->frequency);
1315
Istvan Varga56149422011-06-03 12:23:33 -03001316 mutex_lock(&priv->lock);
1317
Davide Ferri8d009a02009-06-23 22:34:06 -03001318 /* params->frequency is in units of 62.5khz */
1319 priv->freq_hz = params->frequency * 62500;
1320
Istvan Varga818a1772011-06-04 12:17:22 -03001321 params->std &= V4L2_STD_ALL;
1322 /* if std is not defined, choose one */
1323 if (!params->std)
1324 params->std = V4L2_STD_PAL_BG;
1325
1326 if (audio_std & XC4000_AUDIO_STD_MONO)
1327 type = MONO;
1328
Davide Ferri8d009a02009-06-23 22:34:06 -03001329 if (params->std & V4L2_STD_MN) {
Istvan Varga818a1772011-06-04 12:17:22 -03001330 params->std = V4L2_STD_MN;
1331 if (audio_std & XC4000_AUDIO_STD_MONO) {
1332 priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
1333 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1334 params->std |= V4L2_STD_A2;
1335 priv->video_standard = XC4000_MN_NTSC_PAL_A2;
1336 } else {
1337 params->std |= V4L2_STD_BTSC;
1338 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
1339 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001340 goto tune_channel;
1341 }
1342
1343 if (params->std & V4L2_STD_PAL_BG) {
Istvan Varga818a1772011-06-04 12:17:22 -03001344 params->std = V4L2_STD_PAL_BG;
1345 if (audio_std & XC4000_AUDIO_STD_MONO) {
1346 priv->video_standard = XC4000_BG_PAL_MONO;
1347 } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
1348 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1349 params->std |= V4L2_STD_NICAM_A;
1350 priv->video_standard = XC4000_BG_PAL_NICAM;
1351 } else {
1352 params->std |= V4L2_STD_NICAM_B;
1353 priv->video_standard = XC4000_BG_PAL_NICAM;
1354 }
1355 } else {
1356 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1357 params->std |= V4L2_STD_A2_A;
1358 priv->video_standard = XC4000_BG_PAL_A2;
1359 } else {
1360 params->std |= V4L2_STD_A2_B;
1361 priv->video_standard = XC4000_BG_PAL_A2;
1362 }
1363 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001364 goto tune_channel;
1365 }
1366
1367 if (params->std & V4L2_STD_PAL_I) {
1368 /* default to NICAM audio standard */
Istvan Varga818a1772011-06-04 12:17:22 -03001369 params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
1370 if (audio_std & XC4000_AUDIO_STD_MONO) {
1371 priv->video_standard = XC4000_I_PAL_NICAM_MONO;
1372 } else {
1373 priv->video_standard = XC4000_I_PAL_NICAM;
1374 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001375 goto tune_channel;
1376 }
1377
1378 if (params->std & V4L2_STD_PAL_DK) {
Istvan Varga818a1772011-06-04 12:17:22 -03001379 params->std = V4L2_STD_PAL_DK;
1380 if (audio_std & XC4000_AUDIO_STD_MONO) {
1381 priv->video_standard = XC4000_DK_PAL_MONO;
1382 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1383 params->std |= V4L2_STD_A2;
1384 priv->video_standard = XC4000_DK_PAL_A2;
1385 } else {
1386 params->std |= V4L2_STD_NICAM;
1387 priv->video_standard = XC4000_DK_PAL_NICAM;
1388 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001389 goto tune_channel;
1390 }
1391
1392 if (params->std & V4L2_STD_SECAM_DK) {
Istvan Varga818a1772011-06-04 12:17:22 -03001393 /* default to A2 audio standard */
1394 params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
1395 if (audio_std & XC4000_AUDIO_STD_L) {
1396 type = 0;
1397 priv->video_standard = XC4000_DK_SECAM_NICAM;
1398 } else if (audio_std & XC4000_AUDIO_STD_MONO) {
1399 priv->video_standard = XC4000_DK_SECAM_A2MONO;
1400 } else if (audio_std & XC4000_AUDIO_STD_K3) {
1401 params->std |= V4L2_STD_SECAM_K3;
1402 priv->video_standard = XC4000_DK_SECAM_A2LDK3;
1403 } else {
1404 priv->video_standard = XC4000_DK_SECAM_A2DK1;
1405 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001406 goto tune_channel;
1407 }
1408
1409 if (params->std & V4L2_STD_SECAM_L) {
Istvan Varga818a1772011-06-04 12:17:22 -03001410 /* default to NICAM audio standard */
1411 type = 0;
1412 params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001413 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001414 goto tune_channel;
1415 }
1416
1417 if (params->std & V4L2_STD_SECAM_LC) {
Istvan Varga818a1772011-06-04 12:17:22 -03001418 /* default to NICAM audio standard */
1419 type = 0;
1420 params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001421 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001422 goto tune_channel;
1423 }
1424
1425tune_channel:
Istvan Varga818a1772011-06-04 12:17:22 -03001426 /* Fix me: it could be air. */
1427 priv->rf_mode = XC_RF_MODE_CABLE;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001428
Istvan Varga818a1772011-06-04 12:17:22 -03001429 if (check_firmware(fe, type, params->std,
1430 XC4000_Standard[priv->video_standard].int_freq)
1431 != XC_RESULT_SUCCESS) {
Istvan Varga56149422011-06-03 12:23:33 -03001432 goto fail;
Istvan Varga818a1772011-06-04 12:17:22 -03001433 }
Devin Heitmuellered23db32009-10-05 01:27:14 -03001434
Davide Ferri8d009a02009-06-23 22:34:06 -03001435 ret = xc_SetSignalSource(priv, priv->rf_mode);
1436 if (ret != XC_RESULT_SUCCESS) {
1437 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001438 "xc4000: xc_SetSignalSource(%d) failed\n",
1439 priv->rf_mode);
1440 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001441 } else {
1442 u16 video_mode, audio_mode;
1443 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1444 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1445 if (priv->video_standard < XC4000_BG_PAL_A2) {
1446 if (0 /*type & NOGD*/)
1447 video_mode &= 0xFF7F;
1448 } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
1449 if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
1450 priv->firm_version == 0x0102)
1451 video_mode &= 0xFEFF;
Istvan Varga923137a2011-06-04 12:15:51 -03001452 if (audio_std & XC4000_AUDIO_STD_B)
1453 video_mode |= 0x0080;
Istvan Varga30f544e2011-06-04 12:12:42 -03001454 }
1455 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1456 if (ret != XC_RESULT_SUCCESS) {
1457 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1458 goto fail;
1459 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001460 }
1461
Istvan Varga30f544e2011-06-04 12:12:42 -03001462 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1463 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1464 ret = 0;
1465 if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
1466 ret = -EREMOTEIO;
1467 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1468 ret = -EREMOTEIO;
1469 if (ret != 0) {
1470 printk(KERN_ERR "xc4000: setting registers failed\n");
1471 goto fail;
1472 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001473 }
1474
Istvan Vargae75873c2011-06-04 12:18:41 -03001475 xc_tune_channel(priv, priv->freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001476
Istvan Varga56149422011-06-03 12:23:33 -03001477 ret = 0;
1478
1479fail:
1480 mutex_unlock(&priv->lock);
1481
1482 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001483}
1484
1485static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1486{
1487 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001488
Davide Ferri8d009a02009-06-23 22:34:06 -03001489 *freq = priv->freq_hz;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001490
1491 if (debug) {
1492 mutex_lock(&priv->lock);
1493 if ((priv->cur_fw.type
1494 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1495 u16 snr = 0;
1496 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1497 mutex_unlock(&priv->lock);
1498 dprintk(1, "%s() freq = %u, SNR = %d\n",
1499 __func__, *freq, snr);
1500 return 0;
1501 }
1502 }
1503 mutex_unlock(&priv->lock);
1504 }
1505
1506 dprintk(1, "%s()\n", __func__);
1507
Davide Ferri8d009a02009-06-23 22:34:06 -03001508 return 0;
1509}
1510
1511static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1512{
1513 struct xc4000_priv *priv = fe->tuner_priv;
1514 dprintk(1, "%s()\n", __func__);
1515
1516 *bw = priv->bandwidth;
1517 return 0;
1518}
1519
1520static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1521{
1522 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001523 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001524
Istvan Varga56149422011-06-03 12:23:33 -03001525 mutex_lock(&priv->lock);
1526
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001527 if (priv->cur_fw.type & BASE)
1528 xc_get_lock_status(priv, &lock_status);
1529
1530 *status = (lock_status == 1 ?
1531 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1532 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1533 *status &= (~TUNER_STATUS_STEREO);
Davide Ferri8d009a02009-06-23 22:34:06 -03001534
Istvan Varga56149422011-06-03 12:23:33 -03001535 mutex_unlock(&priv->lock);
1536
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001537 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001538
1539 return 0;
1540}
1541
Davide Ferri8d009a02009-06-23 22:34:06 -03001542static int xc4000_sleep(struct dvb_frontend *fe)
1543{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001544 struct xc4000_priv *priv = fe->tuner_priv;
1545 int ret = XC_RESULT_SUCCESS;
1546
1547 dprintk(1, "%s()\n", __func__);
1548
1549 mutex_lock(&priv->lock);
1550
1551 /* Avoid firmware reload on slow devices */
1552 if ((no_poweroff == 2 ||
1553 (no_poweroff == 0 &&
1554 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1555 (priv->cur_fw.type & BASE) != 0) {
1556 /* force reset and firmware reload */
1557 priv->cur_fw.type = XC_POWERED_DOWN;
1558
1559 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1560 != XC_RESULT_SUCCESS) {
1561 printk(KERN_ERR
1562 "xc4000: %s() unable to shutdown tuner\n",
1563 __func__);
1564 ret = -EREMOTEIO;
1565 }
1566 xc_wait(20);
1567 }
1568
1569 mutex_unlock(&priv->lock);
1570
1571 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001572}
1573
1574static int xc4000_init(struct dvb_frontend *fe)
1575{
Davide Ferri8d009a02009-06-23 22:34:06 -03001576 dprintk(1, "%s()\n", __func__);
1577
Davide Ferri8d009a02009-06-23 22:34:06 -03001578 return 0;
1579}
1580
1581static int xc4000_release(struct dvb_frontend *fe)
1582{
1583 struct xc4000_priv *priv = fe->tuner_priv;
1584
1585 dprintk(1, "%s()\n", __func__);
1586
1587 mutex_lock(&xc4000_list_mutex);
1588
1589 if (priv)
1590 hybrid_tuner_release_state(priv);
1591
1592 mutex_unlock(&xc4000_list_mutex);
1593
1594 fe->tuner_priv = NULL;
1595
1596 return 0;
1597}
1598
1599static const struct dvb_tuner_ops xc4000_tuner_ops = {
1600 .info = {
1601 .name = "Xceive XC4000",
1602 .frequency_min = 1000000,
1603 .frequency_max = 1023000000,
1604 .frequency_step = 50000,
1605 },
1606
1607 .release = xc4000_release,
1608 .init = xc4000_init,
1609 .sleep = xc4000_sleep,
1610
1611 .set_params = xc4000_set_params,
1612 .set_analog_params = xc4000_set_analog_params,
1613 .get_frequency = xc4000_get_frequency,
1614 .get_bandwidth = xc4000_get_bandwidth,
1615 .get_status = xc4000_get_status
1616};
1617
1618struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1619 struct i2c_adapter *i2c,
1620 struct xc4000_config *cfg)
1621{
1622 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001623 int instance;
1624 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001625
Istvan Varga0b402132011-06-03 09:38:04 -03001626 if (cfg->card_type != XC4000_CARD_GENERIC) {
1627 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1628 cfg->i2c_address = 0x61;
1629 cfg->if_khz = 4560;
1630 } else { /* default to PCTV 340E */
1631 cfg->i2c_address = 0x61;
1632 cfg->if_khz = 5400;
1633 }
1634 }
1635
Davide Ferri8d009a02009-06-23 22:34:06 -03001636 dprintk(1, "%s(%d-%04x)\n", __func__,
1637 i2c ? i2c_adapter_id(i2c) : -1,
1638 cfg ? cfg->i2c_address : -1);
1639
1640 mutex_lock(&xc4000_list_mutex);
1641
1642 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1643 hybrid_tuner_instance_list,
1644 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001645 if (cfg->card_type != XC4000_CARD_GENERIC)
1646 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001647 switch (instance) {
1648 case 0:
1649 goto fail;
1650 break;
1651 case 1:
1652 /* new tuner instance */
1653 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001654 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001655 fe->tuner_priv = priv;
1656 break;
1657 default:
1658 /* existing tuner instance */
1659 fe->tuner_priv = priv;
1660 break;
1661 }
1662
Istvan Varga0b402132011-06-03 09:38:04 -03001663 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001664 /* If the IF hasn't been set yet, use the value provided by
1665 the caller (occurs in hybrid devices where the analog
1666 call to xc4000_attach occurs before the digital side) */
1667 priv->if_khz = cfg->if_khz;
1668 }
1669
1670 /* Check if firmware has been loaded. It is possible that another
1671 instance of the driver has loaded the firmware.
1672 */
1673
Istvan Varga027fd362011-06-04 12:04:51 -03001674 if (instance == 1) {
1675 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1676 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001677 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001678 } else {
1679 id = ((priv->cur_fw.type & BASE) != 0 ?
1680 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1681 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001682
1683 switch (id) {
Istvan Varga7db98fe2011-06-04 12:25:19 -03001684 case XC_PRODUCT_ID_XC4000:
1685 case XC_PRODUCT_ID_XC4100:
Davide Ferri8d009a02009-06-23 22:34:06 -03001686 printk(KERN_INFO
1687 "xc4000: Successfully identified at address 0x%02x\n",
1688 cfg->i2c_address);
1689 printk(KERN_INFO
1690 "xc4000: Firmware has been loaded previously\n");
1691 break;
1692 case XC_PRODUCT_ID_FW_NOT_LOADED:
1693 printk(KERN_INFO
1694 "xc4000: Successfully identified at address 0x%02x\n",
1695 cfg->i2c_address);
1696 printk(KERN_INFO
1697 "xc4000: Firmware has not been loaded previously\n");
1698 break;
1699 default:
1700 printk(KERN_ERR
1701 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1702 cfg->i2c_address, id);
1703 goto fail;
1704 }
1705
1706 mutex_unlock(&xc4000_list_mutex);
1707
1708 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1709 sizeof(struct dvb_tuner_ops));
1710
Istvan Varga027fd362011-06-04 12:04:51 -03001711 if (instance == 1) {
1712 int ret;
1713 mutex_lock(&priv->lock);
1714 ret = xc4000_fwupload(fe);
1715 mutex_unlock(&priv->lock);
1716 if (ret != XC_RESULT_SUCCESS)
1717 goto fail2;
1718 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001719
Davide Ferri8d009a02009-06-23 22:34:06 -03001720 return fe;
1721fail:
1722 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001723fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001724 xc4000_release(fe);
1725 return NULL;
1726}
1727EXPORT_SYMBOL(xc4000_attach);
1728
1729MODULE_AUTHOR("Steven Toth, Davide Ferri");
1730MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1731MODULE_LICENSE("GPL");