blob: 24afebb933316d248be6924ffdd881ebf61c698c [file] [log] [blame]
Davide Ferri8d009a02009-06-23 22:34:06 -03001/*
2 * Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 * Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/videodev2.h>
28#include <linux/delay.h>
29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h>
Istvan Varga56149422011-06-03 12:23:33 -030031#include <linux/mutex.h>
Devin Heitmueller11091a32009-07-20 00:54:57 -030032#include <asm/unaligned.h>
Davide Ferri8d009a02009-06-23 22:34:06 -030033
34#include "dvb_frontend.h"
35
36#include "xc4000.h"
37#include "tuner-i2c.h"
Devin Heitmueller11091a32009-07-20 00:54:57 -030038#include "tuner-xc2028-types.h"
Davide Ferri8d009a02009-06-23 22:34:06 -030039
Devin Heitmueller4922cec2009-12-27 17:50:43 -030040static int debug;
Davide Ferri8d009a02009-06-23 22:34:06 -030041module_param(debug, int, 0644);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -030042MODULE_PARM_DESC(debug, "\n\t\tDebugging level (0 to 2, default: 0 (off)).");
Davide Ferri8d009a02009-06-23 22:34:06 -030043
44static int no_poweroff;
45module_param(no_poweroff, int, 0644);
Istvan Varga5272f6b2011-06-04 12:03:03 -030046MODULE_PARM_DESC(no_poweroff, "\n\t\t1: keep device energized and with tuner "
47 "ready all the times.\n"
48 "\t\tFaster, but consumes more power and keeps the device hotter.\n"
49 "\t\t2: powers device off when not used.\n"
50 "\t\t0 (default): use device-specific default mode.");
Davide Ferri8d009a02009-06-23 22:34:06 -030051
Istvan 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);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300242static void xc_debug_dump(struct xc4000_priv *priv);
Davide Ferri8d009a02009-06-23 22:34:06 -0300243
244static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
245{
246 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
247 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300248 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300249 if (priv->ignore_i2c_write_errors == 0) {
250 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
251 len);
252 if (len == 4) {
253 printk("bytes %02x %02x %02x %02x\n", buf[0],
254 buf[1], buf[2], buf[3]);
255 }
256 return XC_RESULT_I2C_WRITE_FAILURE;
257 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300258 }
259 return XC_RESULT_SUCCESS;
260}
261
Davide Ferri8d009a02009-06-23 22:34:06 -0300262static void xc_wait(int wait_ms)
263{
264 msleep(wait_ms);
265}
266
267static int xc4000_TunerReset(struct dvb_frontend *fe)
268{
269 struct xc4000_priv *priv = fe->tuner_priv;
270 int ret;
271
272 dprintk(1, "%s()\n", __func__);
273
274 if (fe->callback) {
275 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
276 fe->dvb->priv :
277 priv->i2c_props.adap->algo_data,
278 DVB_FRONTEND_COMPONENT_TUNER,
279 XC4000_TUNER_RESET, 0);
280 if (ret) {
281 printk(KERN_ERR "xc4000: reset failed\n");
282 return XC_RESULT_RESET_FAILURE;
283 }
284 } else {
285 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
286 return XC_RESULT_RESET_FAILURE;
287 }
288 return XC_RESULT_SUCCESS;
289}
290
291static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
292{
293 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300294 int result;
295
296 buf[0] = (regAddr >> 8) & 0xFF;
297 buf[1] = regAddr & 0xFF;
298 buf[2] = (i2cData >> 8) & 0xFF;
299 buf[3] = i2cData & 0xFF;
300 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300301
302 return result;
303}
304
305static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
306{
307 struct xc4000_priv *priv = fe->tuner_priv;
308
309 int i, nbytes_to_send, result;
310 unsigned int len, pos, index;
311 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
312
313 index = 0;
314 while ((i2c_sequence[index] != 0xFF) ||
315 (i2c_sequence[index + 1] != 0xFF)) {
316 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
317 if (len == 0x0000) {
318 /* RESET command */
319 result = xc4000_TunerReset(fe);
320 index += 2;
321 if (result != XC_RESULT_SUCCESS)
322 return result;
323 } else if (len & 0x8000) {
324 /* WAIT command */
325 xc_wait(len & 0x7FFF);
326 index += 2;
327 } else {
328 /* Send i2c data whilst ensuring individual transactions
329 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
330 */
331 index += 2;
332 buf[0] = i2c_sequence[index];
333 buf[1] = i2c_sequence[index + 1];
334 pos = 2;
335 while (pos < len) {
336 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
337 nbytes_to_send =
338 XC_MAX_I2C_WRITE_LENGTH;
339 else
340 nbytes_to_send = (len - pos + 2);
341 for (i = 2; i < nbytes_to_send; i++) {
342 buf[i] = i2c_sequence[index + pos +
343 i - 2];
344 }
345 result = xc_send_i2c_data(priv, buf,
346 nbytes_to_send);
347
348 if (result != XC_RESULT_SUCCESS)
349 return result;
350
351 pos += nbytes_to_send - 2;
352 }
353 index += len;
354 }
355 }
356 return XC_RESULT_SUCCESS;
357}
358
Davide Ferri8d009a02009-06-23 22:34:06 -0300359static int xc_SetTVStandard(struct xc4000_priv *priv,
360 u16 VideoMode, u16 AudioMode)
361{
362 int ret;
363 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
364 dprintk(1, "%s() Standard = %s\n",
365 __func__,
366 XC4000_Standard[priv->video_standard].Name);
367
Devin Heitmueller799ed112009-10-04 23:09:18 -0300368 /* Don't complain when the request fails because of i2c stretching */
369 priv->ignore_i2c_write_errors = 1;
370
Davide Ferri8d009a02009-06-23 22:34:06 -0300371 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
372 if (ret == XC_RESULT_SUCCESS)
373 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
374
Devin Heitmueller799ed112009-10-04 23:09:18 -0300375 priv->ignore_i2c_write_errors = 0;
376
Davide Ferri8d009a02009-06-23 22:34:06 -0300377 return ret;
378}
379
380static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
381{
382 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
383 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
384
385 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
386 rf_mode = XC_RF_MODE_CABLE;
387 printk(KERN_ERR
388 "%s(), Invalid mode, defaulting to CABLE",
389 __func__);
390 }
391 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
392}
393
394static const struct dvb_tuner_ops xc4000_tuner_ops;
395
396static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
397{
398 u16 freq_code;
399
400 dprintk(1, "%s(%u)\n", __func__, freq_hz);
401
402 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
403 (freq_hz < xc4000_tuner_ops.info.frequency_min))
404 return XC_RESULT_OUT_OF_RANGE;
405
406 freq_code = (u16)(freq_hz / 15625);
407
408 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
409 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
410 only be used for fast scanning for channel lock) */
411 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
412}
413
Davide Ferri8d009a02009-06-23 22:34:06 -0300414static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
415{
416 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
417}
418
419static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
420{
421 int result;
422 u16 regData;
423 u32 tmp;
424
425 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
426 if (result != XC_RESULT_SUCCESS)
427 return result;
428
Istvan Varga1368ceb2011-06-03 12:27:30 -0300429 tmp = (u32)regData & 0xFFFFU;
430 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
431 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300432 return result;
433}
434
435static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
436{
437 return xc4000_readreg(priv, XREG_LOCK, lock_status);
438}
439
440static int xc_get_version(struct xc4000_priv *priv,
441 u8 *hw_majorversion, u8 *hw_minorversion,
442 u8 *fw_majorversion, u8 *fw_minorversion)
443{
444 u16 data;
445 int result;
446
447 result = xc4000_readreg(priv, XREG_VERSION, &data);
448 if (result != XC_RESULT_SUCCESS)
449 return result;
450
451 (*hw_majorversion) = (data >> 12) & 0x0F;
452 (*hw_minorversion) = (data >> 8) & 0x0F;
453 (*fw_majorversion) = (data >> 4) & 0x0F;
454 (*fw_minorversion) = data & 0x0F;
455
456 return 0;
457}
458
Davide Ferri8d009a02009-06-23 22:34:06 -0300459static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
460{
461 u16 regData;
462 int result;
463
464 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
465 if (result != XC_RESULT_SUCCESS)
466 return result;
467
468 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
469 return result;
470}
471
472static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
473{
474 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
475}
476
477static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
478{
479 return xc4000_readreg(priv, XREG_QUALITY, quality);
480}
481
482static u16 WaitForLock(struct xc4000_priv *priv)
483{
484 u16 lockState = 0;
485 int watchDogCount = 40;
486
487 while ((lockState == 0) && (watchDogCount > 0)) {
488 xc_get_lock_status(priv, &lockState);
489 if (lockState != 1) {
490 xc_wait(5);
491 watchDogCount--;
492 }
493 }
494 return lockState;
495}
496
497#define XC_TUNE_ANALOG 0
498#define XC_TUNE_DIGITAL 1
499static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
500{
Istvan Vargafbe4a292011-06-03 10:11:48 -0300501 int found = 0;
502 int result = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300503
504 dprintk(1, "%s(%u)\n", __func__, freq_hz);
505
Devin Heitmueller799ed112009-10-04 23:09:18 -0300506 /* Don't complain when the request fails because of i2c stretching */
507 priv->ignore_i2c_write_errors = 1;
508 result = xc_set_RF_frequency(priv, freq_hz);
509 priv->ignore_i2c_write_errors = 0;
510
511 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300512 return 0;
513
514 if (mode == XC_TUNE_ANALOG) {
515 if (WaitForLock(priv) == 1)
516 found = 1;
517 }
518
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300519 /* Wait for stats to stabilize.
520 * Frame Lines needs two frame times after initial lock
521 * before it is valid.
522 */
523 xc_wait(debug ? 100 : 10);
524
525 if (debug)
526 xc_debug_dump(priv);
527
Davide Ferri8d009a02009-06-23 22:34:06 -0300528 return found;
529}
530
531static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
532{
533 u8 buf[2] = { reg >> 8, reg & 0xff };
534 u8 bval[2] = { 0, 0 };
535 struct i2c_msg msg[2] = {
536 { .addr = priv->i2c_props.addr,
537 .flags = 0, .buf = &buf[0], .len = 2 },
538 { .addr = priv->i2c_props.addr,
539 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
540 };
541
542 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
543 printk(KERN_WARNING "xc4000: I2C read failed\n");
544 return -EREMOTEIO;
545 }
546
547 *val = (bval[0] << 8) | bval[1];
548 return XC_RESULT_SUCCESS;
549}
550
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300551#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300552static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
553{
554 if (type & BASE)
555 printk("BASE ");
556 if (type & INIT1)
557 printk("INIT1 ");
558 if (type & F8MHZ)
559 printk("F8MHZ ");
560 if (type & MTS)
561 printk("MTS ");
562 if (type & D2620)
563 printk("D2620 ");
564 if (type & D2633)
565 printk("D2633 ");
566 if (type & DTV6)
567 printk("DTV6 ");
568 if (type & QAM)
569 printk("QAM ");
570 if (type & DTV7)
571 printk("DTV7 ");
572 if (type & DTV78)
573 printk("DTV78 ");
574 if (type & DTV8)
575 printk("DTV8 ");
576 if (type & FM)
577 printk("FM ");
578 if (type & INPUT1)
579 printk("INPUT1 ");
580 if (type & LCD)
581 printk("LCD ");
582 if (type & NOGD)
583 printk("NOGD ");
584 if (type & MONO)
585 printk("MONO ");
586 if (type & ATSC)
587 printk("ATSC ");
588 if (type & IF)
589 printk("IF ");
590 if (type & LG60)
591 printk("LG60 ");
592 if (type & ATI638)
593 printk("ATI638 ");
594 if (type & OREN538)
595 printk("OREN538 ");
596 if (type & OREN36)
597 printk("OREN36 ");
598 if (type & TOYOTA388)
599 printk("TOYOTA388 ");
600 if (type & TOYOTA794)
601 printk("TOYOTA794 ");
602 if (type & DIBCOM52)
603 printk("DIBCOM52 ");
604 if (type & ZARLINK456)
605 printk("ZARLINK456 ");
606 if (type & CHINA)
607 printk("CHINA ");
608 if (type & F6MHZ)
609 printk("F6MHZ ");
610 if (type & INPUT2)
611 printk("INPUT2 ");
612 if (type & SCODE)
613 printk("SCODE ");
614 if (type & HAS_IF)
615 printk("HAS_IF_%d ", int_freq);
616}
617
Devin Heitmueller11091a32009-07-20 00:54:57 -0300618static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
619 v4l2_std_id *id)
620{
621 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300622 int i, best_i = -1;
623 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300624
Devin Heitmueller11091a32009-07-20 00:54:57 -0300625 if (!priv->firm) {
626 printk("Error! firmware not loaded\n");
627 return -EINVAL;
628 }
629
630 if (((type & ~SCODE) == 0) && (*id == 0))
631 *id = V4L2_STD_PAL;
632
Devin Heitmueller11091a32009-07-20 00:54:57 -0300633 /* Seek for generic video standard match */
634 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300635 v4l2_std_id id_diff_mask =
636 (priv->firm[i].id ^ (*id)) & (*id);
637 unsigned int type_diff_mask =
638 (priv->firm[i].type ^ type)
639 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
640 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300641
Istvan Varga3db95702011-06-04 11:52:34 -0300642 if (type_diff_mask
643 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300644 continue;
645
Istvan Varga3db95702011-06-04 11:52:34 -0300646 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
647 if (!nr_diffs) /* Supports all the requested standards */
648 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300649
Istvan Varga3db95702011-06-04 11:52:34 -0300650 if (nr_diffs < best_nr_diffs) {
651 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300652 best_i = i;
653 }
654 }
655
Istvan Varga3db95702011-06-04 11:52:34 -0300656 /* FIXME: Would make sense to seek for type "hint" match ? */
657 if (best_i < 0) {
658 i = -ENOENT;
659 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300660 }
661
Istvan Varga3db95702011-06-04 11:52:34 -0300662 if (best_nr_diffs > 0U) {
663 printk("Selecting best matching firmware (%u bits differ) for "
664 "type=", best_nr_diffs);
665 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
666 i = best_i;
667 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300668
669found:
670 *id = priv->firm[i].id;
671
672ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300673 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300674 printk("%s firmware for type=", (i < 0) ? "Can't find" :
675 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300676 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300677 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
678 }
679 return i;
680}
681
682static int load_firmware(struct dvb_frontend *fe, unsigned int type,
683 v4l2_std_id *id)
684{
685 struct xc4000_priv *priv = fe->tuner_priv;
686 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300687 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300688
Devin Heitmueller11091a32009-07-20 00:54:57 -0300689 pos = seek_firmware(fe, type, id);
690 if (pos < 0)
691 return pos;
692
Devin Heitmueller11091a32009-07-20 00:54:57 -0300693 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300694
Devin Heitmueller799ed112009-10-04 23:09:18 -0300695 /* Don't complain when the request fails because of i2c stretching */
696 priv->ignore_i2c_write_errors = 1;
697
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300698 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300699
Devin Heitmueller799ed112009-10-04 23:09:18 -0300700 priv->ignore_i2c_write_errors = 0;
701
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300702 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300703}
704
Davide Ferri8d009a02009-06-23 22:34:06 -0300705static int xc4000_fwupload(struct dvb_frontend *fe)
706{
707 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300708 const struct firmware *fw = NULL;
709 const unsigned char *p, *endp;
710 int rc = 0;
711 int n, n_array;
712 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300713 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300714
Istvan Vargafa285bc2011-06-04 11:48:16 -0300715 if (firmware_name[0] != '\0')
716 fname = firmware_name;
717 else
718 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300719
720 printk("Reading firmware %s\n", fname);
721 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
722 if (rc < 0) {
723 if (rc == -ENOENT)
724 printk("Error: firmware %s not found.\n",
725 fname);
726 else
727 printk("Error %d while requesting firmware %s \n",
728 rc, fname);
729
730 return rc;
731 }
732 p = fw->data;
733 endp = p + fw->size;
734
735 if (fw->size < sizeof(name) - 1 + 2 + 2) {
736 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300737 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300738 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300739 }
740
Devin Heitmueller11091a32009-07-20 00:54:57 -0300741 memcpy(name, p, sizeof(name) - 1);
742 name[sizeof(name) - 1] = 0;
743 p += sizeof(name) - 1;
744
745 priv->firm_version = get_unaligned_le16(p);
746 p += 2;
747
748 n_array = get_unaligned_le16(p);
749 p += 2;
750
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300751 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
752 n_array, fname, name,
753 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300754
755 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
756 if (priv->firm == NULL) {
757 printk("Not enough memory to load firmware file.\n");
758 rc = -ENOMEM;
759 goto err;
760 }
761 priv->firm_size = n_array;
762
763 n = -1;
764 while (p < endp) {
765 __u32 type, size;
766 v4l2_std_id id;
767 __u16 int_freq = 0;
768
769 n++;
770 if (n >= n_array) {
771 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300772 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300773 goto corrupt;
774 }
775
776 /* Checks if there's enough bytes to read */
777 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
778 goto header;
779
780 type = get_unaligned_le32(p);
781 p += sizeof(type);
782
783 id = get_unaligned_le64(p);
784 p += sizeof(id);
785
786 if (type & HAS_IF) {
787 int_freq = get_unaligned_le16(p);
788 p += sizeof(int_freq);
789 if (endp - p < sizeof(size))
790 goto header;
791 }
792
793 size = get_unaligned_le32(p);
794 p += sizeof(size);
795
796 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300797 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300798 "(size=%d, expected %d)\n",
799 type, (unsigned long long)id,
800 (unsigned)(endp - p), size);
801 goto corrupt;
802 }
803
804 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
805 if (priv->firm[n].ptr == NULL) {
806 printk("Not enough memory to load firmware file.\n");
807 rc = -ENOMEM;
808 goto err;
809 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300810
Devin Heitmueller11091a32009-07-20 00:54:57 -0300811 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300812 printk("Reading firmware type ");
813 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300814 printk("(%x), id %llx, size=%d.\n",
815 type, (unsigned long long)id, size);
816 }
817
818 memcpy(priv->firm[n].ptr, p, size);
819 priv->firm[n].type = type;
820 priv->firm[n].id = id;
821 priv->firm[n].size = size;
822 priv->firm[n].int_freq = int_freq;
823
824 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300825 }
826
Devin Heitmueller11091a32009-07-20 00:54:57 -0300827 if (n + 1 != priv->firm_size) {
828 printk("Firmware file is incomplete!\n");
829 goto corrupt;
830 }
831
832 goto done;
833
834header:
835 printk("Firmware header is incomplete!\n");
836corrupt:
837 rc = -EINVAL;
838 printk("Error: firmware file is corrupted!\n");
839
840err:
841 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300842
843done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300844 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300845 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300846 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300847
848 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300849}
850
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300851static int load_scode(struct dvb_frontend *fe, unsigned int type,
852 v4l2_std_id *id, __u16 int_freq, int scode)
853{
854 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300855 int pos, rc;
856 unsigned char *p;
857 u8 scode_buf[13];
858 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300859
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300860 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300861
862 if (!int_freq) {
863 pos = seek_firmware(fe, type, id);
864 if (pos < 0)
865 return pos;
866 } else {
867 for (pos = 0; pos < priv->firm_size; pos++) {
868 if ((priv->firm[pos].int_freq == int_freq) &&
869 (priv->firm[pos].type & HAS_IF))
870 break;
871 }
872 if (pos == priv->firm_size)
873 return -ENOENT;
874 }
875
876 p = priv->firm[pos].ptr;
877
Istvan Vargaffce6262011-06-04 11:56:18 -0300878 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
879 return -EINVAL;
880 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300881
882 tuner_info("Loading SCODE for type=");
883 dump_firm_type_and_int_freq(priv->firm[pos].type,
884 priv->firm[pos].int_freq);
885 printk("(%x), id %016llx.\n", priv->firm[pos].type,
886 (unsigned long long)*id);
887
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300888 scode_buf[0] = 0x00;
889 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300890
891 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300892 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
893 if (rc < 0) {
894 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300895 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300896 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300897
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300898 rc = xc_send_i2c_data(priv, scode_buf, 13);
899 if (rc != XC_RESULT_SUCCESS) {
900 /* Even if the send failed, make sure we set back to indirect
901 mode */
902 printk("Failed to set scode %d\n", rc);
903 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300904
905 /* Switch back to indirect-mode */
906 memset(indirect_mode, 0, sizeof(indirect_mode));
907 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300908 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
909 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300910
911 return 0;
912}
913
914static int check_firmware(struct dvb_frontend *fe, unsigned int type,
915 v4l2_std_id std, __u16 int_freq)
916{
917 struct xc4000_priv *priv = fe->tuner_priv;
918 struct firmware_properties new_fw;
919 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300920 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300921 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300922 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300923
924 dprintk(1, "%s called\n", __func__);
925
926 if (!priv->firm) {
927 rc = xc4000_fwupload(fe);
928 if (rc < 0)
929 return rc;
930 }
931
932#ifdef DJH_DEBUG
933 if (priv->ctrl.mts && !(type & FM))
934 type |= MTS;
935#endif
936
937retry:
938 new_fw.type = type;
939 new_fw.id = std;
940 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300941 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300942 new_fw.scode_nr = 0;
943 new_fw.int_freq = int_freq;
944
945 dprintk(1, "checking firmware, user requested type=");
946 if (debug) {
947 dump_firm_type(new_fw.type);
948 printk("(%x), id %016llx, ", new_fw.type,
949 (unsigned long long)new_fw.std_req);
950 if (!int_freq) {
951 printk("scode_tbl ");
952#ifdef DJH_DEBUG
953 dump_firm_type(priv->ctrl.scode_table);
954 printk("(%x), ", priv->ctrl.scode_table);
955#endif
956 } else
957 printk("int_freq %d, ", new_fw.int_freq);
958 printk("scode_nr %d\n", new_fw.scode_nr);
959 }
960
961 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300962 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300963 dprintk(1, "BASE firmware not changed.\n");
964 goto skip_base;
965 }
966
967 /* Updating BASE - forget about all currently loaded firmware */
968 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
969
970 /* Reset is needed before loading firmware */
971 rc = xc4000_TunerReset(fe);
972 if (rc < 0)
973 goto fail;
974
975 /* BASE firmwares are all std0 */
976 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300977 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300978 if (rc < 0) {
979 printk("Error %d while loading base firmware\n", rc);
980 goto fail;
981 }
982
983 /* Load INIT1, if needed */
984 dprintk(1, "Load init1 firmware, if exists\n");
985
Istvan Varga595a83f2011-06-04 11:59:54 -0300986 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300987 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -0300988 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300989 if (rc < 0 && rc != -ENOENT) {
990 tuner_err("Error %d while loading init1 firmware\n",
991 rc);
992 goto fail;
993 }
994
995skip_base:
996 /*
997 * No need to reload standard specific firmware if base firmware
998 * was not reloaded and requested video standards have not changed.
999 */
1000 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1001 priv->cur_fw.std_req == std) {
1002 dprintk(1, "Std-specific firmware already loaded.\n");
1003 goto skip_std_specific;
1004 }
1005
1006 /* Reloading std-specific firmware forces a SCODE update */
1007 priv->cur_fw.scode_table = 0;
1008
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001009 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001010 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001011
1012 if (rc < 0)
1013 goto fail;
1014
1015skip_std_specific:
1016 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1017 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1018 dprintk(1, "SCODE firmware already loaded.\n");
1019 goto check_device;
1020 }
1021
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001022 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001023 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1024 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001025 if (rc != XC_RESULT_SUCCESS)
1026 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001027
1028check_device:
1029 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1030
Devin Heitmueller799ed112009-10-04 23:09:18 -03001031 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001032 &fw_minor) != XC_RESULT_SUCCESS) {
1033 printk("Unable to read tuner registers.\n");
1034 goto fail;
1035 }
1036
1037 dprintk(1, "Device is Xceive %d version %d.%d, "
1038 "firmware version %d.%d\n",
1039 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1040
1041 /* Check firmware version against what we downloaded. */
1042#ifdef DJH_DEBUG
1043 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1044 printk("Incorrect readback of firmware version %x.\n",
1045 (version & 0xff));
1046 goto fail;
1047 }
1048#endif
1049
1050 /* Check that the tuner hardware model remains consistent over time. */
1051 if (priv->hwmodel == 0 && hwmodel == 4000) {
1052 priv->hwmodel = hwmodel;
1053 priv->hwvers = version & 0xff00;
1054 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1055 priv->hwvers != (version & 0xff00)) {
1056 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001057 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001058 goto fail;
1059 }
1060
1061 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1062
1063 /*
1064 * By setting BASE in cur_fw.type only after successfully loading all
1065 * firmwares, we can:
1066 * 1. Identify that BASE firmware with type=0 has been loaded;
1067 * 2. Tell whether BASE firmware was just changed the next time through.
1068 */
1069 priv->cur_fw.type |= BASE;
1070
1071 return 0;
1072
1073fail:
1074 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1075 if (!is_retry) {
1076 msleep(50);
1077 is_retry = 1;
1078 dprintk(1, "Retrying firmware load\n");
1079 goto retry;
1080 }
1081
1082 if (rc == -ENOENT)
1083 rc = -EINVAL;
1084 return rc;
1085}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001086
Davide Ferri8d009a02009-06-23 22:34:06 -03001087static void xc_debug_dump(struct xc4000_priv *priv)
1088{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001089 u16 adc_envelope;
1090 u32 freq_error_hz = 0;
1091 u16 lock_status;
1092 u32 hsync_freq_hz = 0;
1093 u16 frame_lines;
1094 u16 quality;
1095 u8 hw_majorversion = 0, hw_minorversion = 0;
1096 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001097
Istvan Vargafbe4a292011-06-03 10:11:48 -03001098 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001099 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1100
1101 xc_get_frequency_error(priv, &freq_error_hz);
1102 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1103
Istvan Vargafbe4a292011-06-03 10:11:48 -03001104 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001105 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1106 lock_status);
1107
Istvan Vargafbe4a292011-06-03 10:11:48 -03001108 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1109 &fw_majorversion, &fw_minorversion);
Davide Ferri8d009a02009-06-23 22:34:06 -03001110 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1111 hw_majorversion, hw_minorversion,
1112 fw_majorversion, fw_minorversion);
1113
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001114 if (priv->video_standard < XC4000_DTV6) {
1115 xc_get_hsync_freq(priv, &hsync_freq_hz);
1116 dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
1117 hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001118
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001119 xc_get_frame_lines(priv, &frame_lines);
1120 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1121 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001122
Istvan Vargafbe4a292011-06-03 10:11:48 -03001123 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001124 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1125}
1126
1127static int xc4000_set_params(struct dvb_frontend *fe,
1128 struct dvb_frontend_parameters *params)
1129{
1130 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001131 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001132 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001133
Davide Ferri8d009a02009-06-23 22:34:06 -03001134 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1135
Istvan Varga56149422011-06-03 12:23:33 -03001136 mutex_lock(&priv->lock);
1137
Davide Ferri8d009a02009-06-23 22:34:06 -03001138 if (fe->ops.info.type == FE_ATSC) {
1139 dprintk(1, "%s() ATSC\n", __func__);
1140 switch (params->u.vsb.modulation) {
1141 case VSB_8:
1142 case VSB_16:
1143 dprintk(1, "%s() VSB modulation\n", __func__);
1144 priv->rf_mode = XC_RF_MODE_AIR;
1145 priv->freq_hz = params->frequency - 1750000;
1146 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001147 priv->video_standard = XC4000_DTV6;
1148 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001149 break;
1150 case QAM_64:
1151 case QAM_256:
1152 case QAM_AUTO:
1153 dprintk(1, "%s() QAM modulation\n", __func__);
1154 priv->rf_mode = XC_RF_MODE_CABLE;
1155 priv->freq_hz = params->frequency - 1750000;
1156 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001157 priv->video_standard = XC4000_DTV6;
1158 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001159 break;
1160 default:
Istvan Varga56149422011-06-03 12:23:33 -03001161 ret = -EINVAL;
1162 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001163 }
1164 } else if (fe->ops.info.type == FE_OFDM) {
1165 dprintk(1, "%s() OFDM\n", __func__);
1166 switch (params->u.ofdm.bandwidth) {
1167 case BANDWIDTH_6_MHZ:
1168 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001169 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001170 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001171 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001172 break;
1173 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001174 priv->bandwidth = BANDWIDTH_7_MHZ;
1175 priv->video_standard = XC4000_DTV7;
1176 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001177 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001178 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001179 case BANDWIDTH_8_MHZ:
1180 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001181 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001182 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001183 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001184 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001185 case BANDWIDTH_AUTO:
1186 if (params->frequency < 400000000) {
1187 priv->bandwidth = BANDWIDTH_7_MHZ;
1188 priv->freq_hz = params->frequency - 2250000;
1189 } else {
1190 priv->bandwidth = BANDWIDTH_8_MHZ;
1191 priv->freq_hz = params->frequency - 2750000;
1192 }
1193 priv->video_standard = XC4000_DTV7_8;
1194 type = DTV78;
1195 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001196 default:
1197 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001198 ret = -EINVAL;
1199 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001200 }
1201 priv->rf_mode = XC_RF_MODE_AIR;
1202 } else {
1203 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001204 ret = -EINVAL;
1205 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001206 }
1207
1208 dprintk(1, "%s() frequency=%d (compensated)\n",
1209 __func__, priv->freq_hz);
1210
Devin Heitmuellered23db32009-10-05 01:27:14 -03001211 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001212 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1213 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001214
Davide Ferri8d009a02009-06-23 22:34:06 -03001215 ret = xc_SetSignalSource(priv, priv->rf_mode);
1216 if (ret != XC_RESULT_SUCCESS) {
1217 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001218 "xc4000: xc_SetSignalSource(%d) failed\n",
1219 priv->rf_mode);
1220 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001221 }
1222
1223 ret = xc_SetTVStandard(priv,
1224 XC4000_Standard[priv->video_standard].VideoMode,
1225 XC4000_Standard[priv->video_standard].AudioMode);
1226 if (ret != XC_RESULT_SUCCESS) {
1227 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
Istvan Varga56149422011-06-03 12:23:33 -03001228 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001229 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001230 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
1231
Istvan Varga56149422011-06-03 12:23:33 -03001232 ret = 0;
1233
1234fail:
1235 mutex_unlock(&priv->lock);
1236
1237 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001238}
1239
Davide Ferri8d009a02009-06-23 22:34:06 -03001240static int xc4000_set_analog_params(struct dvb_frontend *fe,
1241 struct analog_parameters *params)
1242{
1243 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga56149422011-06-03 12:23:33 -03001244 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001245
Davide Ferri8d009a02009-06-23 22:34:06 -03001246 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1247 __func__, params->frequency);
1248
Istvan Varga56149422011-06-03 12:23:33 -03001249 mutex_lock(&priv->lock);
1250
Davide Ferri8d009a02009-06-23 22:34:06 -03001251 /* Fix me: it could be air. */
1252 priv->rf_mode = params->mode;
1253 if (params->mode > XC_RF_MODE_CABLE)
1254 priv->rf_mode = XC_RF_MODE_CABLE;
1255
1256 /* params->frequency is in units of 62.5khz */
1257 priv->freq_hz = params->frequency * 62500;
1258
1259 /* FIX ME: Some video standards may have several possible audio
1260 standards. We simply default to one of them here.
1261 */
1262 if (params->std & V4L2_STD_MN) {
1263 /* default to BTSC audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001264 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
Davide Ferri8d009a02009-06-23 22:34:06 -03001265 goto tune_channel;
1266 }
1267
1268 if (params->std & V4L2_STD_PAL_BG) {
1269 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001270 priv->video_standard = XC4000_BG_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001271 goto tune_channel;
1272 }
1273
1274 if (params->std & V4L2_STD_PAL_I) {
1275 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001276 priv->video_standard = XC4000_I_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001277 goto tune_channel;
1278 }
1279
1280 if (params->std & V4L2_STD_PAL_DK) {
1281 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001282 priv->video_standard = XC4000_DK_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001283 goto tune_channel;
1284 }
1285
1286 if (params->std & V4L2_STD_SECAM_DK) {
1287 /* default to A2 DK1 audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001288 priv->video_standard = XC4000_DK_SECAM_A2DK1;
Davide Ferri8d009a02009-06-23 22:34:06 -03001289 goto tune_channel;
1290 }
1291
1292 if (params->std & V4L2_STD_SECAM_L) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001293 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001294 goto tune_channel;
1295 }
1296
1297 if (params->std & V4L2_STD_SECAM_LC) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001298 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001299 goto tune_channel;
1300 }
1301
1302tune_channel:
Devin Heitmuellered23db32009-10-05 01:27:14 -03001303
1304 /* FIXME - firmware type not being set properly */
Istvan Varga56149422011-06-03 12:23:33 -03001305 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1306 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001307
Davide Ferri8d009a02009-06-23 22:34:06 -03001308 ret = xc_SetSignalSource(priv, priv->rf_mode);
1309 if (ret != XC_RESULT_SUCCESS) {
1310 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001311 "xc4000: xc_SetSignalSource(%d) failed\n",
1312 priv->rf_mode);
1313 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001314 }
1315
1316 ret = xc_SetTVStandard(priv,
1317 XC4000_Standard[priv->video_standard].VideoMode,
1318 XC4000_Standard[priv->video_standard].AudioMode);
1319 if (ret != XC_RESULT_SUCCESS) {
1320 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
Istvan Varga56149422011-06-03 12:23:33 -03001321 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001322 }
1323
1324 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
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;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001337
Davide Ferri8d009a02009-06-23 22:34:06 -03001338 *freq = priv->freq_hz;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001339
1340 if (debug) {
1341 mutex_lock(&priv->lock);
1342 if ((priv->cur_fw.type
1343 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1344 u16 snr = 0;
1345 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1346 mutex_unlock(&priv->lock);
1347 dprintk(1, "%s() freq = %u, SNR = %d\n",
1348 __func__, *freq, snr);
1349 return 0;
1350 }
1351 }
1352 mutex_unlock(&priv->lock);
1353 }
1354
1355 dprintk(1, "%s()\n", __func__);
1356
Davide Ferri8d009a02009-06-23 22:34:06 -03001357 return 0;
1358}
1359
1360static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1361{
1362 struct xc4000_priv *priv = fe->tuner_priv;
1363 dprintk(1, "%s()\n", __func__);
1364
1365 *bw = priv->bandwidth;
1366 return 0;
1367}
1368
1369static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1370{
1371 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001372 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001373
Istvan Varga56149422011-06-03 12:23:33 -03001374 mutex_lock(&priv->lock);
1375
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001376 if (priv->cur_fw.type & BASE)
1377 xc_get_lock_status(priv, &lock_status);
1378
1379 *status = (lock_status == 1 ?
1380 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1381 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1382 *status &= (~TUNER_STATUS_STEREO);
Davide Ferri8d009a02009-06-23 22:34:06 -03001383
Istvan Varga56149422011-06-03 12:23:33 -03001384 mutex_unlock(&priv->lock);
1385
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001386 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001387
1388 return 0;
1389}
1390
Davide Ferri8d009a02009-06-23 22:34:06 -03001391static int xc4000_sleep(struct dvb_frontend *fe)
1392{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001393 struct xc4000_priv *priv = fe->tuner_priv;
1394 int ret = XC_RESULT_SUCCESS;
1395
1396 dprintk(1, "%s()\n", __func__);
1397
1398 mutex_lock(&priv->lock);
1399
1400 /* Avoid firmware reload on slow devices */
1401 if ((no_poweroff == 2 ||
1402 (no_poweroff == 0 &&
1403 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1404 (priv->cur_fw.type & BASE) != 0) {
1405 /* force reset and firmware reload */
1406 priv->cur_fw.type = XC_POWERED_DOWN;
1407
1408 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1409 != XC_RESULT_SUCCESS) {
1410 printk(KERN_ERR
1411 "xc4000: %s() unable to shutdown tuner\n",
1412 __func__);
1413 ret = -EREMOTEIO;
1414 }
1415 xc_wait(20);
1416 }
1417
1418 mutex_unlock(&priv->lock);
1419
1420 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001421}
1422
1423static int xc4000_init(struct dvb_frontend *fe)
1424{
Davide Ferri8d009a02009-06-23 22:34:06 -03001425 dprintk(1, "%s()\n", __func__);
1426
Davide Ferri8d009a02009-06-23 22:34:06 -03001427 return 0;
1428}
1429
1430static int xc4000_release(struct dvb_frontend *fe)
1431{
1432 struct xc4000_priv *priv = fe->tuner_priv;
1433
1434 dprintk(1, "%s()\n", __func__);
1435
1436 mutex_lock(&xc4000_list_mutex);
1437
1438 if (priv)
1439 hybrid_tuner_release_state(priv);
1440
1441 mutex_unlock(&xc4000_list_mutex);
1442
1443 fe->tuner_priv = NULL;
1444
1445 return 0;
1446}
1447
1448static const struct dvb_tuner_ops xc4000_tuner_ops = {
1449 .info = {
1450 .name = "Xceive XC4000",
1451 .frequency_min = 1000000,
1452 .frequency_max = 1023000000,
1453 .frequency_step = 50000,
1454 },
1455
1456 .release = xc4000_release,
1457 .init = xc4000_init,
1458 .sleep = xc4000_sleep,
1459
1460 .set_params = xc4000_set_params,
1461 .set_analog_params = xc4000_set_analog_params,
1462 .get_frequency = xc4000_get_frequency,
1463 .get_bandwidth = xc4000_get_bandwidth,
1464 .get_status = xc4000_get_status
1465};
1466
1467struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1468 struct i2c_adapter *i2c,
1469 struct xc4000_config *cfg)
1470{
1471 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001472 int instance;
1473 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001474
Istvan Varga0b402132011-06-03 09:38:04 -03001475 if (cfg->card_type != XC4000_CARD_GENERIC) {
1476 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1477 cfg->i2c_address = 0x61;
1478 cfg->if_khz = 4560;
1479 } else { /* default to PCTV 340E */
1480 cfg->i2c_address = 0x61;
1481 cfg->if_khz = 5400;
1482 }
1483 }
1484
Davide Ferri8d009a02009-06-23 22:34:06 -03001485 dprintk(1, "%s(%d-%04x)\n", __func__,
1486 i2c ? i2c_adapter_id(i2c) : -1,
1487 cfg ? cfg->i2c_address : -1);
1488
1489 mutex_lock(&xc4000_list_mutex);
1490
1491 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1492 hybrid_tuner_instance_list,
1493 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001494 if (cfg->card_type != XC4000_CARD_GENERIC)
1495 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001496 switch (instance) {
1497 case 0:
1498 goto fail;
1499 break;
1500 case 1:
1501 /* new tuner instance */
1502 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001503 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001504 fe->tuner_priv = priv;
1505 break;
1506 default:
1507 /* existing tuner instance */
1508 fe->tuner_priv = priv;
1509 break;
1510 }
1511
Istvan Varga0b402132011-06-03 09:38:04 -03001512 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001513 /* If the IF hasn't been set yet, use the value provided by
1514 the caller (occurs in hybrid devices where the analog
1515 call to xc4000_attach occurs before the digital side) */
1516 priv->if_khz = cfg->if_khz;
1517 }
1518
1519 /* Check if firmware has been loaded. It is possible that another
1520 instance of the driver has loaded the firmware.
1521 */
1522
Istvan Varga027fd362011-06-04 12:04:51 -03001523 if (instance == 1) {
1524 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1525 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001526 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001527 } else {
1528 id = ((priv->cur_fw.type & BASE) != 0 ?
1529 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1530 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001531
1532 switch (id) {
1533 case XC_PRODUCT_ID_FW_LOADED:
1534 printk(KERN_INFO
1535 "xc4000: Successfully identified at address 0x%02x\n",
1536 cfg->i2c_address);
1537 printk(KERN_INFO
1538 "xc4000: Firmware has been loaded previously\n");
1539 break;
1540 case XC_PRODUCT_ID_FW_NOT_LOADED:
1541 printk(KERN_INFO
1542 "xc4000: Successfully identified at address 0x%02x\n",
1543 cfg->i2c_address);
1544 printk(KERN_INFO
1545 "xc4000: Firmware has not been loaded previously\n");
1546 break;
1547 default:
1548 printk(KERN_ERR
1549 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1550 cfg->i2c_address, id);
1551 goto fail;
1552 }
1553
1554 mutex_unlock(&xc4000_list_mutex);
1555
1556 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1557 sizeof(struct dvb_tuner_ops));
1558
Istvan Varga027fd362011-06-04 12:04:51 -03001559 if (instance == 1) {
1560 int ret;
1561 mutex_lock(&priv->lock);
1562 ret = xc4000_fwupload(fe);
1563 mutex_unlock(&priv->lock);
1564 if (ret != XC_RESULT_SUCCESS)
1565 goto fail2;
1566 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001567
Davide Ferri8d009a02009-06-23 22:34:06 -03001568 return fe;
1569fail:
1570 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001571fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001572 xc4000_release(fe);
1573 return NULL;
1574}
1575EXPORT_SYMBOL(xc4000_attach);
1576
1577MODULE_AUTHOR("Steven Toth, Davide Ferri");
1578MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1579MODULE_LICENSE("GPL");