blob: 0afb61f8eae55441b7669eeffc7cb6fb9af2105c [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);
42MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
43
44static int no_poweroff;
45module_param(no_poweroff, int, 0644);
46MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
47 "\t\t1 keep device energized and with tuner ready all the times.\n"
48 "\t\tFaster, but consumes more power and keeps the device hotter");
49
Istvan Vargafa285bc2011-06-04 11:48:16 -030050#define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
51
52static char firmware_name[30];
53module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
54MODULE_PARM_DESC(firmware_name, "\n\t\tFirmware file name. Allows overriding "
55 "the default firmware\n"
56 "\t\tname.");
57
Davide Ferri8d009a02009-06-23 22:34:06 -030058static DEFINE_MUTEX(xc4000_list_mutex);
59static LIST_HEAD(hybrid_tuner_instance_list);
60
61#define dprintk(level, fmt, arg...) if (debug >= level) \
62 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
63
Devin Heitmueller11091a32009-07-20 00:54:57 -030064/* struct for storing firmware table */
65struct firmware_description {
66 unsigned int type;
67 v4l2_std_id id;
68 __u16 int_freq;
69 unsigned char *ptr;
70 unsigned int size;
71};
72
73struct firmware_properties {
74 unsigned int type;
75 v4l2_std_id id;
76 v4l2_std_id std_req;
77 __u16 int_freq;
78 unsigned int scode_table;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -030079 int scode_nr;
Devin Heitmueller11091a32009-07-20 00:54:57 -030080};
Davide Ferri8d009a02009-06-23 22:34:06 -030081
82struct xc4000_priv {
83 struct tuner_i2c_props i2c_props;
84 struct list_head hybrid_tuner_instance_list;
Devin Heitmueller11091a32009-07-20 00:54:57 -030085 struct firmware_description *firm;
Istvan Vargafbe4a292011-06-03 10:11:48 -030086 int firm_size;
87 __u16 firm_version;
88 u32 if_khz;
89 u32 freq_hz;
90 u32 bandwidth;
91 u8 video_standard;
92 u8 rf_mode;
Istvan Varga0b402132011-06-03 09:38:04 -030093 u8 card_type;
Istvan Vargafbe4a292011-06-03 10:11:48 -030094 u8 ignore_i2c_write_errors;
95 /* struct xc2028_ctrl ctrl; */
Devin Heitmuellerd0962382009-07-25 17:39:54 -030096 struct firmware_properties cur_fw;
Istvan Vargafbe4a292011-06-03 10:11:48 -030097 __u16 hwmodel;
98 __u16 hwvers;
Istvan Varga56149422011-06-03 12:23:33 -030099 struct mutex lock;
Davide Ferri8d009a02009-06-23 22:34:06 -0300100};
101
102/* Misc Defines */
Istvan Varga49110852011-06-03 10:55:24 -0300103#define MAX_TV_STANDARD 24
Davide Ferri8d009a02009-06-23 22:34:06 -0300104#define XC_MAX_I2C_WRITE_LENGTH 64
105
106/* Signal Types */
107#define XC_RF_MODE_AIR 0
108#define XC_RF_MODE_CABLE 1
109
110/* Result codes */
111#define XC_RESULT_SUCCESS 0
112#define XC_RESULT_RESET_FAILURE 1
113#define XC_RESULT_I2C_WRITE_FAILURE 2
114#define XC_RESULT_I2C_READ_FAILURE 3
115#define XC_RESULT_OUT_OF_RANGE 5
116
117/* Product id */
118#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300119#define XC_PRODUCT_ID_FW_LOADED 0x0FA0
Davide Ferri8d009a02009-06-23 22:34:06 -0300120
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300121/* Registers (Write-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300122#define XREG_INIT 0x00
123#define XREG_VIDEO_MODE 0x01
124#define XREG_AUDIO_MODE 0x02
125#define XREG_RF_FREQ 0x03
126#define XREG_D_CODE 0x04
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300127#define XREG_DIRECTSITTING_MODE 0x05
128#define XREG_SEEK_MODE 0x06
129#define XREG_POWER_DOWN 0x08
130#define XREG_SIGNALSOURCE 0x0A
131#define XREG_AMPLITUDE 0x10
Davide Ferri8d009a02009-06-23 22:34:06 -0300132
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300133/* Registers (Read-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300134#define XREG_ADC_ENV 0x00
135#define XREG_QUALITY 0x01
136#define XREG_FRAME_LINES 0x02
137#define XREG_HSYNC_FREQ 0x03
138#define XREG_LOCK 0x04
139#define XREG_FREQ_ERROR 0x05
140#define XREG_SNR 0x06
141#define XREG_VERSION 0x07
142#define XREG_PRODUCT_ID 0x08
Davide Ferri8d009a02009-06-23 22:34:06 -0300143
144/*
145 Basic firmware description. This will remain with
146 the driver for documentation purposes.
147
148 This represents an I2C firmware file encoded as a
149 string of unsigned char. Format is as follows:
150
151 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
152 char[1 ]=len0_LSB -> length of first write transaction
153 char[2 ]=data0 -> first byte to be sent
154 char[3 ]=data1
155 char[4 ]=data2
156 char[ ]=...
157 char[M ]=dataN -> last byte to be sent
158 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
159 char[M+2]=len1_LSB -> length of second write transaction
160 char[M+3]=data0
161 char[M+4]=data1
162 ...
163 etc.
164
165 The [len] value should be interpreted as follows:
166
167 len= len_MSB _ len_LSB
168 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
169 len=0000_0000_0000_0000 : Reset command: Do hardware reset
170 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
171 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
172
173 For the RESET and WAIT commands, the two following bytes will contain
174 immediately the length of the following transaction.
Davide Ferri8d009a02009-06-23 22:34:06 -0300175*/
Istvan Vargafbe4a292011-06-03 10:11:48 -0300176
Davide Ferri8d009a02009-06-23 22:34:06 -0300177struct XC_TV_STANDARD {
Istvan Vargafbe4a292011-06-03 10:11:48 -0300178 const char *Name;
179 u16 AudioMode;
180 u16 VideoMode;
Istvan Varga49110852011-06-03 10:55:24 -0300181 u16 int_freq;
Davide Ferri8d009a02009-06-23 22:34:06 -0300182};
183
184/* Tuner standards */
Devin Heitmuellered23db32009-10-05 01:27:14 -0300185#define XC4000_MN_NTSC_PAL_BTSC 0
186#define XC4000_MN_NTSC_PAL_A2 1
187#define XC4000_MN_NTSC_PAL_EIAJ 2
188#define XC4000_MN_NTSC_PAL_Mono 3
189#define XC4000_BG_PAL_A2 4
190#define XC4000_BG_PAL_NICAM 5
191#define XC4000_BG_PAL_MONO 6
192#define XC4000_I_PAL_NICAM 7
193#define XC4000_I_PAL_NICAM_MONO 8
194#define XC4000_DK_PAL_A2 9
195#define XC4000_DK_PAL_NICAM 10
196#define XC4000_DK_PAL_MONO 11
197#define XC4000_DK_SECAM_A2DK1 12
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300198#define XC4000_DK_SECAM_A2LDK3 13
199#define XC4000_DK_SECAM_A2MONO 14
Istvan Varga49110852011-06-03 10:55:24 -0300200#define XC4000_DK_SECAM_NICAM 15
201#define XC4000_L_SECAM_NICAM 16
202#define XC4000_LC_SECAM_NICAM 17
203#define XC4000_DTV6 18
204#define XC4000_DTV8 19
205#define XC4000_DTV7_8 20
206#define XC4000_DTV7 21
207#define XC4000_FM_Radio_INPUT2 22
208#define XC4000_FM_Radio_INPUT1 23
Davide Ferri8d009a02009-06-23 22:34:06 -0300209
Davide Ferri8d009a02009-06-23 22:34:06 -0300210static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
Istvan Varga49110852011-06-03 10:55:24 -0300211 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
212 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
213 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
214 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
215 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
216 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
217 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
218 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
219 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
220 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
221 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
222 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
223 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
224 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
225 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
226 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
227 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
228 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
229 {"DTV6", 0x00C0, 0x8002, 0},
230 {"DTV8", 0x00C0, 0x800B, 0},
231 {"DTV7/8", 0x00C0, 0x801B, 0},
232 {"DTV7", 0x00C0, 0x8007, 0},
233 {"FM Radio-INPUT2", 0x0008, 0x9800,10700},
234 {"FM Radio-INPUT1", 0x0008, 0x9000,10700}
Davide Ferri8d009a02009-06-23 22:34:06 -0300235};
236
Davide Ferri8d009a02009-06-23 22:34:06 -0300237static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
238static int xc4000_TunerReset(struct dvb_frontend *fe);
239
240static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
241{
242 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
243 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300244 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300245 if (priv->ignore_i2c_write_errors == 0) {
246 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
247 len);
248 if (len == 4) {
249 printk("bytes %02x %02x %02x %02x\n", buf[0],
250 buf[1], buf[2], buf[3]);
251 }
252 return XC_RESULT_I2C_WRITE_FAILURE;
253 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300254 }
255 return XC_RESULT_SUCCESS;
256}
257
Davide Ferri8d009a02009-06-23 22:34:06 -0300258static void xc_wait(int wait_ms)
259{
260 msleep(wait_ms);
261}
262
263static int xc4000_TunerReset(struct dvb_frontend *fe)
264{
265 struct xc4000_priv *priv = fe->tuner_priv;
266 int ret;
267
268 dprintk(1, "%s()\n", __func__);
269
270 if (fe->callback) {
271 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
272 fe->dvb->priv :
273 priv->i2c_props.adap->algo_data,
274 DVB_FRONTEND_COMPONENT_TUNER,
275 XC4000_TUNER_RESET, 0);
276 if (ret) {
277 printk(KERN_ERR "xc4000: reset failed\n");
278 return XC_RESULT_RESET_FAILURE;
279 }
280 } else {
281 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
282 return XC_RESULT_RESET_FAILURE;
283 }
284 return XC_RESULT_SUCCESS;
285}
286
287static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
288{
289 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300290 int result;
291
292 buf[0] = (regAddr >> 8) & 0xFF;
293 buf[1] = regAddr & 0xFF;
294 buf[2] = (i2cData >> 8) & 0xFF;
295 buf[3] = i2cData & 0xFF;
296 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300297
298 return result;
299}
300
301static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
302{
303 struct xc4000_priv *priv = fe->tuner_priv;
304
305 int i, nbytes_to_send, result;
306 unsigned int len, pos, index;
307 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
308
309 index = 0;
310 while ((i2c_sequence[index] != 0xFF) ||
311 (i2c_sequence[index + 1] != 0xFF)) {
312 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
313 if (len == 0x0000) {
314 /* RESET command */
315 result = xc4000_TunerReset(fe);
316 index += 2;
317 if (result != XC_RESULT_SUCCESS)
318 return result;
319 } else if (len & 0x8000) {
320 /* WAIT command */
321 xc_wait(len & 0x7FFF);
322 index += 2;
323 } else {
324 /* Send i2c data whilst ensuring individual transactions
325 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
326 */
327 index += 2;
328 buf[0] = i2c_sequence[index];
329 buf[1] = i2c_sequence[index + 1];
330 pos = 2;
331 while (pos < len) {
332 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
333 nbytes_to_send =
334 XC_MAX_I2C_WRITE_LENGTH;
335 else
336 nbytes_to_send = (len - pos + 2);
337 for (i = 2; i < nbytes_to_send; i++) {
338 buf[i] = i2c_sequence[index + pos +
339 i - 2];
340 }
341 result = xc_send_i2c_data(priv, buf,
342 nbytes_to_send);
343
344 if (result != XC_RESULT_SUCCESS)
345 return result;
346
347 pos += nbytes_to_send - 2;
348 }
349 index += len;
350 }
351 }
352 return XC_RESULT_SUCCESS;
353}
354
Davide Ferri8d009a02009-06-23 22:34:06 -0300355static int xc_SetTVStandard(struct xc4000_priv *priv,
356 u16 VideoMode, u16 AudioMode)
357{
358 int ret;
359 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
360 dprintk(1, "%s() Standard = %s\n",
361 __func__,
362 XC4000_Standard[priv->video_standard].Name);
363
Devin Heitmueller799ed112009-10-04 23:09:18 -0300364 /* Don't complain when the request fails because of i2c stretching */
365 priv->ignore_i2c_write_errors = 1;
366
Davide Ferri8d009a02009-06-23 22:34:06 -0300367 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
368 if (ret == XC_RESULT_SUCCESS)
369 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
370
Devin Heitmueller799ed112009-10-04 23:09:18 -0300371 priv->ignore_i2c_write_errors = 0;
372
Davide Ferri8d009a02009-06-23 22:34:06 -0300373 return ret;
374}
375
376static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
377{
378 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
379 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
380
381 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
382 rf_mode = XC_RF_MODE_CABLE;
383 printk(KERN_ERR
384 "%s(), Invalid mode, defaulting to CABLE",
385 __func__);
386 }
387 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
388}
389
390static const struct dvb_tuner_ops xc4000_tuner_ops;
391
392static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
393{
394 u16 freq_code;
395
396 dprintk(1, "%s(%u)\n", __func__, freq_hz);
397
398 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
399 (freq_hz < xc4000_tuner_ops.info.frequency_min))
400 return XC_RESULT_OUT_OF_RANGE;
401
402 freq_code = (u16)(freq_hz / 15625);
403
404 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
405 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
406 only be used for fast scanning for channel lock) */
407 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
408}
409
Davide Ferri8d009a02009-06-23 22:34:06 -0300410static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
411{
412 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
413}
414
415static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
416{
417 int result;
418 u16 regData;
419 u32 tmp;
420
421 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
422 if (result != XC_RESULT_SUCCESS)
423 return result;
424
Istvan Varga1368ceb2011-06-03 12:27:30 -0300425 tmp = (u32)regData & 0xFFFFU;
426 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
427 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300428 return result;
429}
430
431static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
432{
433 return xc4000_readreg(priv, XREG_LOCK, lock_status);
434}
435
436static int xc_get_version(struct xc4000_priv *priv,
437 u8 *hw_majorversion, u8 *hw_minorversion,
438 u8 *fw_majorversion, u8 *fw_minorversion)
439{
440 u16 data;
441 int result;
442
443 result = xc4000_readreg(priv, XREG_VERSION, &data);
444 if (result != XC_RESULT_SUCCESS)
445 return result;
446
447 (*hw_majorversion) = (data >> 12) & 0x0F;
448 (*hw_minorversion) = (data >> 8) & 0x0F;
449 (*fw_majorversion) = (data >> 4) & 0x0F;
450 (*fw_minorversion) = data & 0x0F;
451
452 return 0;
453}
454
Davide Ferri8d009a02009-06-23 22:34:06 -0300455static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
456{
457 u16 regData;
458 int result;
459
460 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
461 if (result != XC_RESULT_SUCCESS)
462 return result;
463
464 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
465 return result;
466}
467
468static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
469{
470 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
471}
472
473static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
474{
475 return xc4000_readreg(priv, XREG_QUALITY, quality);
476}
477
478static u16 WaitForLock(struct xc4000_priv *priv)
479{
480 u16 lockState = 0;
481 int watchDogCount = 40;
482
483 while ((lockState == 0) && (watchDogCount > 0)) {
484 xc_get_lock_status(priv, &lockState);
485 if (lockState != 1) {
486 xc_wait(5);
487 watchDogCount--;
488 }
489 }
490 return lockState;
491}
492
493#define XC_TUNE_ANALOG 0
494#define XC_TUNE_DIGITAL 1
495static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
496{
Istvan Vargafbe4a292011-06-03 10:11:48 -0300497 int found = 0;
498 int result = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300499
500 dprintk(1, "%s(%u)\n", __func__, freq_hz);
501
Devin Heitmueller799ed112009-10-04 23:09:18 -0300502 /* Don't complain when the request fails because of i2c stretching */
503 priv->ignore_i2c_write_errors = 1;
504 result = xc_set_RF_frequency(priv, freq_hz);
505 priv->ignore_i2c_write_errors = 0;
506
507 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300508 return 0;
509
510 if (mode == XC_TUNE_ANALOG) {
511 if (WaitForLock(priv) == 1)
512 found = 1;
513 }
514
515 return found;
516}
517
518static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
519{
520 u8 buf[2] = { reg >> 8, reg & 0xff };
521 u8 bval[2] = { 0, 0 };
522 struct i2c_msg msg[2] = {
523 { .addr = priv->i2c_props.addr,
524 .flags = 0, .buf = &buf[0], .len = 2 },
525 { .addr = priv->i2c_props.addr,
526 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
527 };
528
529 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
530 printk(KERN_WARNING "xc4000: I2C read failed\n");
531 return -EREMOTEIO;
532 }
533
534 *val = (bval[0] << 8) | bval[1];
535 return XC_RESULT_SUCCESS;
536}
537
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300538#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300539static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
540{
541 if (type & BASE)
542 printk("BASE ");
543 if (type & INIT1)
544 printk("INIT1 ");
545 if (type & F8MHZ)
546 printk("F8MHZ ");
547 if (type & MTS)
548 printk("MTS ");
549 if (type & D2620)
550 printk("D2620 ");
551 if (type & D2633)
552 printk("D2633 ");
553 if (type & DTV6)
554 printk("DTV6 ");
555 if (type & QAM)
556 printk("QAM ");
557 if (type & DTV7)
558 printk("DTV7 ");
559 if (type & DTV78)
560 printk("DTV78 ");
561 if (type & DTV8)
562 printk("DTV8 ");
563 if (type & FM)
564 printk("FM ");
565 if (type & INPUT1)
566 printk("INPUT1 ");
567 if (type & LCD)
568 printk("LCD ");
569 if (type & NOGD)
570 printk("NOGD ");
571 if (type & MONO)
572 printk("MONO ");
573 if (type & ATSC)
574 printk("ATSC ");
575 if (type & IF)
576 printk("IF ");
577 if (type & LG60)
578 printk("LG60 ");
579 if (type & ATI638)
580 printk("ATI638 ");
581 if (type & OREN538)
582 printk("OREN538 ");
583 if (type & OREN36)
584 printk("OREN36 ");
585 if (type & TOYOTA388)
586 printk("TOYOTA388 ");
587 if (type & TOYOTA794)
588 printk("TOYOTA794 ");
589 if (type & DIBCOM52)
590 printk("DIBCOM52 ");
591 if (type & ZARLINK456)
592 printk("ZARLINK456 ");
593 if (type & CHINA)
594 printk("CHINA ");
595 if (type & F6MHZ)
596 printk("F6MHZ ");
597 if (type & INPUT2)
598 printk("INPUT2 ");
599 if (type & SCODE)
600 printk("SCODE ");
601 if (type & HAS_IF)
602 printk("HAS_IF_%d ", int_freq);
603}
604
Devin Heitmueller11091a32009-07-20 00:54:57 -0300605static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
606 v4l2_std_id *id)
607{
608 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300609 int i, best_i = -1;
610 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300611
Devin Heitmueller11091a32009-07-20 00:54:57 -0300612 if (!priv->firm) {
613 printk("Error! firmware not loaded\n");
614 return -EINVAL;
615 }
616
617 if (((type & ~SCODE) == 0) && (*id == 0))
618 *id = V4L2_STD_PAL;
619
Devin Heitmueller11091a32009-07-20 00:54:57 -0300620 /* Seek for generic video standard match */
621 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300622 v4l2_std_id id_diff_mask =
623 (priv->firm[i].id ^ (*id)) & (*id);
624 unsigned int type_diff_mask =
625 (priv->firm[i].type ^ type)
626 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
627 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300628
Istvan Varga3db95702011-06-04 11:52:34 -0300629 if (type_diff_mask
630 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300631 continue;
632
Istvan Varga3db95702011-06-04 11:52:34 -0300633 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
634 if (!nr_diffs) /* Supports all the requested standards */
635 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300636
Istvan Varga3db95702011-06-04 11:52:34 -0300637 if (nr_diffs < best_nr_diffs) {
638 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300639 best_i = i;
640 }
641 }
642
Istvan Varga3db95702011-06-04 11:52:34 -0300643 /* FIXME: Would make sense to seek for type "hint" match ? */
644 if (best_i < 0) {
645 i = -ENOENT;
646 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300647 }
648
Istvan Varga3db95702011-06-04 11:52:34 -0300649 if (best_nr_diffs > 0U) {
650 printk("Selecting best matching firmware (%u bits differ) for "
651 "type=", best_nr_diffs);
652 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
653 i = best_i;
654 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300655
656found:
657 *id = priv->firm[i].id;
658
659ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300660 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300661 printk("%s firmware for type=", (i < 0) ? "Can't find" :
662 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300663 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300664 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
665 }
666 return i;
667}
668
669static int load_firmware(struct dvb_frontend *fe, unsigned int type,
670 v4l2_std_id *id)
671{
672 struct xc4000_priv *priv = fe->tuner_priv;
673 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300674 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300675
Devin Heitmueller11091a32009-07-20 00:54:57 -0300676 pos = seek_firmware(fe, type, id);
677 if (pos < 0)
678 return pos;
679
Devin Heitmueller11091a32009-07-20 00:54:57 -0300680 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300681
Devin Heitmueller799ed112009-10-04 23:09:18 -0300682 /* Don't complain when the request fails because of i2c stretching */
683 priv->ignore_i2c_write_errors = 1;
684
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300685 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300686
Devin Heitmueller799ed112009-10-04 23:09:18 -0300687 priv->ignore_i2c_write_errors = 0;
688
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300689 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300690}
691
Davide Ferri8d009a02009-06-23 22:34:06 -0300692static int xc4000_fwupload(struct dvb_frontend *fe)
693{
694 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300695 const struct firmware *fw = NULL;
696 const unsigned char *p, *endp;
697 int rc = 0;
698 int n, n_array;
699 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300700 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300701
Istvan Vargafa285bc2011-06-04 11:48:16 -0300702 if (firmware_name[0] != '\0')
703 fname = firmware_name;
704 else
705 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300706
707 printk("Reading firmware %s\n", fname);
708 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
709 if (rc < 0) {
710 if (rc == -ENOENT)
711 printk("Error: firmware %s not found.\n",
712 fname);
713 else
714 printk("Error %d while requesting firmware %s \n",
715 rc, fname);
716
717 return rc;
718 }
719 p = fw->data;
720 endp = p + fw->size;
721
722 if (fw->size < sizeof(name) - 1 + 2 + 2) {
723 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300724 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300725 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300726 }
727
Devin Heitmueller11091a32009-07-20 00:54:57 -0300728 memcpy(name, p, sizeof(name) - 1);
729 name[sizeof(name) - 1] = 0;
730 p += sizeof(name) - 1;
731
732 priv->firm_version = get_unaligned_le16(p);
733 p += 2;
734
735 n_array = get_unaligned_le16(p);
736 p += 2;
737
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300738 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
739 n_array, fname, name,
740 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300741
742 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
743 if (priv->firm == NULL) {
744 printk("Not enough memory to load firmware file.\n");
745 rc = -ENOMEM;
746 goto err;
747 }
748 priv->firm_size = n_array;
749
750 n = -1;
751 while (p < endp) {
752 __u32 type, size;
753 v4l2_std_id id;
754 __u16 int_freq = 0;
755
756 n++;
757 if (n >= n_array) {
758 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300759 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300760 goto corrupt;
761 }
762
763 /* Checks if there's enough bytes to read */
764 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
765 goto header;
766
767 type = get_unaligned_le32(p);
768 p += sizeof(type);
769
770 id = get_unaligned_le64(p);
771 p += sizeof(id);
772
773 if (type & HAS_IF) {
774 int_freq = get_unaligned_le16(p);
775 p += sizeof(int_freq);
776 if (endp - p < sizeof(size))
777 goto header;
778 }
779
780 size = get_unaligned_le32(p);
781 p += sizeof(size);
782
783 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300784 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300785 "(size=%d, expected %d)\n",
786 type, (unsigned long long)id,
787 (unsigned)(endp - p), size);
788 goto corrupt;
789 }
790
791 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
792 if (priv->firm[n].ptr == NULL) {
793 printk("Not enough memory to load firmware file.\n");
794 rc = -ENOMEM;
795 goto err;
796 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300797
Devin Heitmueller11091a32009-07-20 00:54:57 -0300798 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300799 printk("Reading firmware type ");
800 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300801 printk("(%x), id %llx, size=%d.\n",
802 type, (unsigned long long)id, size);
803 }
804
805 memcpy(priv->firm[n].ptr, p, size);
806 priv->firm[n].type = type;
807 priv->firm[n].id = id;
808 priv->firm[n].size = size;
809 priv->firm[n].int_freq = int_freq;
810
811 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300812 }
813
Devin Heitmueller11091a32009-07-20 00:54:57 -0300814 if (n + 1 != priv->firm_size) {
815 printk("Firmware file is incomplete!\n");
816 goto corrupt;
817 }
818
819 goto done;
820
821header:
822 printk("Firmware header is incomplete!\n");
823corrupt:
824 rc = -EINVAL;
825 printk("Error: firmware file is corrupted!\n");
826
827err:
828 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300829
830done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300831 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300832 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300833 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300834
835 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300836}
837
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300838static int load_scode(struct dvb_frontend *fe, unsigned int type,
839 v4l2_std_id *id, __u16 int_freq, int scode)
840{
841 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300842 int pos, rc;
843 unsigned char *p;
844 u8 scode_buf[13];
845 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300846
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300847 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300848
849 if (!int_freq) {
850 pos = seek_firmware(fe, type, id);
851 if (pos < 0)
852 return pos;
853 } else {
854 for (pos = 0; pos < priv->firm_size; pos++) {
855 if ((priv->firm[pos].int_freq == int_freq) &&
856 (priv->firm[pos].type & HAS_IF))
857 break;
858 }
859 if (pos == priv->firm_size)
860 return -ENOENT;
861 }
862
863 p = priv->firm[pos].ptr;
864
Istvan Vargaffce6262011-06-04 11:56:18 -0300865 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
866 return -EINVAL;
867 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300868
869 tuner_info("Loading SCODE for type=");
870 dump_firm_type_and_int_freq(priv->firm[pos].type,
871 priv->firm[pos].int_freq);
872 printk("(%x), id %016llx.\n", priv->firm[pos].type,
873 (unsigned long long)*id);
874
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300875 scode_buf[0] = 0x00;
876 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300877
878 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300879 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
880 if (rc < 0) {
881 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300882 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300883 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300884
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300885 rc = xc_send_i2c_data(priv, scode_buf, 13);
886 if (rc != XC_RESULT_SUCCESS) {
887 /* Even if the send failed, make sure we set back to indirect
888 mode */
889 printk("Failed to set scode %d\n", rc);
890 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300891
892 /* Switch back to indirect-mode */
893 memset(indirect_mode, 0, sizeof(indirect_mode));
894 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300895 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
896 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300897
898 return 0;
899}
900
901static int check_firmware(struct dvb_frontend *fe, unsigned int type,
902 v4l2_std_id std, __u16 int_freq)
903{
904 struct xc4000_priv *priv = fe->tuner_priv;
905 struct firmware_properties new_fw;
906 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300907 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300908 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300909 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300910
911 dprintk(1, "%s called\n", __func__);
912
913 if (!priv->firm) {
914 rc = xc4000_fwupload(fe);
915 if (rc < 0)
916 return rc;
917 }
918
919#ifdef DJH_DEBUG
920 if (priv->ctrl.mts && !(type & FM))
921 type |= MTS;
922#endif
923
924retry:
925 new_fw.type = type;
926 new_fw.id = std;
927 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300928 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300929 new_fw.scode_nr = 0;
930 new_fw.int_freq = int_freq;
931
932 dprintk(1, "checking firmware, user requested type=");
933 if (debug) {
934 dump_firm_type(new_fw.type);
935 printk("(%x), id %016llx, ", new_fw.type,
936 (unsigned long long)new_fw.std_req);
937 if (!int_freq) {
938 printk("scode_tbl ");
939#ifdef DJH_DEBUG
940 dump_firm_type(priv->ctrl.scode_table);
941 printk("(%x), ", priv->ctrl.scode_table);
942#endif
943 } else
944 printk("int_freq %d, ", new_fw.int_freq);
945 printk("scode_nr %d\n", new_fw.scode_nr);
946 }
947
948 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300949 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300950 dprintk(1, "BASE firmware not changed.\n");
951 goto skip_base;
952 }
953
954 /* Updating BASE - forget about all currently loaded firmware */
955 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
956
957 /* Reset is needed before loading firmware */
958 rc = xc4000_TunerReset(fe);
959 if (rc < 0)
960 goto fail;
961
962 /* BASE firmwares are all std0 */
963 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300964 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300965 if (rc < 0) {
966 printk("Error %d while loading base firmware\n", rc);
967 goto fail;
968 }
969
970 /* Load INIT1, if needed */
971 dprintk(1, "Load init1 firmware, if exists\n");
972
Istvan Varga595a83f2011-06-04 11:59:54 -0300973 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300974 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -0300975 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300976 if (rc < 0 && rc != -ENOENT) {
977 tuner_err("Error %d while loading init1 firmware\n",
978 rc);
979 goto fail;
980 }
981
982skip_base:
983 /*
984 * No need to reload standard specific firmware if base firmware
985 * was not reloaded and requested video standards have not changed.
986 */
987 if (priv->cur_fw.type == (BASE | new_fw.type) &&
988 priv->cur_fw.std_req == std) {
989 dprintk(1, "Std-specific firmware already loaded.\n");
990 goto skip_std_specific;
991 }
992
993 /* Reloading std-specific firmware forces a SCODE update */
994 priv->cur_fw.scode_table = 0;
995
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300996 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300997 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300998
999 if (rc < 0)
1000 goto fail;
1001
1002skip_std_specific:
1003 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1004 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1005 dprintk(1, "SCODE firmware already loaded.\n");
1006 goto check_device;
1007 }
1008
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001009 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001010 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1011 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001012 if (rc != XC_RESULT_SUCCESS)
1013 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001014
1015check_device:
1016 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1017
Devin Heitmueller799ed112009-10-04 23:09:18 -03001018 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001019 &fw_minor) != XC_RESULT_SUCCESS) {
1020 printk("Unable to read tuner registers.\n");
1021 goto fail;
1022 }
1023
1024 dprintk(1, "Device is Xceive %d version %d.%d, "
1025 "firmware version %d.%d\n",
1026 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1027
1028 /* Check firmware version against what we downloaded. */
1029#ifdef DJH_DEBUG
1030 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1031 printk("Incorrect readback of firmware version %x.\n",
1032 (version & 0xff));
1033 goto fail;
1034 }
1035#endif
1036
1037 /* Check that the tuner hardware model remains consistent over time. */
1038 if (priv->hwmodel == 0 && hwmodel == 4000) {
1039 priv->hwmodel = hwmodel;
1040 priv->hwvers = version & 0xff00;
1041 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1042 priv->hwvers != (version & 0xff00)) {
1043 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001044 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001045 goto fail;
1046 }
1047
1048 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1049
1050 /*
1051 * By setting BASE in cur_fw.type only after successfully loading all
1052 * firmwares, we can:
1053 * 1. Identify that BASE firmware with type=0 has been loaded;
1054 * 2. Tell whether BASE firmware was just changed the next time through.
1055 */
1056 priv->cur_fw.type |= BASE;
1057
1058 return 0;
1059
1060fail:
1061 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1062 if (!is_retry) {
1063 msleep(50);
1064 is_retry = 1;
1065 dprintk(1, "Retrying firmware load\n");
1066 goto retry;
1067 }
1068
1069 if (rc == -ENOENT)
1070 rc = -EINVAL;
1071 return rc;
1072}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001073
Davide Ferri8d009a02009-06-23 22:34:06 -03001074static void xc_debug_dump(struct xc4000_priv *priv)
1075{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001076 u16 adc_envelope;
1077 u32 freq_error_hz = 0;
1078 u16 lock_status;
1079 u32 hsync_freq_hz = 0;
1080 u16 frame_lines;
1081 u16 quality;
1082 u8 hw_majorversion = 0, hw_minorversion = 0;
1083 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001084
1085 /* Wait for stats to stabilize.
1086 * Frame Lines needs two frame times after initial lock
1087 * before it is valid.
1088 */
1089 xc_wait(100);
1090
Istvan Vargafbe4a292011-06-03 10:11:48 -03001091 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001092 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1093
1094 xc_get_frequency_error(priv, &freq_error_hz);
1095 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1096
Istvan Vargafbe4a292011-06-03 10:11:48 -03001097 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001098 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1099 lock_status);
1100
Istvan Vargafbe4a292011-06-03 10:11:48 -03001101 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1102 &fw_majorversion, &fw_minorversion);
1103
Davide Ferri8d009a02009-06-23 22:34:06 -03001104 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1105 hw_majorversion, hw_minorversion,
1106 fw_majorversion, fw_minorversion);
1107
Istvan Vargafbe4a292011-06-03 10:11:48 -03001108 xc_get_hsync_freq(priv, &hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001109 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
1110
Istvan Vargafbe4a292011-06-03 10:11:48 -03001111 xc_get_frame_lines(priv, &frame_lines);
Davide Ferri8d009a02009-06-23 22:34:06 -03001112 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1113
Istvan Vargafbe4a292011-06-03 10:11:48 -03001114 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001115 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1116}
1117
1118static int xc4000_set_params(struct dvb_frontend *fe,
1119 struct dvb_frontend_parameters *params)
1120{
1121 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001122 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001123 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001124
Davide Ferri8d009a02009-06-23 22:34:06 -03001125 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1126
Istvan Varga56149422011-06-03 12:23:33 -03001127 mutex_lock(&priv->lock);
1128
Davide Ferri8d009a02009-06-23 22:34:06 -03001129 if (fe->ops.info.type == FE_ATSC) {
1130 dprintk(1, "%s() ATSC\n", __func__);
1131 switch (params->u.vsb.modulation) {
1132 case VSB_8:
1133 case VSB_16:
1134 dprintk(1, "%s() VSB modulation\n", __func__);
1135 priv->rf_mode = XC_RF_MODE_AIR;
1136 priv->freq_hz = params->frequency - 1750000;
1137 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001138 priv->video_standard = XC4000_DTV6;
1139 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001140 break;
1141 case QAM_64:
1142 case QAM_256:
1143 case QAM_AUTO:
1144 dprintk(1, "%s() QAM modulation\n", __func__);
1145 priv->rf_mode = XC_RF_MODE_CABLE;
1146 priv->freq_hz = params->frequency - 1750000;
1147 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001148 priv->video_standard = XC4000_DTV6;
1149 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001150 break;
1151 default:
Istvan Varga56149422011-06-03 12:23:33 -03001152 ret = -EINVAL;
1153 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001154 }
1155 } else if (fe->ops.info.type == FE_OFDM) {
1156 dprintk(1, "%s() OFDM\n", __func__);
1157 switch (params->u.ofdm.bandwidth) {
1158 case BANDWIDTH_6_MHZ:
1159 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001160 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001161 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001162 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001163 break;
1164 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001165 priv->bandwidth = BANDWIDTH_7_MHZ;
1166 priv->video_standard = XC4000_DTV7;
1167 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001168 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001169 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001170 case BANDWIDTH_8_MHZ:
1171 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001172 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001173 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001174 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001175 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001176 case BANDWIDTH_AUTO:
1177 if (params->frequency < 400000000) {
1178 priv->bandwidth = BANDWIDTH_7_MHZ;
1179 priv->freq_hz = params->frequency - 2250000;
1180 } else {
1181 priv->bandwidth = BANDWIDTH_8_MHZ;
1182 priv->freq_hz = params->frequency - 2750000;
1183 }
1184 priv->video_standard = XC4000_DTV7_8;
1185 type = DTV78;
1186 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001187 default:
1188 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001189 ret = -EINVAL;
1190 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001191 }
1192 priv->rf_mode = XC_RF_MODE_AIR;
1193 } else {
1194 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001195 ret = -EINVAL;
1196 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001197 }
1198
1199 dprintk(1, "%s() frequency=%d (compensated)\n",
1200 __func__, priv->freq_hz);
1201
Devin Heitmuellered23db32009-10-05 01:27:14 -03001202 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001203 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1204 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001205
Davide Ferri8d009a02009-06-23 22:34:06 -03001206 ret = xc_SetSignalSource(priv, priv->rf_mode);
1207 if (ret != XC_RESULT_SUCCESS) {
1208 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001209 "xc4000: xc_SetSignalSource(%d) failed\n",
1210 priv->rf_mode);
1211 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001212 }
1213
1214 ret = xc_SetTVStandard(priv,
1215 XC4000_Standard[priv->video_standard].VideoMode,
1216 XC4000_Standard[priv->video_standard].AudioMode);
1217 if (ret != XC_RESULT_SUCCESS) {
1218 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
Istvan Varga56149422011-06-03 12:23:33 -03001219 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001220 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001221 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
1222
1223 if (debug)
1224 xc_debug_dump(priv);
1225
Istvan Varga56149422011-06-03 12:23:33 -03001226 ret = 0;
1227
1228fail:
1229 mutex_unlock(&priv->lock);
1230
1231 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001232}
1233
Davide Ferri8d009a02009-06-23 22:34:06 -03001234static int xc4000_set_analog_params(struct dvb_frontend *fe,
1235 struct analog_parameters *params)
1236{
1237 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga56149422011-06-03 12:23:33 -03001238 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001239
Davide Ferri8d009a02009-06-23 22:34:06 -03001240 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1241 __func__, params->frequency);
1242
Istvan Varga56149422011-06-03 12:23:33 -03001243 mutex_lock(&priv->lock);
1244
Davide Ferri8d009a02009-06-23 22:34:06 -03001245 /* Fix me: it could be air. */
1246 priv->rf_mode = params->mode;
1247 if (params->mode > XC_RF_MODE_CABLE)
1248 priv->rf_mode = XC_RF_MODE_CABLE;
1249
1250 /* params->frequency is in units of 62.5khz */
1251 priv->freq_hz = params->frequency * 62500;
1252
1253 /* FIX ME: Some video standards may have several possible audio
1254 standards. We simply default to one of them here.
1255 */
1256 if (params->std & V4L2_STD_MN) {
1257 /* default to BTSC audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001258 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
Davide Ferri8d009a02009-06-23 22:34:06 -03001259 goto tune_channel;
1260 }
1261
1262 if (params->std & V4L2_STD_PAL_BG) {
1263 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001264 priv->video_standard = XC4000_BG_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001265 goto tune_channel;
1266 }
1267
1268 if (params->std & V4L2_STD_PAL_I) {
1269 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001270 priv->video_standard = XC4000_I_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001271 goto tune_channel;
1272 }
1273
1274 if (params->std & V4L2_STD_PAL_DK) {
1275 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001276 priv->video_standard = XC4000_DK_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001277 goto tune_channel;
1278 }
1279
1280 if (params->std & V4L2_STD_SECAM_DK) {
1281 /* default to A2 DK1 audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001282 priv->video_standard = XC4000_DK_SECAM_A2DK1;
Davide Ferri8d009a02009-06-23 22:34:06 -03001283 goto tune_channel;
1284 }
1285
1286 if (params->std & V4L2_STD_SECAM_L) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001287 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001288 goto tune_channel;
1289 }
1290
1291 if (params->std & V4L2_STD_SECAM_LC) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001292 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001293 goto tune_channel;
1294 }
1295
1296tune_channel:
Devin Heitmuellered23db32009-10-05 01:27:14 -03001297
1298 /* FIXME - firmware type not being set properly */
Istvan Varga56149422011-06-03 12:23:33 -03001299 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1300 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001301
Davide Ferri8d009a02009-06-23 22:34:06 -03001302 ret = xc_SetSignalSource(priv, priv->rf_mode);
1303 if (ret != XC_RESULT_SUCCESS) {
1304 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001305 "xc4000: xc_SetSignalSource(%d) failed\n",
1306 priv->rf_mode);
1307 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001308 }
1309
1310 ret = xc_SetTVStandard(priv,
1311 XC4000_Standard[priv->video_standard].VideoMode,
1312 XC4000_Standard[priv->video_standard].AudioMode);
1313 if (ret != XC_RESULT_SUCCESS) {
1314 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
Istvan Varga56149422011-06-03 12:23:33 -03001315 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001316 }
1317
1318 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
1319
1320 if (debug)
1321 xc_debug_dump(priv);
1322
Istvan Varga56149422011-06-03 12:23:33 -03001323 ret = 0;
1324
1325fail:
1326 mutex_unlock(&priv->lock);
1327
1328 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001329}
1330
1331static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1332{
1333 struct xc4000_priv *priv = fe->tuner_priv;
1334 dprintk(1, "%s()\n", __func__);
1335 *freq = priv->freq_hz;
1336 return 0;
1337}
1338
1339static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1340{
1341 struct xc4000_priv *priv = fe->tuner_priv;
1342 dprintk(1, "%s()\n", __func__);
1343
1344 *bw = priv->bandwidth;
1345 return 0;
1346}
1347
1348static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1349{
1350 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001351 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001352
Istvan Varga56149422011-06-03 12:23:33 -03001353 mutex_lock(&priv->lock);
1354
Davide Ferri8d009a02009-06-23 22:34:06 -03001355 xc_get_lock_status(priv, &lock_status);
1356
Istvan Varga56149422011-06-03 12:23:33 -03001357 mutex_unlock(&priv->lock);
1358
Davide Ferri8d009a02009-06-23 22:34:06 -03001359 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
1360
1361 *status = lock_status;
1362
1363 return 0;
1364}
1365
Davide Ferri8d009a02009-06-23 22:34:06 -03001366static int xc4000_sleep(struct dvb_frontend *fe)
1367{
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001368 /* FIXME: djh disable this for now... */
1369 return XC_RESULT_SUCCESS;
Davide Ferri8d009a02009-06-23 22:34:06 -03001370}
1371
1372static int xc4000_init(struct dvb_frontend *fe)
1373{
1374 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga56149422011-06-03 12:23:33 -03001375 int ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001376 dprintk(1, "%s()\n", __func__);
1377
Istvan Varga56149422011-06-03 12:23:33 -03001378 mutex_lock(&priv->lock);
1379 ret = check_firmware(fe, DTV8, 0, priv->if_khz);
1380 mutex_unlock(&priv->lock);
1381 if (ret != XC_RESULT_SUCCESS) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001382 printk(KERN_ERR "xc4000: Unable to initialise tuner\n");
1383 return -EREMOTEIO;
1384 }
1385
1386 if (debug)
1387 xc_debug_dump(priv);
1388
1389 return 0;
1390}
1391
1392static int xc4000_release(struct dvb_frontend *fe)
1393{
1394 struct xc4000_priv *priv = fe->tuner_priv;
1395
1396 dprintk(1, "%s()\n", __func__);
1397
1398 mutex_lock(&xc4000_list_mutex);
1399
1400 if (priv)
1401 hybrid_tuner_release_state(priv);
1402
1403 mutex_unlock(&xc4000_list_mutex);
1404
1405 fe->tuner_priv = NULL;
1406
1407 return 0;
1408}
1409
1410static const struct dvb_tuner_ops xc4000_tuner_ops = {
1411 .info = {
1412 .name = "Xceive XC4000",
1413 .frequency_min = 1000000,
1414 .frequency_max = 1023000000,
1415 .frequency_step = 50000,
1416 },
1417
1418 .release = xc4000_release,
1419 .init = xc4000_init,
1420 .sleep = xc4000_sleep,
1421
1422 .set_params = xc4000_set_params,
1423 .set_analog_params = xc4000_set_analog_params,
1424 .get_frequency = xc4000_get_frequency,
1425 .get_bandwidth = xc4000_get_bandwidth,
1426 .get_status = xc4000_get_status
1427};
1428
1429struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1430 struct i2c_adapter *i2c,
1431 struct xc4000_config *cfg)
1432{
1433 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001434 int instance;
1435 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001436
Istvan Varga0b402132011-06-03 09:38:04 -03001437 if (cfg->card_type != XC4000_CARD_GENERIC) {
1438 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1439 cfg->i2c_address = 0x61;
1440 cfg->if_khz = 4560;
1441 } else { /* default to PCTV 340E */
1442 cfg->i2c_address = 0x61;
1443 cfg->if_khz = 5400;
1444 }
1445 }
1446
Davide Ferri8d009a02009-06-23 22:34:06 -03001447 dprintk(1, "%s(%d-%04x)\n", __func__,
1448 i2c ? i2c_adapter_id(i2c) : -1,
1449 cfg ? cfg->i2c_address : -1);
1450
1451 mutex_lock(&xc4000_list_mutex);
1452
1453 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1454 hybrid_tuner_instance_list,
1455 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001456 if (cfg->card_type != XC4000_CARD_GENERIC)
1457 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001458 switch (instance) {
1459 case 0:
1460 goto fail;
1461 break;
1462 case 1:
1463 /* new tuner instance */
1464 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001465 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001466 fe->tuner_priv = priv;
1467 break;
1468 default:
1469 /* existing tuner instance */
1470 fe->tuner_priv = priv;
1471 break;
1472 }
1473
Istvan Varga0b402132011-06-03 09:38:04 -03001474 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001475 /* If the IF hasn't been set yet, use the value provided by
1476 the caller (occurs in hybrid devices where the analog
1477 call to xc4000_attach occurs before the digital side) */
1478 priv->if_khz = cfg->if_khz;
1479 }
1480
1481 /* Check if firmware has been loaded. It is possible that another
1482 instance of the driver has loaded the firmware.
1483 */
1484
1485 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
1486 goto fail;
1487
1488 switch (id) {
1489 case XC_PRODUCT_ID_FW_LOADED:
1490 printk(KERN_INFO
1491 "xc4000: Successfully identified at address 0x%02x\n",
1492 cfg->i2c_address);
1493 printk(KERN_INFO
1494 "xc4000: Firmware has been loaded previously\n");
1495 break;
1496 case XC_PRODUCT_ID_FW_NOT_LOADED:
1497 printk(KERN_INFO
1498 "xc4000: Successfully identified at address 0x%02x\n",
1499 cfg->i2c_address);
1500 printk(KERN_INFO
1501 "xc4000: Firmware has not been loaded previously\n");
1502 break;
1503 default:
1504 printk(KERN_ERR
1505 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1506 cfg->i2c_address, id);
1507 goto fail;
1508 }
1509
1510 mutex_unlock(&xc4000_list_mutex);
1511
1512 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1513 sizeof(struct dvb_tuner_ops));
1514
Devin Heitmueller11091a32009-07-20 00:54:57 -03001515 /* FIXME: For now, load the firmware at startup. We will remove this
1516 before the code goes to production... */
Istvan Varga56149422011-06-03 12:23:33 -03001517 mutex_lock(&priv->lock);
Devin Heitmuellerfe830362009-07-28 00:04:27 -03001518 check_firmware(fe, DTV8, 0, priv->if_khz);
Istvan Varga56149422011-06-03 12:23:33 -03001519 mutex_unlock(&priv->lock);
Devin Heitmueller11091a32009-07-20 00:54:57 -03001520
Davide Ferri8d009a02009-06-23 22:34:06 -03001521 return fe;
1522fail:
1523 mutex_unlock(&xc4000_list_mutex);
1524
1525 xc4000_release(fe);
1526 return NULL;
1527}
1528EXPORT_SYMBOL(xc4000_attach);
1529
1530MODULE_AUTHOR("Steven Toth, Davide Ferri");
1531MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1532MODULE_LICENSE("GPL");