blob: bf3f6f1664cd2b0e1f049250fe94ce40e1c243aa [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
Istvan Varga30f544e2011-06-04 12:12:42 -0300134#define XREG_SMOOTHEDCVBS 0x0E
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300135#define XREG_AMPLITUDE 0x10
Davide Ferri8d009a02009-06-23 22:34:06 -0300136
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300137/* Registers (Read-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300138#define XREG_ADC_ENV 0x00
139#define XREG_QUALITY 0x01
140#define XREG_FRAME_LINES 0x02
141#define XREG_HSYNC_FREQ 0x03
142#define XREG_LOCK 0x04
143#define XREG_FREQ_ERROR 0x05
144#define XREG_SNR 0x06
145#define XREG_VERSION 0x07
146#define XREG_PRODUCT_ID 0x08
Davide Ferri8d009a02009-06-23 22:34:06 -0300147
148/*
149 Basic firmware description. This will remain with
150 the driver for documentation purposes.
151
152 This represents an I2C firmware file encoded as a
153 string of unsigned char. Format is as follows:
154
155 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
156 char[1 ]=len0_LSB -> length of first write transaction
157 char[2 ]=data0 -> first byte to be sent
158 char[3 ]=data1
159 char[4 ]=data2
160 char[ ]=...
161 char[M ]=dataN -> last byte to be sent
162 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
163 char[M+2]=len1_LSB -> length of second write transaction
164 char[M+3]=data0
165 char[M+4]=data1
166 ...
167 etc.
168
169 The [len] value should be interpreted as follows:
170
171 len= len_MSB _ len_LSB
172 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
173 len=0000_0000_0000_0000 : Reset command: Do hardware reset
174 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
175 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
176
177 For the RESET and WAIT commands, the two following bytes will contain
178 immediately the length of the following transaction.
Davide Ferri8d009a02009-06-23 22:34:06 -0300179*/
Istvan Vargafbe4a292011-06-03 10:11:48 -0300180
Davide Ferri8d009a02009-06-23 22:34:06 -0300181struct XC_TV_STANDARD {
Istvan Vargafbe4a292011-06-03 10:11:48 -0300182 const char *Name;
183 u16 AudioMode;
184 u16 VideoMode;
Istvan Varga49110852011-06-03 10:55:24 -0300185 u16 int_freq;
Davide Ferri8d009a02009-06-23 22:34:06 -0300186};
187
188/* Tuner standards */
Devin Heitmuellered23db32009-10-05 01:27:14 -0300189#define XC4000_MN_NTSC_PAL_BTSC 0
190#define XC4000_MN_NTSC_PAL_A2 1
191#define XC4000_MN_NTSC_PAL_EIAJ 2
192#define XC4000_MN_NTSC_PAL_Mono 3
193#define XC4000_BG_PAL_A2 4
194#define XC4000_BG_PAL_NICAM 5
195#define XC4000_BG_PAL_MONO 6
196#define XC4000_I_PAL_NICAM 7
197#define XC4000_I_PAL_NICAM_MONO 8
198#define XC4000_DK_PAL_A2 9
199#define XC4000_DK_PAL_NICAM 10
200#define XC4000_DK_PAL_MONO 11
201#define XC4000_DK_SECAM_A2DK1 12
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300202#define XC4000_DK_SECAM_A2LDK3 13
203#define XC4000_DK_SECAM_A2MONO 14
Istvan Varga49110852011-06-03 10:55:24 -0300204#define XC4000_DK_SECAM_NICAM 15
205#define XC4000_L_SECAM_NICAM 16
206#define XC4000_LC_SECAM_NICAM 17
207#define XC4000_DTV6 18
208#define XC4000_DTV8 19
209#define XC4000_DTV7_8 20
210#define XC4000_DTV7 21
211#define XC4000_FM_Radio_INPUT2 22
212#define XC4000_FM_Radio_INPUT1 23
Davide Ferri8d009a02009-06-23 22:34:06 -0300213
Davide Ferri8d009a02009-06-23 22:34:06 -0300214static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
Istvan Varga49110852011-06-03 10:55:24 -0300215 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
216 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
217 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
218 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
219 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
220 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
221 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
222 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
223 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
224 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
225 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
226 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
227 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
228 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
229 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
230 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
231 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
232 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
233 {"DTV6", 0x00C0, 0x8002, 0},
234 {"DTV8", 0x00C0, 0x800B, 0},
235 {"DTV7/8", 0x00C0, 0x801B, 0},
236 {"DTV7", 0x00C0, 0x8007, 0},
237 {"FM Radio-INPUT2", 0x0008, 0x9800,10700},
238 {"FM Radio-INPUT1", 0x0008, 0x9000,10700}
Davide Ferri8d009a02009-06-23 22:34:06 -0300239};
240
Davide Ferri8d009a02009-06-23 22:34:06 -0300241static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
242static int xc4000_TunerReset(struct dvb_frontend *fe);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300243static void xc_debug_dump(struct xc4000_priv *priv);
Davide Ferri8d009a02009-06-23 22:34:06 -0300244
245static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
246{
247 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
248 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300249 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300250 if (priv->ignore_i2c_write_errors == 0) {
251 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
252 len);
253 if (len == 4) {
254 printk("bytes %02x %02x %02x %02x\n", buf[0],
255 buf[1], buf[2], buf[3]);
256 }
257 return XC_RESULT_I2C_WRITE_FAILURE;
258 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300259 }
260 return XC_RESULT_SUCCESS;
261}
262
Davide Ferri8d009a02009-06-23 22:34:06 -0300263static void xc_wait(int wait_ms)
264{
265 msleep(wait_ms);
266}
267
268static int xc4000_TunerReset(struct dvb_frontend *fe)
269{
270 struct xc4000_priv *priv = fe->tuner_priv;
271 int ret;
272
273 dprintk(1, "%s()\n", __func__);
274
275 if (fe->callback) {
276 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
277 fe->dvb->priv :
278 priv->i2c_props.adap->algo_data,
279 DVB_FRONTEND_COMPONENT_TUNER,
280 XC4000_TUNER_RESET, 0);
281 if (ret) {
282 printk(KERN_ERR "xc4000: reset failed\n");
283 return XC_RESULT_RESET_FAILURE;
284 }
285 } else {
286 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
287 return XC_RESULT_RESET_FAILURE;
288 }
289 return XC_RESULT_SUCCESS;
290}
291
292static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
293{
294 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300295 int result;
296
297 buf[0] = (regAddr >> 8) & 0xFF;
298 buf[1] = regAddr & 0xFF;
299 buf[2] = (i2cData >> 8) & 0xFF;
300 buf[3] = i2cData & 0xFF;
301 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300302
303 return result;
304}
305
306static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
307{
308 struct xc4000_priv *priv = fe->tuner_priv;
309
310 int i, nbytes_to_send, result;
311 unsigned int len, pos, index;
312 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
313
314 index = 0;
315 while ((i2c_sequence[index] != 0xFF) ||
316 (i2c_sequence[index + 1] != 0xFF)) {
317 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
318 if (len == 0x0000) {
319 /* RESET command */
320 result = xc4000_TunerReset(fe);
321 index += 2;
322 if (result != XC_RESULT_SUCCESS)
323 return result;
324 } else if (len & 0x8000) {
325 /* WAIT command */
326 xc_wait(len & 0x7FFF);
327 index += 2;
328 } else {
329 /* Send i2c data whilst ensuring individual transactions
330 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
331 */
332 index += 2;
333 buf[0] = i2c_sequence[index];
334 buf[1] = i2c_sequence[index + 1];
335 pos = 2;
336 while (pos < len) {
337 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
338 nbytes_to_send =
339 XC_MAX_I2C_WRITE_LENGTH;
340 else
341 nbytes_to_send = (len - pos + 2);
342 for (i = 2; i < nbytes_to_send; i++) {
343 buf[i] = i2c_sequence[index + pos +
344 i - 2];
345 }
346 result = xc_send_i2c_data(priv, buf,
347 nbytes_to_send);
348
349 if (result != XC_RESULT_SUCCESS)
350 return result;
351
352 pos += nbytes_to_send - 2;
353 }
354 index += len;
355 }
356 }
357 return XC_RESULT_SUCCESS;
358}
359
Davide Ferri8d009a02009-06-23 22:34:06 -0300360static int xc_SetTVStandard(struct xc4000_priv *priv,
361 u16 VideoMode, u16 AudioMode)
362{
363 int ret;
364 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
365 dprintk(1, "%s() Standard = %s\n",
366 __func__,
367 XC4000_Standard[priv->video_standard].Name);
368
Devin Heitmueller799ed112009-10-04 23:09:18 -0300369 /* Don't complain when the request fails because of i2c stretching */
370 priv->ignore_i2c_write_errors = 1;
371
Davide Ferri8d009a02009-06-23 22:34:06 -0300372 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
373 if (ret == XC_RESULT_SUCCESS)
374 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
375
Devin Heitmueller799ed112009-10-04 23:09:18 -0300376 priv->ignore_i2c_write_errors = 0;
377
Davide Ferri8d009a02009-06-23 22:34:06 -0300378 return ret;
379}
380
381static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
382{
383 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
384 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
385
386 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
387 rf_mode = XC_RF_MODE_CABLE;
388 printk(KERN_ERR
389 "%s(), Invalid mode, defaulting to CABLE",
390 __func__);
391 }
392 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
393}
394
395static const struct dvb_tuner_ops xc4000_tuner_ops;
396
397static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
398{
399 u16 freq_code;
400
401 dprintk(1, "%s(%u)\n", __func__, freq_hz);
402
403 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
404 (freq_hz < xc4000_tuner_ops.info.frequency_min))
405 return XC_RESULT_OUT_OF_RANGE;
406
407 freq_code = (u16)(freq_hz / 15625);
408
409 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
410 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
411 only be used for fast scanning for channel lock) */
412 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
413}
414
Davide Ferri8d009a02009-06-23 22:34:06 -0300415static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
416{
417 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
418}
419
420static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
421{
422 int result;
423 u16 regData;
424 u32 tmp;
425
426 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
427 if (result != XC_RESULT_SUCCESS)
428 return result;
429
Istvan Varga1368ceb2011-06-03 12:27:30 -0300430 tmp = (u32)regData & 0xFFFFU;
431 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
432 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300433 return result;
434}
435
436static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
437{
438 return xc4000_readreg(priv, XREG_LOCK, lock_status);
439}
440
441static int xc_get_version(struct xc4000_priv *priv,
442 u8 *hw_majorversion, u8 *hw_minorversion,
443 u8 *fw_majorversion, u8 *fw_minorversion)
444{
445 u16 data;
446 int result;
447
448 result = xc4000_readreg(priv, XREG_VERSION, &data);
449 if (result != XC_RESULT_SUCCESS)
450 return result;
451
452 (*hw_majorversion) = (data >> 12) & 0x0F;
453 (*hw_minorversion) = (data >> 8) & 0x0F;
454 (*fw_majorversion) = (data >> 4) & 0x0F;
455 (*fw_minorversion) = data & 0x0F;
456
457 return 0;
458}
459
Davide Ferri8d009a02009-06-23 22:34:06 -0300460static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
461{
462 u16 regData;
463 int result;
464
465 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
466 if (result != XC_RESULT_SUCCESS)
467 return result;
468
469 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
470 return result;
471}
472
473static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
474{
475 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
476}
477
478static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
479{
480 return xc4000_readreg(priv, XREG_QUALITY, quality);
481}
482
483static u16 WaitForLock(struct xc4000_priv *priv)
484{
485 u16 lockState = 0;
486 int watchDogCount = 40;
487
488 while ((lockState == 0) && (watchDogCount > 0)) {
489 xc_get_lock_status(priv, &lockState);
490 if (lockState != 1) {
491 xc_wait(5);
492 watchDogCount--;
493 }
494 }
495 return lockState;
496}
497
498#define XC_TUNE_ANALOG 0
499#define XC_TUNE_DIGITAL 1
500static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
501{
Istvan Vargafbe4a292011-06-03 10:11:48 -0300502 int found = 0;
503 int result = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300504
505 dprintk(1, "%s(%u)\n", __func__, freq_hz);
506
Devin Heitmueller799ed112009-10-04 23:09:18 -0300507 /* Don't complain when the request fails because of i2c stretching */
508 priv->ignore_i2c_write_errors = 1;
509 result = xc_set_RF_frequency(priv, freq_hz);
510 priv->ignore_i2c_write_errors = 0;
511
512 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300513 return 0;
514
515 if (mode == XC_TUNE_ANALOG) {
516 if (WaitForLock(priv) == 1)
517 found = 1;
518 }
519
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300520 /* Wait for stats to stabilize.
521 * Frame Lines needs two frame times after initial lock
522 * before it is valid.
523 */
524 xc_wait(debug ? 100 : 10);
525
526 if (debug)
527 xc_debug_dump(priv);
528
Davide Ferri8d009a02009-06-23 22:34:06 -0300529 return found;
530}
531
532static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
533{
534 u8 buf[2] = { reg >> 8, reg & 0xff };
535 u8 bval[2] = { 0, 0 };
536 struct i2c_msg msg[2] = {
537 { .addr = priv->i2c_props.addr,
538 .flags = 0, .buf = &buf[0], .len = 2 },
539 { .addr = priv->i2c_props.addr,
540 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
541 };
542
543 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
544 printk(KERN_WARNING "xc4000: I2C read failed\n");
545 return -EREMOTEIO;
546 }
547
548 *val = (bval[0] << 8) | bval[1];
549 return XC_RESULT_SUCCESS;
550}
551
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300552#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300553static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
554{
555 if (type & BASE)
556 printk("BASE ");
557 if (type & INIT1)
558 printk("INIT1 ");
559 if (type & F8MHZ)
560 printk("F8MHZ ");
561 if (type & MTS)
562 printk("MTS ");
563 if (type & D2620)
564 printk("D2620 ");
565 if (type & D2633)
566 printk("D2633 ");
567 if (type & DTV6)
568 printk("DTV6 ");
569 if (type & QAM)
570 printk("QAM ");
571 if (type & DTV7)
572 printk("DTV7 ");
573 if (type & DTV78)
574 printk("DTV78 ");
575 if (type & DTV8)
576 printk("DTV8 ");
577 if (type & FM)
578 printk("FM ");
579 if (type & INPUT1)
580 printk("INPUT1 ");
581 if (type & LCD)
582 printk("LCD ");
583 if (type & NOGD)
584 printk("NOGD ");
585 if (type & MONO)
586 printk("MONO ");
587 if (type & ATSC)
588 printk("ATSC ");
589 if (type & IF)
590 printk("IF ");
591 if (type & LG60)
592 printk("LG60 ");
593 if (type & ATI638)
594 printk("ATI638 ");
595 if (type & OREN538)
596 printk("OREN538 ");
597 if (type & OREN36)
598 printk("OREN36 ");
599 if (type & TOYOTA388)
600 printk("TOYOTA388 ");
601 if (type & TOYOTA794)
602 printk("TOYOTA794 ");
603 if (type & DIBCOM52)
604 printk("DIBCOM52 ");
605 if (type & ZARLINK456)
606 printk("ZARLINK456 ");
607 if (type & CHINA)
608 printk("CHINA ");
609 if (type & F6MHZ)
610 printk("F6MHZ ");
611 if (type & INPUT2)
612 printk("INPUT2 ");
613 if (type & SCODE)
614 printk("SCODE ");
615 if (type & HAS_IF)
616 printk("HAS_IF_%d ", int_freq);
617}
618
Devin Heitmueller11091a32009-07-20 00:54:57 -0300619static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
620 v4l2_std_id *id)
621{
622 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300623 int i, best_i = -1;
624 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300625
Devin Heitmueller11091a32009-07-20 00:54:57 -0300626 if (!priv->firm) {
627 printk("Error! firmware not loaded\n");
628 return -EINVAL;
629 }
630
631 if (((type & ~SCODE) == 0) && (*id == 0))
632 *id = V4L2_STD_PAL;
633
Devin Heitmueller11091a32009-07-20 00:54:57 -0300634 /* Seek for generic video standard match */
635 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300636 v4l2_std_id id_diff_mask =
637 (priv->firm[i].id ^ (*id)) & (*id);
638 unsigned int type_diff_mask =
639 (priv->firm[i].type ^ type)
640 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
641 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300642
Istvan Varga3db95702011-06-04 11:52:34 -0300643 if (type_diff_mask
644 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300645 continue;
646
Istvan Varga3db95702011-06-04 11:52:34 -0300647 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
648 if (!nr_diffs) /* Supports all the requested standards */
649 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300650
Istvan Varga3db95702011-06-04 11:52:34 -0300651 if (nr_diffs < best_nr_diffs) {
652 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300653 best_i = i;
654 }
655 }
656
Istvan Varga3db95702011-06-04 11:52:34 -0300657 /* FIXME: Would make sense to seek for type "hint" match ? */
658 if (best_i < 0) {
659 i = -ENOENT;
660 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300661 }
662
Istvan Varga3db95702011-06-04 11:52:34 -0300663 if (best_nr_diffs > 0U) {
664 printk("Selecting best matching firmware (%u bits differ) for "
665 "type=", best_nr_diffs);
666 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
667 i = best_i;
668 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300669
670found:
671 *id = priv->firm[i].id;
672
673ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300674 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300675 printk("%s firmware for type=", (i < 0) ? "Can't find" :
676 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300677 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300678 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
679 }
680 return i;
681}
682
683static int load_firmware(struct dvb_frontend *fe, unsigned int type,
684 v4l2_std_id *id)
685{
686 struct xc4000_priv *priv = fe->tuner_priv;
687 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300688 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300689
Devin Heitmueller11091a32009-07-20 00:54:57 -0300690 pos = seek_firmware(fe, type, id);
691 if (pos < 0)
692 return pos;
693
Devin Heitmueller11091a32009-07-20 00:54:57 -0300694 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300695
Devin Heitmueller799ed112009-10-04 23:09:18 -0300696 /* Don't complain when the request fails because of i2c stretching */
697 priv->ignore_i2c_write_errors = 1;
698
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300699 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300700
Devin Heitmueller799ed112009-10-04 23:09:18 -0300701 priv->ignore_i2c_write_errors = 0;
702
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300703 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300704}
705
Davide Ferri8d009a02009-06-23 22:34:06 -0300706static int xc4000_fwupload(struct dvb_frontend *fe)
707{
708 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300709 const struct firmware *fw = NULL;
710 const unsigned char *p, *endp;
711 int rc = 0;
712 int n, n_array;
713 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300714 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300715
Istvan Vargafa285bc2011-06-04 11:48:16 -0300716 if (firmware_name[0] != '\0')
717 fname = firmware_name;
718 else
719 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300720
721 printk("Reading firmware %s\n", fname);
722 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
723 if (rc < 0) {
724 if (rc == -ENOENT)
725 printk("Error: firmware %s not found.\n",
726 fname);
727 else
728 printk("Error %d while requesting firmware %s \n",
729 rc, fname);
730
731 return rc;
732 }
733 p = fw->data;
734 endp = p + fw->size;
735
736 if (fw->size < sizeof(name) - 1 + 2 + 2) {
737 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300738 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300739 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300740 }
741
Devin Heitmueller11091a32009-07-20 00:54:57 -0300742 memcpy(name, p, sizeof(name) - 1);
743 name[sizeof(name) - 1] = 0;
744 p += sizeof(name) - 1;
745
746 priv->firm_version = get_unaligned_le16(p);
747 p += 2;
748
749 n_array = get_unaligned_le16(p);
750 p += 2;
751
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300752 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
753 n_array, fname, name,
754 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300755
756 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
757 if (priv->firm == NULL) {
758 printk("Not enough memory to load firmware file.\n");
759 rc = -ENOMEM;
760 goto err;
761 }
762 priv->firm_size = n_array;
763
764 n = -1;
765 while (p < endp) {
766 __u32 type, size;
767 v4l2_std_id id;
768 __u16 int_freq = 0;
769
770 n++;
771 if (n >= n_array) {
772 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300773 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300774 goto corrupt;
775 }
776
777 /* Checks if there's enough bytes to read */
778 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
779 goto header;
780
781 type = get_unaligned_le32(p);
782 p += sizeof(type);
783
784 id = get_unaligned_le64(p);
785 p += sizeof(id);
786
787 if (type & HAS_IF) {
788 int_freq = get_unaligned_le16(p);
789 p += sizeof(int_freq);
790 if (endp - p < sizeof(size))
791 goto header;
792 }
793
794 size = get_unaligned_le32(p);
795 p += sizeof(size);
796
797 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300798 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300799 "(size=%d, expected %d)\n",
800 type, (unsigned long long)id,
801 (unsigned)(endp - p), size);
802 goto corrupt;
803 }
804
805 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
806 if (priv->firm[n].ptr == NULL) {
807 printk("Not enough memory to load firmware file.\n");
808 rc = -ENOMEM;
809 goto err;
810 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300811
Devin Heitmueller11091a32009-07-20 00:54:57 -0300812 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300813 printk("Reading firmware type ");
814 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300815 printk("(%x), id %llx, size=%d.\n",
816 type, (unsigned long long)id, size);
817 }
818
819 memcpy(priv->firm[n].ptr, p, size);
820 priv->firm[n].type = type;
821 priv->firm[n].id = id;
822 priv->firm[n].size = size;
823 priv->firm[n].int_freq = int_freq;
824
825 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300826 }
827
Devin Heitmueller11091a32009-07-20 00:54:57 -0300828 if (n + 1 != priv->firm_size) {
829 printk("Firmware file is incomplete!\n");
830 goto corrupt;
831 }
832
833 goto done;
834
835header:
836 printk("Firmware header is incomplete!\n");
837corrupt:
838 rc = -EINVAL;
839 printk("Error: firmware file is corrupted!\n");
840
841err:
842 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300843
844done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300845 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300846 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300847 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300848
849 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300850}
851
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300852static int load_scode(struct dvb_frontend *fe, unsigned int type,
853 v4l2_std_id *id, __u16 int_freq, int scode)
854{
855 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300856 int pos, rc;
857 unsigned char *p;
858 u8 scode_buf[13];
859 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300860
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300861 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300862
863 if (!int_freq) {
864 pos = seek_firmware(fe, type, id);
865 if (pos < 0)
866 return pos;
867 } else {
868 for (pos = 0; pos < priv->firm_size; pos++) {
869 if ((priv->firm[pos].int_freq == int_freq) &&
870 (priv->firm[pos].type & HAS_IF))
871 break;
872 }
873 if (pos == priv->firm_size)
874 return -ENOENT;
875 }
876
877 p = priv->firm[pos].ptr;
878
Istvan Vargaffce6262011-06-04 11:56:18 -0300879 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
880 return -EINVAL;
881 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300882
883 tuner_info("Loading SCODE for type=");
884 dump_firm_type_and_int_freq(priv->firm[pos].type,
885 priv->firm[pos].int_freq);
886 printk("(%x), id %016llx.\n", priv->firm[pos].type,
887 (unsigned long long)*id);
888
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300889 scode_buf[0] = 0x00;
890 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300891
892 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300893 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
894 if (rc < 0) {
895 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300896 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300897 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300898
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300899 rc = xc_send_i2c_data(priv, scode_buf, 13);
900 if (rc != XC_RESULT_SUCCESS) {
901 /* Even if the send failed, make sure we set back to indirect
902 mode */
903 printk("Failed to set scode %d\n", rc);
904 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300905
906 /* Switch back to indirect-mode */
907 memset(indirect_mode, 0, sizeof(indirect_mode));
908 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300909 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
910 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300911
912 return 0;
913}
914
915static int check_firmware(struct dvb_frontend *fe, unsigned int type,
916 v4l2_std_id std, __u16 int_freq)
917{
918 struct xc4000_priv *priv = fe->tuner_priv;
919 struct firmware_properties new_fw;
920 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300921 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300922 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300923 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300924
925 dprintk(1, "%s called\n", __func__);
926
927 if (!priv->firm) {
928 rc = xc4000_fwupload(fe);
929 if (rc < 0)
930 return rc;
931 }
932
933#ifdef DJH_DEBUG
934 if (priv->ctrl.mts && !(type & FM))
935 type |= MTS;
936#endif
937
938retry:
939 new_fw.type = type;
940 new_fw.id = std;
941 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300942 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300943 new_fw.scode_nr = 0;
944 new_fw.int_freq = int_freq;
945
946 dprintk(1, "checking firmware, user requested type=");
947 if (debug) {
948 dump_firm_type(new_fw.type);
949 printk("(%x), id %016llx, ", new_fw.type,
950 (unsigned long long)new_fw.std_req);
951 if (!int_freq) {
952 printk("scode_tbl ");
953#ifdef DJH_DEBUG
954 dump_firm_type(priv->ctrl.scode_table);
955 printk("(%x), ", priv->ctrl.scode_table);
956#endif
957 } else
958 printk("int_freq %d, ", new_fw.int_freq);
959 printk("scode_nr %d\n", new_fw.scode_nr);
960 }
961
962 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300963 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300964 dprintk(1, "BASE firmware not changed.\n");
965 goto skip_base;
966 }
967
968 /* Updating BASE - forget about all currently loaded firmware */
969 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
970
971 /* Reset is needed before loading firmware */
972 rc = xc4000_TunerReset(fe);
973 if (rc < 0)
974 goto fail;
975
976 /* BASE firmwares are all std0 */
977 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300978 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300979 if (rc < 0) {
980 printk("Error %d while loading base firmware\n", rc);
981 goto fail;
982 }
983
984 /* Load INIT1, if needed */
985 dprintk(1, "Load init1 firmware, if exists\n");
986
Istvan Varga595a83f2011-06-04 11:59:54 -0300987 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300988 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -0300989 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300990 if (rc < 0 && rc != -ENOENT) {
991 tuner_err("Error %d while loading init1 firmware\n",
992 rc);
993 goto fail;
994 }
995
996skip_base:
997 /*
998 * No need to reload standard specific firmware if base firmware
999 * was not reloaded and requested video standards have not changed.
1000 */
1001 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1002 priv->cur_fw.std_req == std) {
1003 dprintk(1, "Std-specific firmware already loaded.\n");
1004 goto skip_std_specific;
1005 }
1006
1007 /* Reloading std-specific firmware forces a SCODE update */
1008 priv->cur_fw.scode_table = 0;
1009
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001010 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001011 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001012
1013 if (rc < 0)
1014 goto fail;
1015
1016skip_std_specific:
1017 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1018 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1019 dprintk(1, "SCODE firmware already loaded.\n");
1020 goto check_device;
1021 }
1022
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001023 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001024 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1025 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001026 if (rc != XC_RESULT_SUCCESS)
1027 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001028
1029check_device:
1030 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1031
Devin Heitmueller799ed112009-10-04 23:09:18 -03001032 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001033 &fw_minor) != XC_RESULT_SUCCESS) {
1034 printk("Unable to read tuner registers.\n");
1035 goto fail;
1036 }
1037
1038 dprintk(1, "Device is Xceive %d version %d.%d, "
1039 "firmware version %d.%d\n",
1040 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1041
1042 /* Check firmware version against what we downloaded. */
1043#ifdef DJH_DEBUG
1044 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1045 printk("Incorrect readback of firmware version %x.\n",
1046 (version & 0xff));
1047 goto fail;
1048 }
1049#endif
1050
1051 /* Check that the tuner hardware model remains consistent over time. */
1052 if (priv->hwmodel == 0 && hwmodel == 4000) {
1053 priv->hwmodel = hwmodel;
1054 priv->hwvers = version & 0xff00;
1055 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1056 priv->hwvers != (version & 0xff00)) {
1057 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001058 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001059 goto fail;
1060 }
1061
1062 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1063
1064 /*
1065 * By setting BASE in cur_fw.type only after successfully loading all
1066 * firmwares, we can:
1067 * 1. Identify that BASE firmware with type=0 has been loaded;
1068 * 2. Tell whether BASE firmware was just changed the next time through.
1069 */
1070 priv->cur_fw.type |= BASE;
1071
1072 return 0;
1073
1074fail:
1075 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1076 if (!is_retry) {
1077 msleep(50);
1078 is_retry = 1;
1079 dprintk(1, "Retrying firmware load\n");
1080 goto retry;
1081 }
1082
1083 if (rc == -ENOENT)
1084 rc = -EINVAL;
1085 return rc;
1086}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001087
Davide Ferri8d009a02009-06-23 22:34:06 -03001088static void xc_debug_dump(struct xc4000_priv *priv)
1089{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001090 u16 adc_envelope;
1091 u32 freq_error_hz = 0;
1092 u16 lock_status;
1093 u32 hsync_freq_hz = 0;
1094 u16 frame_lines;
1095 u16 quality;
1096 u8 hw_majorversion = 0, hw_minorversion = 0;
1097 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001098
Istvan Vargafbe4a292011-06-03 10:11:48 -03001099 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001100 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1101
1102 xc_get_frequency_error(priv, &freq_error_hz);
1103 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1104
Istvan Vargafbe4a292011-06-03 10:11:48 -03001105 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001106 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1107 lock_status);
1108
Istvan Vargafbe4a292011-06-03 10:11:48 -03001109 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1110 &fw_majorversion, &fw_minorversion);
Davide Ferri8d009a02009-06-23 22:34:06 -03001111 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1112 hw_majorversion, hw_minorversion,
1113 fw_majorversion, fw_minorversion);
1114
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001115 if (priv->video_standard < XC4000_DTV6) {
1116 xc_get_hsync_freq(priv, &hsync_freq_hz);
1117 dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
1118 hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001119
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001120 xc_get_frame_lines(priv, &frame_lines);
1121 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1122 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001123
Istvan Vargafbe4a292011-06-03 10:11:48 -03001124 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001125 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1126}
1127
1128static int xc4000_set_params(struct dvb_frontend *fe,
1129 struct dvb_frontend_parameters *params)
1130{
1131 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001132 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001133 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001134
Davide Ferri8d009a02009-06-23 22:34:06 -03001135 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1136
Istvan Varga56149422011-06-03 12:23:33 -03001137 mutex_lock(&priv->lock);
1138
Davide Ferri8d009a02009-06-23 22:34:06 -03001139 if (fe->ops.info.type == FE_ATSC) {
1140 dprintk(1, "%s() ATSC\n", __func__);
1141 switch (params->u.vsb.modulation) {
1142 case VSB_8:
1143 case VSB_16:
1144 dprintk(1, "%s() VSB modulation\n", __func__);
1145 priv->rf_mode = XC_RF_MODE_AIR;
1146 priv->freq_hz = params->frequency - 1750000;
1147 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001148 priv->video_standard = XC4000_DTV6;
1149 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001150 break;
1151 case QAM_64:
1152 case QAM_256:
1153 case QAM_AUTO:
1154 dprintk(1, "%s() QAM modulation\n", __func__);
1155 priv->rf_mode = XC_RF_MODE_CABLE;
1156 priv->freq_hz = params->frequency - 1750000;
1157 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001158 priv->video_standard = XC4000_DTV6;
1159 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001160 break;
1161 default:
Istvan Varga56149422011-06-03 12:23:33 -03001162 ret = -EINVAL;
1163 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001164 }
1165 } else if (fe->ops.info.type == FE_OFDM) {
1166 dprintk(1, "%s() OFDM\n", __func__);
1167 switch (params->u.ofdm.bandwidth) {
1168 case BANDWIDTH_6_MHZ:
1169 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001170 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001171 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001172 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001173 break;
1174 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001175 priv->bandwidth = BANDWIDTH_7_MHZ;
1176 priv->video_standard = XC4000_DTV7;
1177 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001178 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001179 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001180 case BANDWIDTH_8_MHZ:
1181 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001182 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001183 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001184 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001185 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001186 case BANDWIDTH_AUTO:
1187 if (params->frequency < 400000000) {
1188 priv->bandwidth = BANDWIDTH_7_MHZ;
1189 priv->freq_hz = params->frequency - 2250000;
1190 } else {
1191 priv->bandwidth = BANDWIDTH_8_MHZ;
1192 priv->freq_hz = params->frequency - 2750000;
1193 }
1194 priv->video_standard = XC4000_DTV7_8;
1195 type = DTV78;
1196 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001197 default:
1198 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001199 ret = -EINVAL;
1200 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001201 }
1202 priv->rf_mode = XC_RF_MODE_AIR;
1203 } else {
1204 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001205 ret = -EINVAL;
1206 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001207 }
1208
1209 dprintk(1, "%s() frequency=%d (compensated)\n",
1210 __func__, priv->freq_hz);
1211
Devin Heitmuellered23db32009-10-05 01:27:14 -03001212 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001213 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1214 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001215
Davide Ferri8d009a02009-06-23 22:34:06 -03001216 ret = xc_SetSignalSource(priv, priv->rf_mode);
1217 if (ret != XC_RESULT_SUCCESS) {
1218 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001219 "xc4000: xc_SetSignalSource(%d) failed\n",
1220 priv->rf_mode);
1221 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001222 } else {
1223 u16 video_mode, audio_mode;
1224 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1225 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1226 if (type == DTV6 && priv->firm_version != 0x0102)
1227 video_mode |= 0x0001;
1228 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1229 if (ret != XC_RESULT_SUCCESS) {
1230 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1231 /* DJH - do not return when it fails... */
1232 /* goto fail; */
1233 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001234 }
1235
Istvan Varga30f544e2011-06-04 12:12:42 -03001236 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1237 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1238 ret = 0;
1239 if (xc_write_reg(priv, XREG_AMPLITUDE,
1240 (priv->firm_version == 0x0102 ? 132 : 134))
1241 != 0)
1242 ret = -EREMOTEIO;
1243 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1244 ret = -EREMOTEIO;
1245 if (ret != 0) {
1246 printk(KERN_ERR "xc4000: setting registers failed\n");
1247 /* goto fail; */
1248 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001249 }
Istvan Varga30f544e2011-06-04 12:12:42 -03001250
Davide Ferri8d009a02009-06-23 22:34:06 -03001251 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
1252
Istvan Varga56149422011-06-03 12:23:33 -03001253 ret = 0;
1254
1255fail:
1256 mutex_unlock(&priv->lock);
1257
1258 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001259}
1260
Davide Ferri8d009a02009-06-23 22:34:06 -03001261static int xc4000_set_analog_params(struct dvb_frontend *fe,
1262 struct analog_parameters *params)
1263{
1264 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga56149422011-06-03 12:23:33 -03001265 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001266
Davide Ferri8d009a02009-06-23 22:34:06 -03001267 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1268 __func__, params->frequency);
1269
Istvan Varga56149422011-06-03 12:23:33 -03001270 mutex_lock(&priv->lock);
1271
Davide Ferri8d009a02009-06-23 22:34:06 -03001272 /* Fix me: it could be air. */
1273 priv->rf_mode = params->mode;
1274 if (params->mode > XC_RF_MODE_CABLE)
1275 priv->rf_mode = XC_RF_MODE_CABLE;
1276
1277 /* params->frequency is in units of 62.5khz */
1278 priv->freq_hz = params->frequency * 62500;
1279
1280 /* FIX ME: Some video standards may have several possible audio
1281 standards. We simply default to one of them here.
1282 */
1283 if (params->std & V4L2_STD_MN) {
1284 /* default to BTSC audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001285 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
Davide Ferri8d009a02009-06-23 22:34:06 -03001286 goto tune_channel;
1287 }
1288
1289 if (params->std & V4L2_STD_PAL_BG) {
1290 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001291 priv->video_standard = XC4000_BG_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001292 goto tune_channel;
1293 }
1294
1295 if (params->std & V4L2_STD_PAL_I) {
1296 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001297 priv->video_standard = XC4000_I_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001298 goto tune_channel;
1299 }
1300
1301 if (params->std & V4L2_STD_PAL_DK) {
1302 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001303 priv->video_standard = XC4000_DK_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001304 goto tune_channel;
1305 }
1306
1307 if (params->std & V4L2_STD_SECAM_DK) {
1308 /* default to A2 DK1 audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001309 priv->video_standard = XC4000_DK_SECAM_A2DK1;
Davide Ferri8d009a02009-06-23 22:34:06 -03001310 goto tune_channel;
1311 }
1312
1313 if (params->std & V4L2_STD_SECAM_L) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001314 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001315 goto tune_channel;
1316 }
1317
1318 if (params->std & V4L2_STD_SECAM_LC) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001319 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001320 goto tune_channel;
1321 }
1322
1323tune_channel:
Devin Heitmuellered23db32009-10-05 01:27:14 -03001324
1325 /* FIXME - firmware type not being set properly */
Istvan Varga56149422011-06-03 12:23:33 -03001326 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1327 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001328
Davide Ferri8d009a02009-06-23 22:34:06 -03001329 ret = xc_SetSignalSource(priv, priv->rf_mode);
1330 if (ret != XC_RESULT_SUCCESS) {
1331 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001332 "xc4000: xc_SetSignalSource(%d) failed\n",
1333 priv->rf_mode);
1334 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001335 } else {
1336 u16 video_mode, audio_mode;
1337 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1338 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1339 if (priv->video_standard < XC4000_BG_PAL_A2) {
1340 if (0 /*type & NOGD*/)
1341 video_mode &= 0xFF7F;
1342 } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
1343 if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
1344 priv->firm_version == 0x0102)
1345 video_mode &= 0xFEFF;
1346 }
1347 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1348 if (ret != XC_RESULT_SUCCESS) {
1349 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1350 goto fail;
1351 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001352 }
1353
Istvan Varga30f544e2011-06-04 12:12:42 -03001354 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1355 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1356 ret = 0;
1357 if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
1358 ret = -EREMOTEIO;
1359 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1360 ret = -EREMOTEIO;
1361 if (ret != 0) {
1362 printk(KERN_ERR "xc4000: setting registers failed\n");
1363 goto fail;
1364 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001365 }
1366
1367 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
1368
Istvan Varga56149422011-06-03 12:23:33 -03001369 ret = 0;
1370
1371fail:
1372 mutex_unlock(&priv->lock);
1373
1374 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001375}
1376
1377static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1378{
1379 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001380
Davide Ferri8d009a02009-06-23 22:34:06 -03001381 *freq = priv->freq_hz;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001382
1383 if (debug) {
1384 mutex_lock(&priv->lock);
1385 if ((priv->cur_fw.type
1386 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1387 u16 snr = 0;
1388 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1389 mutex_unlock(&priv->lock);
1390 dprintk(1, "%s() freq = %u, SNR = %d\n",
1391 __func__, *freq, snr);
1392 return 0;
1393 }
1394 }
1395 mutex_unlock(&priv->lock);
1396 }
1397
1398 dprintk(1, "%s()\n", __func__);
1399
Davide Ferri8d009a02009-06-23 22:34:06 -03001400 return 0;
1401}
1402
1403static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1404{
1405 struct xc4000_priv *priv = fe->tuner_priv;
1406 dprintk(1, "%s()\n", __func__);
1407
1408 *bw = priv->bandwidth;
1409 return 0;
1410}
1411
1412static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1413{
1414 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001415 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001416
Istvan Varga56149422011-06-03 12:23:33 -03001417 mutex_lock(&priv->lock);
1418
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001419 if (priv->cur_fw.type & BASE)
1420 xc_get_lock_status(priv, &lock_status);
1421
1422 *status = (lock_status == 1 ?
1423 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1424 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1425 *status &= (~TUNER_STATUS_STEREO);
Davide Ferri8d009a02009-06-23 22:34:06 -03001426
Istvan Varga56149422011-06-03 12:23:33 -03001427 mutex_unlock(&priv->lock);
1428
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001429 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001430
1431 return 0;
1432}
1433
Davide Ferri8d009a02009-06-23 22:34:06 -03001434static int xc4000_sleep(struct dvb_frontend *fe)
1435{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001436 struct xc4000_priv *priv = fe->tuner_priv;
1437 int ret = XC_RESULT_SUCCESS;
1438
1439 dprintk(1, "%s()\n", __func__);
1440
1441 mutex_lock(&priv->lock);
1442
1443 /* Avoid firmware reload on slow devices */
1444 if ((no_poweroff == 2 ||
1445 (no_poweroff == 0 &&
1446 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1447 (priv->cur_fw.type & BASE) != 0) {
1448 /* force reset and firmware reload */
1449 priv->cur_fw.type = XC_POWERED_DOWN;
1450
1451 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1452 != XC_RESULT_SUCCESS) {
1453 printk(KERN_ERR
1454 "xc4000: %s() unable to shutdown tuner\n",
1455 __func__);
1456 ret = -EREMOTEIO;
1457 }
1458 xc_wait(20);
1459 }
1460
1461 mutex_unlock(&priv->lock);
1462
1463 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001464}
1465
1466static int xc4000_init(struct dvb_frontend *fe)
1467{
Davide Ferri8d009a02009-06-23 22:34:06 -03001468 dprintk(1, "%s()\n", __func__);
1469
Davide Ferri8d009a02009-06-23 22:34:06 -03001470 return 0;
1471}
1472
1473static int xc4000_release(struct dvb_frontend *fe)
1474{
1475 struct xc4000_priv *priv = fe->tuner_priv;
1476
1477 dprintk(1, "%s()\n", __func__);
1478
1479 mutex_lock(&xc4000_list_mutex);
1480
1481 if (priv)
1482 hybrid_tuner_release_state(priv);
1483
1484 mutex_unlock(&xc4000_list_mutex);
1485
1486 fe->tuner_priv = NULL;
1487
1488 return 0;
1489}
1490
1491static const struct dvb_tuner_ops xc4000_tuner_ops = {
1492 .info = {
1493 .name = "Xceive XC4000",
1494 .frequency_min = 1000000,
1495 .frequency_max = 1023000000,
1496 .frequency_step = 50000,
1497 },
1498
1499 .release = xc4000_release,
1500 .init = xc4000_init,
1501 .sleep = xc4000_sleep,
1502
1503 .set_params = xc4000_set_params,
1504 .set_analog_params = xc4000_set_analog_params,
1505 .get_frequency = xc4000_get_frequency,
1506 .get_bandwidth = xc4000_get_bandwidth,
1507 .get_status = xc4000_get_status
1508};
1509
1510struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1511 struct i2c_adapter *i2c,
1512 struct xc4000_config *cfg)
1513{
1514 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001515 int instance;
1516 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001517
Istvan Varga0b402132011-06-03 09:38:04 -03001518 if (cfg->card_type != XC4000_CARD_GENERIC) {
1519 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1520 cfg->i2c_address = 0x61;
1521 cfg->if_khz = 4560;
1522 } else { /* default to PCTV 340E */
1523 cfg->i2c_address = 0x61;
1524 cfg->if_khz = 5400;
1525 }
1526 }
1527
Davide Ferri8d009a02009-06-23 22:34:06 -03001528 dprintk(1, "%s(%d-%04x)\n", __func__,
1529 i2c ? i2c_adapter_id(i2c) : -1,
1530 cfg ? cfg->i2c_address : -1);
1531
1532 mutex_lock(&xc4000_list_mutex);
1533
1534 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1535 hybrid_tuner_instance_list,
1536 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001537 if (cfg->card_type != XC4000_CARD_GENERIC)
1538 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001539 switch (instance) {
1540 case 0:
1541 goto fail;
1542 break;
1543 case 1:
1544 /* new tuner instance */
1545 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001546 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001547 fe->tuner_priv = priv;
1548 break;
1549 default:
1550 /* existing tuner instance */
1551 fe->tuner_priv = priv;
1552 break;
1553 }
1554
Istvan Varga0b402132011-06-03 09:38:04 -03001555 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001556 /* If the IF hasn't been set yet, use the value provided by
1557 the caller (occurs in hybrid devices where the analog
1558 call to xc4000_attach occurs before the digital side) */
1559 priv->if_khz = cfg->if_khz;
1560 }
1561
1562 /* Check if firmware has been loaded. It is possible that another
1563 instance of the driver has loaded the firmware.
1564 */
1565
Istvan Varga027fd362011-06-04 12:04:51 -03001566 if (instance == 1) {
1567 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1568 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001569 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001570 } else {
1571 id = ((priv->cur_fw.type & BASE) != 0 ?
1572 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1573 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001574
1575 switch (id) {
1576 case XC_PRODUCT_ID_FW_LOADED:
1577 printk(KERN_INFO
1578 "xc4000: Successfully identified at address 0x%02x\n",
1579 cfg->i2c_address);
1580 printk(KERN_INFO
1581 "xc4000: Firmware has been loaded previously\n");
1582 break;
1583 case XC_PRODUCT_ID_FW_NOT_LOADED:
1584 printk(KERN_INFO
1585 "xc4000: Successfully identified at address 0x%02x\n",
1586 cfg->i2c_address);
1587 printk(KERN_INFO
1588 "xc4000: Firmware has not been loaded previously\n");
1589 break;
1590 default:
1591 printk(KERN_ERR
1592 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1593 cfg->i2c_address, id);
1594 goto fail;
1595 }
1596
1597 mutex_unlock(&xc4000_list_mutex);
1598
1599 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1600 sizeof(struct dvb_tuner_ops));
1601
Istvan Varga027fd362011-06-04 12:04:51 -03001602 if (instance == 1) {
1603 int ret;
1604 mutex_lock(&priv->lock);
1605 ret = xc4000_fwupload(fe);
1606 mutex_unlock(&priv->lock);
1607 if (ret != XC_RESULT_SUCCESS)
1608 goto fail2;
1609 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001610
Davide Ferri8d009a02009-06-23 22:34:06 -03001611 return fe;
1612fail:
1613 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001614fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001615 xc4000_release(fe);
1616 return NULL;
1617}
1618EXPORT_SYMBOL(xc4000_attach);
1619
1620MODULE_AUTHOR("Steven Toth, Davide Ferri");
1621MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1622MODULE_LICENSE("GPL");