blob: ec5f1f1b3f3cb8b157348d73e53a50b643fed53a [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);
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 Vargafa285bc2011-06-04 11:48:16 -030052#define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
53
54static char firmware_name[30];
55module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
56MODULE_PARM_DESC(firmware_name, "\n\t\tFirmware file name. Allows overriding "
57 "the default firmware\n"
58 "\t\tname.");
59
Davide Ferri8d009a02009-06-23 22:34:06 -030060static DEFINE_MUTEX(xc4000_list_mutex);
61static LIST_HEAD(hybrid_tuner_instance_list);
62
63#define dprintk(level, fmt, arg...) if (debug >= level) \
64 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
65
Devin Heitmueller11091a32009-07-20 00:54:57 -030066/* struct for storing firmware table */
67struct firmware_description {
68 unsigned int type;
69 v4l2_std_id id;
70 __u16 int_freq;
71 unsigned char *ptr;
72 unsigned int size;
73};
74
75struct firmware_properties {
76 unsigned int type;
77 v4l2_std_id id;
78 v4l2_std_id std_req;
79 __u16 int_freq;
80 unsigned int scode_table;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -030081 int scode_nr;
Devin Heitmueller11091a32009-07-20 00:54:57 -030082};
Davide Ferri8d009a02009-06-23 22:34:06 -030083
84struct xc4000_priv {
85 struct tuner_i2c_props i2c_props;
86 struct list_head hybrid_tuner_instance_list;
Devin Heitmueller11091a32009-07-20 00:54:57 -030087 struct firmware_description *firm;
Istvan Vargafbe4a292011-06-03 10:11:48 -030088 int firm_size;
89 __u16 firm_version;
90 u32 if_khz;
91 u32 freq_hz;
92 u32 bandwidth;
93 u8 video_standard;
94 u8 rf_mode;
Istvan Varga0b402132011-06-03 09:38:04 -030095 u8 card_type;
Istvan Vargafbe4a292011-06-03 10:11:48 -030096 u8 ignore_i2c_write_errors;
97 /* struct xc2028_ctrl ctrl; */
Devin Heitmuellerd0962382009-07-25 17:39:54 -030098 struct firmware_properties cur_fw;
Istvan Vargafbe4a292011-06-03 10:11:48 -030099 __u16 hwmodel;
100 __u16 hwvers;
Istvan Varga56149422011-06-03 12:23:33 -0300101 struct mutex lock;
Davide Ferri8d009a02009-06-23 22:34:06 -0300102};
103
104/* Misc Defines */
Istvan Varga49110852011-06-03 10:55:24 -0300105#define MAX_TV_STANDARD 24
Davide Ferri8d009a02009-06-23 22:34:06 -0300106#define XC_MAX_I2C_WRITE_LENGTH 64
Istvan Varga5272f6b2011-06-04 12:03:03 -0300107#define XC_POWERED_DOWN 0x80000000U
Davide Ferri8d009a02009-06-23 22:34:06 -0300108
109/* Signal Types */
110#define XC_RF_MODE_AIR 0
111#define XC_RF_MODE_CABLE 1
112
113/* Result codes */
114#define XC_RESULT_SUCCESS 0
115#define XC_RESULT_RESET_FAILURE 1
116#define XC_RESULT_I2C_WRITE_FAILURE 2
117#define XC_RESULT_I2C_READ_FAILURE 3
118#define XC_RESULT_OUT_OF_RANGE 5
119
120/* Product id */
121#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300122#define XC_PRODUCT_ID_FW_LOADED 0x0FA0
Davide Ferri8d009a02009-06-23 22:34:06 -0300123
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300124/* Registers (Write-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300125#define XREG_INIT 0x00
126#define XREG_VIDEO_MODE 0x01
127#define XREG_AUDIO_MODE 0x02
128#define XREG_RF_FREQ 0x03
129#define XREG_D_CODE 0x04
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300130#define XREG_DIRECTSITTING_MODE 0x05
131#define XREG_SEEK_MODE 0x06
132#define XREG_POWER_DOWN 0x08
133#define XREG_SIGNALSOURCE 0x0A
134#define XREG_AMPLITUDE 0x10
Davide Ferri8d009a02009-06-23 22:34:06 -0300135
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300136/* Registers (Read-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300137#define XREG_ADC_ENV 0x00
138#define XREG_QUALITY 0x01
139#define XREG_FRAME_LINES 0x02
140#define XREG_HSYNC_FREQ 0x03
141#define XREG_LOCK 0x04
142#define XREG_FREQ_ERROR 0x05
143#define XREG_SNR 0x06
144#define XREG_VERSION 0x07
145#define XREG_PRODUCT_ID 0x08
Davide Ferri8d009a02009-06-23 22:34:06 -0300146
147/*
148 Basic firmware description. This will remain with
149 the driver for documentation purposes.
150
151 This represents an I2C firmware file encoded as a
152 string of unsigned char. Format is as follows:
153
154 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
155 char[1 ]=len0_LSB -> length of first write transaction
156 char[2 ]=data0 -> first byte to be sent
157 char[3 ]=data1
158 char[4 ]=data2
159 char[ ]=...
160 char[M ]=dataN -> last byte to be sent
161 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
162 char[M+2]=len1_LSB -> length of second write transaction
163 char[M+3]=data0
164 char[M+4]=data1
165 ...
166 etc.
167
168 The [len] value should be interpreted as follows:
169
170 len= len_MSB _ len_LSB
171 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
172 len=0000_0000_0000_0000 : Reset command: Do hardware reset
173 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
174 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
175
176 For the RESET and WAIT commands, the two following bytes will contain
177 immediately the length of the following transaction.
Davide Ferri8d009a02009-06-23 22:34:06 -0300178*/
Istvan Vargafbe4a292011-06-03 10:11:48 -0300179
Davide Ferri8d009a02009-06-23 22:34:06 -0300180struct XC_TV_STANDARD {
Istvan Vargafbe4a292011-06-03 10:11:48 -0300181 const char *Name;
182 u16 AudioMode;
183 u16 VideoMode;
Istvan Varga49110852011-06-03 10:55:24 -0300184 u16 int_freq;
Davide Ferri8d009a02009-06-23 22:34:06 -0300185};
186
187/* Tuner standards */
Devin Heitmuellered23db32009-10-05 01:27:14 -0300188#define XC4000_MN_NTSC_PAL_BTSC 0
189#define XC4000_MN_NTSC_PAL_A2 1
190#define XC4000_MN_NTSC_PAL_EIAJ 2
191#define XC4000_MN_NTSC_PAL_Mono 3
192#define XC4000_BG_PAL_A2 4
193#define XC4000_BG_PAL_NICAM 5
194#define XC4000_BG_PAL_MONO 6
195#define XC4000_I_PAL_NICAM 7
196#define XC4000_I_PAL_NICAM_MONO 8
197#define XC4000_DK_PAL_A2 9
198#define XC4000_DK_PAL_NICAM 10
199#define XC4000_DK_PAL_MONO 11
200#define XC4000_DK_SECAM_A2DK1 12
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300201#define XC4000_DK_SECAM_A2LDK3 13
202#define XC4000_DK_SECAM_A2MONO 14
Istvan Varga49110852011-06-03 10:55:24 -0300203#define XC4000_DK_SECAM_NICAM 15
204#define XC4000_L_SECAM_NICAM 16
205#define XC4000_LC_SECAM_NICAM 17
206#define XC4000_DTV6 18
207#define XC4000_DTV8 19
208#define XC4000_DTV7_8 20
209#define XC4000_DTV7 21
210#define XC4000_FM_Radio_INPUT2 22
211#define XC4000_FM_Radio_INPUT1 23
Davide Ferri8d009a02009-06-23 22:34:06 -0300212
Davide Ferri8d009a02009-06-23 22:34:06 -0300213static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
Istvan Varga49110852011-06-03 10:55:24 -0300214 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
215 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
216 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
217 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
218 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
219 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
220 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
221 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
222 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
223 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
224 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
225 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
226 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
227 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
228 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
229 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
230 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
231 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
232 {"DTV6", 0x00C0, 0x8002, 0},
233 {"DTV8", 0x00C0, 0x800B, 0},
234 {"DTV7/8", 0x00C0, 0x801B, 0},
235 {"DTV7", 0x00C0, 0x8007, 0},
236 {"FM Radio-INPUT2", 0x0008, 0x9800,10700},
237 {"FM Radio-INPUT1", 0x0008, 0x9000,10700}
Davide Ferri8d009a02009-06-23 22:34:06 -0300238};
239
Davide Ferri8d009a02009-06-23 22:34:06 -0300240static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
241static int xc4000_TunerReset(struct dvb_frontend *fe);
242
243static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
244{
245 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
246 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300247 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300248 if (priv->ignore_i2c_write_errors == 0) {
249 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
250 len);
251 if (len == 4) {
252 printk("bytes %02x %02x %02x %02x\n", buf[0],
253 buf[1], buf[2], buf[3]);
254 }
255 return XC_RESULT_I2C_WRITE_FAILURE;
256 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300257 }
258 return XC_RESULT_SUCCESS;
259}
260
Davide Ferri8d009a02009-06-23 22:34:06 -0300261static void xc_wait(int wait_ms)
262{
263 msleep(wait_ms);
264}
265
266static int xc4000_TunerReset(struct dvb_frontend *fe)
267{
268 struct xc4000_priv *priv = fe->tuner_priv;
269 int ret;
270
271 dprintk(1, "%s()\n", __func__);
272
273 if (fe->callback) {
274 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
275 fe->dvb->priv :
276 priv->i2c_props.adap->algo_data,
277 DVB_FRONTEND_COMPONENT_TUNER,
278 XC4000_TUNER_RESET, 0);
279 if (ret) {
280 printk(KERN_ERR "xc4000: reset failed\n");
281 return XC_RESULT_RESET_FAILURE;
282 }
283 } else {
284 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
285 return XC_RESULT_RESET_FAILURE;
286 }
287 return XC_RESULT_SUCCESS;
288}
289
290static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
291{
292 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300293 int result;
294
295 buf[0] = (regAddr >> 8) & 0xFF;
296 buf[1] = regAddr & 0xFF;
297 buf[2] = (i2cData >> 8) & 0xFF;
298 buf[3] = i2cData & 0xFF;
299 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300300
301 return result;
302}
303
304static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
305{
306 struct xc4000_priv *priv = fe->tuner_priv;
307
308 int i, nbytes_to_send, result;
309 unsigned int len, pos, index;
310 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
311
312 index = 0;
313 while ((i2c_sequence[index] != 0xFF) ||
314 (i2c_sequence[index + 1] != 0xFF)) {
315 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
316 if (len == 0x0000) {
317 /* RESET command */
318 result = xc4000_TunerReset(fe);
319 index += 2;
320 if (result != XC_RESULT_SUCCESS)
321 return result;
322 } else if (len & 0x8000) {
323 /* WAIT command */
324 xc_wait(len & 0x7FFF);
325 index += 2;
326 } else {
327 /* Send i2c data whilst ensuring individual transactions
328 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
329 */
330 index += 2;
331 buf[0] = i2c_sequence[index];
332 buf[1] = i2c_sequence[index + 1];
333 pos = 2;
334 while (pos < len) {
335 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
336 nbytes_to_send =
337 XC_MAX_I2C_WRITE_LENGTH;
338 else
339 nbytes_to_send = (len - pos + 2);
340 for (i = 2; i < nbytes_to_send; i++) {
341 buf[i] = i2c_sequence[index + pos +
342 i - 2];
343 }
344 result = xc_send_i2c_data(priv, buf,
345 nbytes_to_send);
346
347 if (result != XC_RESULT_SUCCESS)
348 return result;
349
350 pos += nbytes_to_send - 2;
351 }
352 index += len;
353 }
354 }
355 return XC_RESULT_SUCCESS;
356}
357
Davide Ferri8d009a02009-06-23 22:34:06 -0300358static int xc_SetTVStandard(struct xc4000_priv *priv,
359 u16 VideoMode, u16 AudioMode)
360{
361 int ret;
362 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
363 dprintk(1, "%s() Standard = %s\n",
364 __func__,
365 XC4000_Standard[priv->video_standard].Name);
366
Devin Heitmueller799ed112009-10-04 23:09:18 -0300367 /* Don't complain when the request fails because of i2c stretching */
368 priv->ignore_i2c_write_errors = 1;
369
Davide Ferri8d009a02009-06-23 22:34:06 -0300370 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
371 if (ret == XC_RESULT_SUCCESS)
372 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
373
Devin Heitmueller799ed112009-10-04 23:09:18 -0300374 priv->ignore_i2c_write_errors = 0;
375
Davide Ferri8d009a02009-06-23 22:34:06 -0300376 return ret;
377}
378
379static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
380{
381 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
382 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
383
384 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
385 rf_mode = XC_RF_MODE_CABLE;
386 printk(KERN_ERR
387 "%s(), Invalid mode, defaulting to CABLE",
388 __func__);
389 }
390 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
391}
392
393static const struct dvb_tuner_ops xc4000_tuner_ops;
394
395static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
396{
397 u16 freq_code;
398
399 dprintk(1, "%s(%u)\n", __func__, freq_hz);
400
401 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
402 (freq_hz < xc4000_tuner_ops.info.frequency_min))
403 return XC_RESULT_OUT_OF_RANGE;
404
405 freq_code = (u16)(freq_hz / 15625);
406
407 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
408 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
409 only be used for fast scanning for channel lock) */
410 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
411}
412
Davide Ferri8d009a02009-06-23 22:34:06 -0300413static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
414{
415 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
416}
417
418static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
419{
420 int result;
421 u16 regData;
422 u32 tmp;
423
424 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
425 if (result != XC_RESULT_SUCCESS)
426 return result;
427
Istvan Varga1368ceb2011-06-03 12:27:30 -0300428 tmp = (u32)regData & 0xFFFFU;
429 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
430 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300431 return result;
432}
433
434static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
435{
436 return xc4000_readreg(priv, XREG_LOCK, lock_status);
437}
438
439static int xc_get_version(struct xc4000_priv *priv,
440 u8 *hw_majorversion, u8 *hw_minorversion,
441 u8 *fw_majorversion, u8 *fw_minorversion)
442{
443 u16 data;
444 int result;
445
446 result = xc4000_readreg(priv, XREG_VERSION, &data);
447 if (result != XC_RESULT_SUCCESS)
448 return result;
449
450 (*hw_majorversion) = (data >> 12) & 0x0F;
451 (*hw_minorversion) = (data >> 8) & 0x0F;
452 (*fw_majorversion) = (data >> 4) & 0x0F;
453 (*fw_minorversion) = data & 0x0F;
454
455 return 0;
456}
457
Davide Ferri8d009a02009-06-23 22:34:06 -0300458static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
459{
460 u16 regData;
461 int result;
462
463 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
464 if (result != XC_RESULT_SUCCESS)
465 return result;
466
467 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
468 return result;
469}
470
471static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
472{
473 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
474}
475
476static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
477{
478 return xc4000_readreg(priv, XREG_QUALITY, quality);
479}
480
481static u16 WaitForLock(struct xc4000_priv *priv)
482{
483 u16 lockState = 0;
484 int watchDogCount = 40;
485
486 while ((lockState == 0) && (watchDogCount > 0)) {
487 xc_get_lock_status(priv, &lockState);
488 if (lockState != 1) {
489 xc_wait(5);
490 watchDogCount--;
491 }
492 }
493 return lockState;
494}
495
496#define XC_TUNE_ANALOG 0
497#define XC_TUNE_DIGITAL 1
498static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
499{
Istvan Vargafbe4a292011-06-03 10:11:48 -0300500 int found = 0;
501 int result = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300502
503 dprintk(1, "%s(%u)\n", __func__, freq_hz);
504
Devin Heitmueller799ed112009-10-04 23:09:18 -0300505 /* Don't complain when the request fails because of i2c stretching */
506 priv->ignore_i2c_write_errors = 1;
507 result = xc_set_RF_frequency(priv, freq_hz);
508 priv->ignore_i2c_write_errors = 0;
509
510 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300511 return 0;
512
513 if (mode == XC_TUNE_ANALOG) {
514 if (WaitForLock(priv) == 1)
515 found = 1;
516 }
517
518 return found;
519}
520
521static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
522{
523 u8 buf[2] = { reg >> 8, reg & 0xff };
524 u8 bval[2] = { 0, 0 };
525 struct i2c_msg msg[2] = {
526 { .addr = priv->i2c_props.addr,
527 .flags = 0, .buf = &buf[0], .len = 2 },
528 { .addr = priv->i2c_props.addr,
529 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
530 };
531
532 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
533 printk(KERN_WARNING "xc4000: I2C read failed\n");
534 return -EREMOTEIO;
535 }
536
537 *val = (bval[0] << 8) | bval[1];
538 return XC_RESULT_SUCCESS;
539}
540
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300541#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300542static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
543{
544 if (type & BASE)
545 printk("BASE ");
546 if (type & INIT1)
547 printk("INIT1 ");
548 if (type & F8MHZ)
549 printk("F8MHZ ");
550 if (type & MTS)
551 printk("MTS ");
552 if (type & D2620)
553 printk("D2620 ");
554 if (type & D2633)
555 printk("D2633 ");
556 if (type & DTV6)
557 printk("DTV6 ");
558 if (type & QAM)
559 printk("QAM ");
560 if (type & DTV7)
561 printk("DTV7 ");
562 if (type & DTV78)
563 printk("DTV78 ");
564 if (type & DTV8)
565 printk("DTV8 ");
566 if (type & FM)
567 printk("FM ");
568 if (type & INPUT1)
569 printk("INPUT1 ");
570 if (type & LCD)
571 printk("LCD ");
572 if (type & NOGD)
573 printk("NOGD ");
574 if (type & MONO)
575 printk("MONO ");
576 if (type & ATSC)
577 printk("ATSC ");
578 if (type & IF)
579 printk("IF ");
580 if (type & LG60)
581 printk("LG60 ");
582 if (type & ATI638)
583 printk("ATI638 ");
584 if (type & OREN538)
585 printk("OREN538 ");
586 if (type & OREN36)
587 printk("OREN36 ");
588 if (type & TOYOTA388)
589 printk("TOYOTA388 ");
590 if (type & TOYOTA794)
591 printk("TOYOTA794 ");
592 if (type & DIBCOM52)
593 printk("DIBCOM52 ");
594 if (type & ZARLINK456)
595 printk("ZARLINK456 ");
596 if (type & CHINA)
597 printk("CHINA ");
598 if (type & F6MHZ)
599 printk("F6MHZ ");
600 if (type & INPUT2)
601 printk("INPUT2 ");
602 if (type & SCODE)
603 printk("SCODE ");
604 if (type & HAS_IF)
605 printk("HAS_IF_%d ", int_freq);
606}
607
Devin Heitmueller11091a32009-07-20 00:54:57 -0300608static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
609 v4l2_std_id *id)
610{
611 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300612 int i, best_i = -1;
613 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300614
Devin Heitmueller11091a32009-07-20 00:54:57 -0300615 if (!priv->firm) {
616 printk("Error! firmware not loaded\n");
617 return -EINVAL;
618 }
619
620 if (((type & ~SCODE) == 0) && (*id == 0))
621 *id = V4L2_STD_PAL;
622
Devin Heitmueller11091a32009-07-20 00:54:57 -0300623 /* Seek for generic video standard match */
624 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300625 v4l2_std_id id_diff_mask =
626 (priv->firm[i].id ^ (*id)) & (*id);
627 unsigned int type_diff_mask =
628 (priv->firm[i].type ^ type)
629 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
630 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300631
Istvan Varga3db95702011-06-04 11:52:34 -0300632 if (type_diff_mask
633 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300634 continue;
635
Istvan Varga3db95702011-06-04 11:52:34 -0300636 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
637 if (!nr_diffs) /* Supports all the requested standards */
638 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300639
Istvan Varga3db95702011-06-04 11:52:34 -0300640 if (nr_diffs < best_nr_diffs) {
641 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300642 best_i = i;
643 }
644 }
645
Istvan Varga3db95702011-06-04 11:52:34 -0300646 /* FIXME: Would make sense to seek for type "hint" match ? */
647 if (best_i < 0) {
648 i = -ENOENT;
649 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300650 }
651
Istvan Varga3db95702011-06-04 11:52:34 -0300652 if (best_nr_diffs > 0U) {
653 printk("Selecting best matching firmware (%u bits differ) for "
654 "type=", best_nr_diffs);
655 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
656 i = best_i;
657 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300658
659found:
660 *id = priv->firm[i].id;
661
662ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300663 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300664 printk("%s firmware for type=", (i < 0) ? "Can't find" :
665 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300666 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300667 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
668 }
669 return i;
670}
671
672static int load_firmware(struct dvb_frontend *fe, unsigned int type,
673 v4l2_std_id *id)
674{
675 struct xc4000_priv *priv = fe->tuner_priv;
676 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300677 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300678
Devin Heitmueller11091a32009-07-20 00:54:57 -0300679 pos = seek_firmware(fe, type, id);
680 if (pos < 0)
681 return pos;
682
Devin Heitmueller11091a32009-07-20 00:54:57 -0300683 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300684
Devin Heitmueller799ed112009-10-04 23:09:18 -0300685 /* Don't complain when the request fails because of i2c stretching */
686 priv->ignore_i2c_write_errors = 1;
687
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300688 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300689
Devin Heitmueller799ed112009-10-04 23:09:18 -0300690 priv->ignore_i2c_write_errors = 0;
691
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300692 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300693}
694
Davide Ferri8d009a02009-06-23 22:34:06 -0300695static int xc4000_fwupload(struct dvb_frontend *fe)
696{
697 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300698 const struct firmware *fw = NULL;
699 const unsigned char *p, *endp;
700 int rc = 0;
701 int n, n_array;
702 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300703 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300704
Istvan Vargafa285bc2011-06-04 11:48:16 -0300705 if (firmware_name[0] != '\0')
706 fname = firmware_name;
707 else
708 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300709
710 printk("Reading firmware %s\n", fname);
711 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
712 if (rc < 0) {
713 if (rc == -ENOENT)
714 printk("Error: firmware %s not found.\n",
715 fname);
716 else
717 printk("Error %d while requesting firmware %s \n",
718 rc, fname);
719
720 return rc;
721 }
722 p = fw->data;
723 endp = p + fw->size;
724
725 if (fw->size < sizeof(name) - 1 + 2 + 2) {
726 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300727 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300728 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300729 }
730
Devin Heitmueller11091a32009-07-20 00:54:57 -0300731 memcpy(name, p, sizeof(name) - 1);
732 name[sizeof(name) - 1] = 0;
733 p += sizeof(name) - 1;
734
735 priv->firm_version = get_unaligned_le16(p);
736 p += 2;
737
738 n_array = get_unaligned_le16(p);
739 p += 2;
740
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300741 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
742 n_array, fname, name,
743 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300744
745 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
746 if (priv->firm == NULL) {
747 printk("Not enough memory to load firmware file.\n");
748 rc = -ENOMEM;
749 goto err;
750 }
751 priv->firm_size = n_array;
752
753 n = -1;
754 while (p < endp) {
755 __u32 type, size;
756 v4l2_std_id id;
757 __u16 int_freq = 0;
758
759 n++;
760 if (n >= n_array) {
761 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300762 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300763 goto corrupt;
764 }
765
766 /* Checks if there's enough bytes to read */
767 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
768 goto header;
769
770 type = get_unaligned_le32(p);
771 p += sizeof(type);
772
773 id = get_unaligned_le64(p);
774 p += sizeof(id);
775
776 if (type & HAS_IF) {
777 int_freq = get_unaligned_le16(p);
778 p += sizeof(int_freq);
779 if (endp - p < sizeof(size))
780 goto header;
781 }
782
783 size = get_unaligned_le32(p);
784 p += sizeof(size);
785
786 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300787 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300788 "(size=%d, expected %d)\n",
789 type, (unsigned long long)id,
790 (unsigned)(endp - p), size);
791 goto corrupt;
792 }
793
794 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
795 if (priv->firm[n].ptr == NULL) {
796 printk("Not enough memory to load firmware file.\n");
797 rc = -ENOMEM;
798 goto err;
799 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300800
Devin Heitmueller11091a32009-07-20 00:54:57 -0300801 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300802 printk("Reading firmware type ");
803 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300804 printk("(%x), id %llx, size=%d.\n",
805 type, (unsigned long long)id, size);
806 }
807
808 memcpy(priv->firm[n].ptr, p, size);
809 priv->firm[n].type = type;
810 priv->firm[n].id = id;
811 priv->firm[n].size = size;
812 priv->firm[n].int_freq = int_freq;
813
814 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300815 }
816
Devin Heitmueller11091a32009-07-20 00:54:57 -0300817 if (n + 1 != priv->firm_size) {
818 printk("Firmware file is incomplete!\n");
819 goto corrupt;
820 }
821
822 goto done;
823
824header:
825 printk("Firmware header is incomplete!\n");
826corrupt:
827 rc = -EINVAL;
828 printk("Error: firmware file is corrupted!\n");
829
830err:
831 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300832
833done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300834 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300835 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300836 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300837
838 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300839}
840
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300841static int load_scode(struct dvb_frontend *fe, unsigned int type,
842 v4l2_std_id *id, __u16 int_freq, int scode)
843{
844 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300845 int pos, rc;
846 unsigned char *p;
847 u8 scode_buf[13];
848 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300849
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300850 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300851
852 if (!int_freq) {
853 pos = seek_firmware(fe, type, id);
854 if (pos < 0)
855 return pos;
856 } else {
857 for (pos = 0; pos < priv->firm_size; pos++) {
858 if ((priv->firm[pos].int_freq == int_freq) &&
859 (priv->firm[pos].type & HAS_IF))
860 break;
861 }
862 if (pos == priv->firm_size)
863 return -ENOENT;
864 }
865
866 p = priv->firm[pos].ptr;
867
Istvan Vargaffce6262011-06-04 11:56:18 -0300868 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
869 return -EINVAL;
870 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300871
872 tuner_info("Loading SCODE for type=");
873 dump_firm_type_and_int_freq(priv->firm[pos].type,
874 priv->firm[pos].int_freq);
875 printk("(%x), id %016llx.\n", priv->firm[pos].type,
876 (unsigned long long)*id);
877
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300878 scode_buf[0] = 0x00;
879 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300880
881 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300882 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
883 if (rc < 0) {
884 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300885 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300886 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300887
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300888 rc = xc_send_i2c_data(priv, scode_buf, 13);
889 if (rc != XC_RESULT_SUCCESS) {
890 /* Even if the send failed, make sure we set back to indirect
891 mode */
892 printk("Failed to set scode %d\n", rc);
893 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300894
895 /* Switch back to indirect-mode */
896 memset(indirect_mode, 0, sizeof(indirect_mode));
897 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300898 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
899 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300900
901 return 0;
902}
903
904static int check_firmware(struct dvb_frontend *fe, unsigned int type,
905 v4l2_std_id std, __u16 int_freq)
906{
907 struct xc4000_priv *priv = fe->tuner_priv;
908 struct firmware_properties new_fw;
909 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300910 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300911 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300912 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300913
914 dprintk(1, "%s called\n", __func__);
915
916 if (!priv->firm) {
917 rc = xc4000_fwupload(fe);
918 if (rc < 0)
919 return rc;
920 }
921
922#ifdef DJH_DEBUG
923 if (priv->ctrl.mts && !(type & FM))
924 type |= MTS;
925#endif
926
927retry:
928 new_fw.type = type;
929 new_fw.id = std;
930 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300931 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300932 new_fw.scode_nr = 0;
933 new_fw.int_freq = int_freq;
934
935 dprintk(1, "checking firmware, user requested type=");
936 if (debug) {
937 dump_firm_type(new_fw.type);
938 printk("(%x), id %016llx, ", new_fw.type,
939 (unsigned long long)new_fw.std_req);
940 if (!int_freq) {
941 printk("scode_tbl ");
942#ifdef DJH_DEBUG
943 dump_firm_type(priv->ctrl.scode_table);
944 printk("(%x), ", priv->ctrl.scode_table);
945#endif
946 } else
947 printk("int_freq %d, ", new_fw.int_freq);
948 printk("scode_nr %d\n", new_fw.scode_nr);
949 }
950
951 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300952 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300953 dprintk(1, "BASE firmware not changed.\n");
954 goto skip_base;
955 }
956
957 /* Updating BASE - forget about all currently loaded firmware */
958 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
959
960 /* Reset is needed before loading firmware */
961 rc = xc4000_TunerReset(fe);
962 if (rc < 0)
963 goto fail;
964
965 /* BASE firmwares are all std0 */
966 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300967 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300968 if (rc < 0) {
969 printk("Error %d while loading base firmware\n", rc);
970 goto fail;
971 }
972
973 /* Load INIT1, if needed */
974 dprintk(1, "Load init1 firmware, if exists\n");
975
Istvan Varga595a83f2011-06-04 11:59:54 -0300976 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300977 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -0300978 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300979 if (rc < 0 && rc != -ENOENT) {
980 tuner_err("Error %d while loading init1 firmware\n",
981 rc);
982 goto fail;
983 }
984
985skip_base:
986 /*
987 * No need to reload standard specific firmware if base firmware
988 * was not reloaded and requested video standards have not changed.
989 */
990 if (priv->cur_fw.type == (BASE | new_fw.type) &&
991 priv->cur_fw.std_req == std) {
992 dprintk(1, "Std-specific firmware already loaded.\n");
993 goto skip_std_specific;
994 }
995
996 /* Reloading std-specific firmware forces a SCODE update */
997 priv->cur_fw.scode_table = 0;
998
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300999 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001000 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001001
1002 if (rc < 0)
1003 goto fail;
1004
1005skip_std_specific:
1006 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1007 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1008 dprintk(1, "SCODE firmware already loaded.\n");
1009 goto check_device;
1010 }
1011
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001012 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001013 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1014 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001015 if (rc != XC_RESULT_SUCCESS)
1016 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001017
1018check_device:
1019 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1020
Devin Heitmueller799ed112009-10-04 23:09:18 -03001021 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001022 &fw_minor) != XC_RESULT_SUCCESS) {
1023 printk("Unable to read tuner registers.\n");
1024 goto fail;
1025 }
1026
1027 dprintk(1, "Device is Xceive %d version %d.%d, "
1028 "firmware version %d.%d\n",
1029 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1030
1031 /* Check firmware version against what we downloaded. */
1032#ifdef DJH_DEBUG
1033 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1034 printk("Incorrect readback of firmware version %x.\n",
1035 (version & 0xff));
1036 goto fail;
1037 }
1038#endif
1039
1040 /* Check that the tuner hardware model remains consistent over time. */
1041 if (priv->hwmodel == 0 && hwmodel == 4000) {
1042 priv->hwmodel = hwmodel;
1043 priv->hwvers = version & 0xff00;
1044 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1045 priv->hwvers != (version & 0xff00)) {
1046 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001047 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001048 goto fail;
1049 }
1050
1051 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1052
1053 /*
1054 * By setting BASE in cur_fw.type only after successfully loading all
1055 * firmwares, we can:
1056 * 1. Identify that BASE firmware with type=0 has been loaded;
1057 * 2. Tell whether BASE firmware was just changed the next time through.
1058 */
1059 priv->cur_fw.type |= BASE;
1060
1061 return 0;
1062
1063fail:
1064 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1065 if (!is_retry) {
1066 msleep(50);
1067 is_retry = 1;
1068 dprintk(1, "Retrying firmware load\n");
1069 goto retry;
1070 }
1071
1072 if (rc == -ENOENT)
1073 rc = -EINVAL;
1074 return rc;
1075}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001076
Davide Ferri8d009a02009-06-23 22:34:06 -03001077static void xc_debug_dump(struct xc4000_priv *priv)
1078{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001079 u16 adc_envelope;
1080 u32 freq_error_hz = 0;
1081 u16 lock_status;
1082 u32 hsync_freq_hz = 0;
1083 u16 frame_lines;
1084 u16 quality;
1085 u8 hw_majorversion = 0, hw_minorversion = 0;
1086 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001087
1088 /* Wait for stats to stabilize.
1089 * Frame Lines needs two frame times after initial lock
1090 * before it is valid.
1091 */
1092 xc_wait(100);
1093
Istvan Vargafbe4a292011-06-03 10:11:48 -03001094 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001095 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1096
1097 xc_get_frequency_error(priv, &freq_error_hz);
1098 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1099
Istvan Vargafbe4a292011-06-03 10:11:48 -03001100 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001101 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1102 lock_status);
1103
Istvan Vargafbe4a292011-06-03 10:11:48 -03001104 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1105 &fw_majorversion, &fw_minorversion);
1106
Davide Ferri8d009a02009-06-23 22:34:06 -03001107 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1108 hw_majorversion, hw_minorversion,
1109 fw_majorversion, fw_minorversion);
1110
Istvan Vargafbe4a292011-06-03 10:11:48 -03001111 xc_get_hsync_freq(priv, &hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001112 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
1113
Istvan Vargafbe4a292011-06-03 10:11:48 -03001114 xc_get_frame_lines(priv, &frame_lines);
Davide Ferri8d009a02009-06-23 22:34:06 -03001115 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1116
Istvan Vargafbe4a292011-06-03 10:11:48 -03001117 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001118 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1119}
1120
1121static int xc4000_set_params(struct dvb_frontend *fe,
1122 struct dvb_frontend_parameters *params)
1123{
1124 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001125 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001126 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001127
Davide Ferri8d009a02009-06-23 22:34:06 -03001128 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1129
Istvan Varga56149422011-06-03 12:23:33 -03001130 mutex_lock(&priv->lock);
1131
Davide Ferri8d009a02009-06-23 22:34:06 -03001132 if (fe->ops.info.type == FE_ATSC) {
1133 dprintk(1, "%s() ATSC\n", __func__);
1134 switch (params->u.vsb.modulation) {
1135 case VSB_8:
1136 case VSB_16:
1137 dprintk(1, "%s() VSB modulation\n", __func__);
1138 priv->rf_mode = XC_RF_MODE_AIR;
1139 priv->freq_hz = params->frequency - 1750000;
1140 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001141 priv->video_standard = XC4000_DTV6;
1142 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001143 break;
1144 case QAM_64:
1145 case QAM_256:
1146 case QAM_AUTO:
1147 dprintk(1, "%s() QAM modulation\n", __func__);
1148 priv->rf_mode = XC_RF_MODE_CABLE;
1149 priv->freq_hz = params->frequency - 1750000;
1150 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001151 priv->video_standard = XC4000_DTV6;
1152 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001153 break;
1154 default:
Istvan Varga56149422011-06-03 12:23:33 -03001155 ret = -EINVAL;
1156 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001157 }
1158 } else if (fe->ops.info.type == FE_OFDM) {
1159 dprintk(1, "%s() OFDM\n", __func__);
1160 switch (params->u.ofdm.bandwidth) {
1161 case BANDWIDTH_6_MHZ:
1162 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001163 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001164 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001165 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001166 break;
1167 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001168 priv->bandwidth = BANDWIDTH_7_MHZ;
1169 priv->video_standard = XC4000_DTV7;
1170 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001171 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001172 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001173 case BANDWIDTH_8_MHZ:
1174 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001175 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001176 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001177 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001178 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001179 case BANDWIDTH_AUTO:
1180 if (params->frequency < 400000000) {
1181 priv->bandwidth = BANDWIDTH_7_MHZ;
1182 priv->freq_hz = params->frequency - 2250000;
1183 } else {
1184 priv->bandwidth = BANDWIDTH_8_MHZ;
1185 priv->freq_hz = params->frequency - 2750000;
1186 }
1187 priv->video_standard = XC4000_DTV7_8;
1188 type = DTV78;
1189 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001190 default:
1191 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001192 ret = -EINVAL;
1193 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001194 }
1195 priv->rf_mode = XC_RF_MODE_AIR;
1196 } else {
1197 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001198 ret = -EINVAL;
1199 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001200 }
1201
1202 dprintk(1, "%s() frequency=%d (compensated)\n",
1203 __func__, priv->freq_hz);
1204
Devin Heitmuellered23db32009-10-05 01:27:14 -03001205 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001206 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1207 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001208
Davide Ferri8d009a02009-06-23 22:34:06 -03001209 ret = xc_SetSignalSource(priv, priv->rf_mode);
1210 if (ret != XC_RESULT_SUCCESS) {
1211 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001212 "xc4000: xc_SetSignalSource(%d) failed\n",
1213 priv->rf_mode);
1214 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001215 }
1216
1217 ret = xc_SetTVStandard(priv,
1218 XC4000_Standard[priv->video_standard].VideoMode,
1219 XC4000_Standard[priv->video_standard].AudioMode);
1220 if (ret != XC_RESULT_SUCCESS) {
1221 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
Istvan Varga56149422011-06-03 12:23:33 -03001222 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001223 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001224 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
1225
1226 if (debug)
1227 xc_debug_dump(priv);
1228
Istvan Varga56149422011-06-03 12:23:33 -03001229 ret = 0;
1230
1231fail:
1232 mutex_unlock(&priv->lock);
1233
1234 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001235}
1236
Davide Ferri8d009a02009-06-23 22:34:06 -03001237static int xc4000_set_analog_params(struct dvb_frontend *fe,
1238 struct analog_parameters *params)
1239{
1240 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga56149422011-06-03 12:23:33 -03001241 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001242
Davide Ferri8d009a02009-06-23 22:34:06 -03001243 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1244 __func__, params->frequency);
1245
Istvan Varga56149422011-06-03 12:23:33 -03001246 mutex_lock(&priv->lock);
1247
Davide Ferri8d009a02009-06-23 22:34:06 -03001248 /* Fix me: it could be air. */
1249 priv->rf_mode = params->mode;
1250 if (params->mode > XC_RF_MODE_CABLE)
1251 priv->rf_mode = XC_RF_MODE_CABLE;
1252
1253 /* params->frequency is in units of 62.5khz */
1254 priv->freq_hz = params->frequency * 62500;
1255
1256 /* FIX ME: Some video standards may have several possible audio
1257 standards. We simply default to one of them here.
1258 */
1259 if (params->std & V4L2_STD_MN) {
1260 /* default to BTSC audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001261 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
Davide Ferri8d009a02009-06-23 22:34:06 -03001262 goto tune_channel;
1263 }
1264
1265 if (params->std & V4L2_STD_PAL_BG) {
1266 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001267 priv->video_standard = XC4000_BG_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001268 goto tune_channel;
1269 }
1270
1271 if (params->std & V4L2_STD_PAL_I) {
1272 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001273 priv->video_standard = XC4000_I_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001274 goto tune_channel;
1275 }
1276
1277 if (params->std & V4L2_STD_PAL_DK) {
1278 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001279 priv->video_standard = XC4000_DK_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001280 goto tune_channel;
1281 }
1282
1283 if (params->std & V4L2_STD_SECAM_DK) {
1284 /* default to A2 DK1 audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001285 priv->video_standard = XC4000_DK_SECAM_A2DK1;
Davide Ferri8d009a02009-06-23 22:34:06 -03001286 goto tune_channel;
1287 }
1288
1289 if (params->std & V4L2_STD_SECAM_L) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001290 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001291 goto tune_channel;
1292 }
1293
1294 if (params->std & V4L2_STD_SECAM_LC) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001295 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001296 goto tune_channel;
1297 }
1298
1299tune_channel:
Devin Heitmuellered23db32009-10-05 01:27:14 -03001300
1301 /* FIXME - firmware type not being set properly */
Istvan Varga56149422011-06-03 12:23:33 -03001302 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1303 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001304
Davide Ferri8d009a02009-06-23 22:34:06 -03001305 ret = xc_SetSignalSource(priv, priv->rf_mode);
1306 if (ret != XC_RESULT_SUCCESS) {
1307 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001308 "xc4000: xc_SetSignalSource(%d) failed\n",
1309 priv->rf_mode);
1310 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001311 }
1312
1313 ret = xc_SetTVStandard(priv,
1314 XC4000_Standard[priv->video_standard].VideoMode,
1315 XC4000_Standard[priv->video_standard].AudioMode);
1316 if (ret != XC_RESULT_SUCCESS) {
1317 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
Istvan Varga56149422011-06-03 12:23:33 -03001318 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001319 }
1320
1321 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
1322
1323 if (debug)
1324 xc_debug_dump(priv);
1325
Istvan Varga56149422011-06-03 12:23:33 -03001326 ret = 0;
1327
1328fail:
1329 mutex_unlock(&priv->lock);
1330
1331 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001332}
1333
1334static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1335{
1336 struct xc4000_priv *priv = fe->tuner_priv;
1337 dprintk(1, "%s()\n", __func__);
1338 *freq = priv->freq_hz;
1339 return 0;
1340}
1341
1342static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1343{
1344 struct xc4000_priv *priv = fe->tuner_priv;
1345 dprintk(1, "%s()\n", __func__);
1346
1347 *bw = priv->bandwidth;
1348 return 0;
1349}
1350
1351static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1352{
1353 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001354 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001355
Istvan Varga56149422011-06-03 12:23:33 -03001356 mutex_lock(&priv->lock);
1357
Davide Ferri8d009a02009-06-23 22:34:06 -03001358 xc_get_lock_status(priv, &lock_status);
1359
Istvan Varga56149422011-06-03 12:23:33 -03001360 mutex_unlock(&priv->lock);
1361
Davide Ferri8d009a02009-06-23 22:34:06 -03001362 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
1363
1364 *status = lock_status;
1365
1366 return 0;
1367}
1368
Davide Ferri8d009a02009-06-23 22:34:06 -03001369static int xc4000_sleep(struct dvb_frontend *fe)
1370{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001371 struct xc4000_priv *priv = fe->tuner_priv;
1372 int ret = XC_RESULT_SUCCESS;
1373
1374 dprintk(1, "%s()\n", __func__);
1375
1376 mutex_lock(&priv->lock);
1377
1378 /* Avoid firmware reload on slow devices */
1379 if ((no_poweroff == 2 ||
1380 (no_poweroff == 0 &&
1381 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1382 (priv->cur_fw.type & BASE) != 0) {
1383 /* force reset and firmware reload */
1384 priv->cur_fw.type = XC_POWERED_DOWN;
1385
1386 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1387 != XC_RESULT_SUCCESS) {
1388 printk(KERN_ERR
1389 "xc4000: %s() unable to shutdown tuner\n",
1390 __func__);
1391 ret = -EREMOTEIO;
1392 }
1393 xc_wait(20);
1394 }
1395
1396 mutex_unlock(&priv->lock);
1397
1398 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001399}
1400
1401static int xc4000_init(struct dvb_frontend *fe)
1402{
Davide Ferri8d009a02009-06-23 22:34:06 -03001403 dprintk(1, "%s()\n", __func__);
1404
Davide Ferri8d009a02009-06-23 22:34:06 -03001405 return 0;
1406}
1407
1408static int xc4000_release(struct dvb_frontend *fe)
1409{
1410 struct xc4000_priv *priv = fe->tuner_priv;
1411
1412 dprintk(1, "%s()\n", __func__);
1413
1414 mutex_lock(&xc4000_list_mutex);
1415
1416 if (priv)
1417 hybrid_tuner_release_state(priv);
1418
1419 mutex_unlock(&xc4000_list_mutex);
1420
1421 fe->tuner_priv = NULL;
1422
1423 return 0;
1424}
1425
1426static const struct dvb_tuner_ops xc4000_tuner_ops = {
1427 .info = {
1428 .name = "Xceive XC4000",
1429 .frequency_min = 1000000,
1430 .frequency_max = 1023000000,
1431 .frequency_step = 50000,
1432 },
1433
1434 .release = xc4000_release,
1435 .init = xc4000_init,
1436 .sleep = xc4000_sleep,
1437
1438 .set_params = xc4000_set_params,
1439 .set_analog_params = xc4000_set_analog_params,
1440 .get_frequency = xc4000_get_frequency,
1441 .get_bandwidth = xc4000_get_bandwidth,
1442 .get_status = xc4000_get_status
1443};
1444
1445struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1446 struct i2c_adapter *i2c,
1447 struct xc4000_config *cfg)
1448{
1449 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001450 int instance;
1451 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001452
Istvan Varga0b402132011-06-03 09:38:04 -03001453 if (cfg->card_type != XC4000_CARD_GENERIC) {
1454 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1455 cfg->i2c_address = 0x61;
1456 cfg->if_khz = 4560;
1457 } else { /* default to PCTV 340E */
1458 cfg->i2c_address = 0x61;
1459 cfg->if_khz = 5400;
1460 }
1461 }
1462
Davide Ferri8d009a02009-06-23 22:34:06 -03001463 dprintk(1, "%s(%d-%04x)\n", __func__,
1464 i2c ? i2c_adapter_id(i2c) : -1,
1465 cfg ? cfg->i2c_address : -1);
1466
1467 mutex_lock(&xc4000_list_mutex);
1468
1469 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1470 hybrid_tuner_instance_list,
1471 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001472 if (cfg->card_type != XC4000_CARD_GENERIC)
1473 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001474 switch (instance) {
1475 case 0:
1476 goto fail;
1477 break;
1478 case 1:
1479 /* new tuner instance */
1480 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001481 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001482 fe->tuner_priv = priv;
1483 break;
1484 default:
1485 /* existing tuner instance */
1486 fe->tuner_priv = priv;
1487 break;
1488 }
1489
Istvan Varga0b402132011-06-03 09:38:04 -03001490 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001491 /* If the IF hasn't been set yet, use the value provided by
1492 the caller (occurs in hybrid devices where the analog
1493 call to xc4000_attach occurs before the digital side) */
1494 priv->if_khz = cfg->if_khz;
1495 }
1496
1497 /* Check if firmware has been loaded. It is possible that another
1498 instance of the driver has loaded the firmware.
1499 */
1500
Istvan Varga027fd362011-06-04 12:04:51 -03001501 if (instance == 1) {
1502 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1503 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001504 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001505 } else {
1506 id = ((priv->cur_fw.type & BASE) != 0 ?
1507 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1508 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001509
1510 switch (id) {
1511 case XC_PRODUCT_ID_FW_LOADED:
1512 printk(KERN_INFO
1513 "xc4000: Successfully identified at address 0x%02x\n",
1514 cfg->i2c_address);
1515 printk(KERN_INFO
1516 "xc4000: Firmware has been loaded previously\n");
1517 break;
1518 case XC_PRODUCT_ID_FW_NOT_LOADED:
1519 printk(KERN_INFO
1520 "xc4000: Successfully identified at address 0x%02x\n",
1521 cfg->i2c_address);
1522 printk(KERN_INFO
1523 "xc4000: Firmware has not been loaded previously\n");
1524 break;
1525 default:
1526 printk(KERN_ERR
1527 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1528 cfg->i2c_address, id);
1529 goto fail;
1530 }
1531
1532 mutex_unlock(&xc4000_list_mutex);
1533
1534 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1535 sizeof(struct dvb_tuner_ops));
1536
Istvan Varga027fd362011-06-04 12:04:51 -03001537 if (instance == 1) {
1538 int ret;
1539 mutex_lock(&priv->lock);
1540 ret = xc4000_fwupload(fe);
1541 mutex_unlock(&priv->lock);
1542 if (ret != XC_RESULT_SUCCESS)
1543 goto fail2;
1544 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001545
Davide Ferri8d009a02009-06-23 22:34:06 -03001546 return fe;
1547fail:
1548 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001549fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001550 xc4000_release(fe);
1551 return NULL;
1552}
1553EXPORT_SYMBOL(xc4000_attach);
1554
1555MODULE_AUTHOR("Steven Toth, Davide Ferri");
1556MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1557MODULE_LICENSE("GPL");