blob: 2a20d0e63da6108c95c1a7633dcbe9a4a16860ea [file] [log] [blame]
Davide Ferri8d009a02009-06-23 22:34:06 -03001/*
2 * Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 * Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/videodev2.h>
28#include <linux/delay.h>
29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h>
Istvan Varga56149422011-06-03 12:23:33 -030031#include <linux/mutex.h>
Devin Heitmueller11091a32009-07-20 00:54:57 -030032#include <asm/unaligned.h>
Davide Ferri8d009a02009-06-23 22:34:06 -030033
34#include "dvb_frontend.h"
35
36#include "xc4000.h"
37#include "tuner-i2c.h"
Devin Heitmueller11091a32009-07-20 00:54:57 -030038#include "tuner-xc2028-types.h"
Davide Ferri8d009a02009-06-23 22:34:06 -030039
Devin Heitmueller4922cec2009-12-27 17:50:43 -030040static int debug;
Davide Ferri8d009a02009-06-23 22:34:06 -030041module_param(debug, int, 0644);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -030042MODULE_PARM_DESC(debug, "\n\t\tDebugging level (0 to 2, default: 0 (off)).");
Davide Ferri8d009a02009-06-23 22:34:06 -030043
44static int no_poweroff;
45module_param(no_poweroff, int, 0644);
Istvan Varga5272f6b2011-06-04 12:03:03 -030046MODULE_PARM_DESC(no_poweroff, "\n\t\t1: keep device energized and with tuner "
47 "ready all the times.\n"
48 "\t\tFaster, but consumes more power and keeps the device hotter.\n"
49 "\t\t2: powers device off when not used.\n"
50 "\t\t0 (default): use device-specific default mode.");
Davide Ferri8d009a02009-06-23 22:34:06 -030051
Istvan Varga923137a2011-06-04 12:15:51 -030052#define XC4000_AUDIO_STD_B 1
53#define XC4000_AUDIO_STD_A2 2
54#define XC4000_AUDIO_STD_K3 4
55#define XC4000_AUDIO_STD_L 8
56#define XC4000_AUDIO_STD_INPUT1 16
57#define XC4000_AUDIO_STD_MONO 32
58
59static int audio_std;
60module_param(audio_std, int, 0644);
61MODULE_PARM_DESC(audio_std, "\n\t\tAudio standard. XC4000 audio decoder "
62 "explicitly needs to know\n"
63 "\t\twhat audio standard is needed for some video standards with\n"
64 "\t\taudio A2 or NICAM.\n"
65 "\t\tThe valid settings are a sum of:\n"
66 "\t\t 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n"
67 "\t\t 2: use A2 instead of NICAM or BTSC\n"
68 "\t\t 4: use SECAM/K3 instead of K1\n"
69 "\t\t 8: use PAL-D/K audio for SECAM-D/K\n"
70 "\t\t16: use FM radio input 1 instead of input 2\n"
71 "\t\t32: use mono audio (the lower three bits are ignored)");
72
Istvan Vargafa285bc2011-06-04 11:48:16 -030073#define XC4000_DEFAULT_FIRMWARE "xc4000.fw"
74
75static char firmware_name[30];
76module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
77MODULE_PARM_DESC(firmware_name, "\n\t\tFirmware file name. Allows overriding "
78 "the default firmware\n"
79 "\t\tname.");
80
Davide Ferri8d009a02009-06-23 22:34:06 -030081static DEFINE_MUTEX(xc4000_list_mutex);
82static LIST_HEAD(hybrid_tuner_instance_list);
83
84#define dprintk(level, fmt, arg...) if (debug >= level) \
85 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
86
Devin Heitmueller11091a32009-07-20 00:54:57 -030087/* struct for storing firmware table */
88struct firmware_description {
89 unsigned int type;
90 v4l2_std_id id;
91 __u16 int_freq;
92 unsigned char *ptr;
93 unsigned int size;
94};
95
96struct firmware_properties {
97 unsigned int type;
98 v4l2_std_id id;
99 v4l2_std_id std_req;
100 __u16 int_freq;
101 unsigned int scode_table;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300102 int scode_nr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300103};
Davide Ferri8d009a02009-06-23 22:34:06 -0300104
105struct xc4000_priv {
106 struct tuner_i2c_props i2c_props;
107 struct list_head hybrid_tuner_instance_list;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300108 struct firmware_description *firm;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300109 int firm_size;
110 __u16 firm_version;
111 u32 if_khz;
112 u32 freq_hz;
113 u32 bandwidth;
114 u8 video_standard;
115 u8 rf_mode;
Istvan Varga0b402132011-06-03 09:38:04 -0300116 u8 card_type;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300117 u8 ignore_i2c_write_errors;
118 /* struct xc2028_ctrl ctrl; */
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300119 struct firmware_properties cur_fw;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300120 __u16 hwmodel;
121 __u16 hwvers;
Istvan Varga56149422011-06-03 12:23:33 -0300122 struct mutex lock;
Davide Ferri8d009a02009-06-23 22:34:06 -0300123};
124
125/* Misc Defines */
Istvan Varga49110852011-06-03 10:55:24 -0300126#define MAX_TV_STANDARD 24
Davide Ferri8d009a02009-06-23 22:34:06 -0300127#define XC_MAX_I2C_WRITE_LENGTH 64
Istvan Varga5272f6b2011-06-04 12:03:03 -0300128#define XC_POWERED_DOWN 0x80000000U
Davide Ferri8d009a02009-06-23 22:34:06 -0300129
130/* Signal Types */
131#define XC_RF_MODE_AIR 0
132#define XC_RF_MODE_CABLE 1
133
134/* Result codes */
135#define XC_RESULT_SUCCESS 0
136#define XC_RESULT_RESET_FAILURE 1
137#define XC_RESULT_I2C_WRITE_FAILURE 2
138#define XC_RESULT_I2C_READ_FAILURE 3
139#define XC_RESULT_OUT_OF_RANGE 5
140
141/* Product id */
142#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300143#define XC_PRODUCT_ID_FW_LOADED 0x0FA0
Davide Ferri8d009a02009-06-23 22:34:06 -0300144
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300145/* Registers (Write-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300146#define XREG_INIT 0x00
147#define XREG_VIDEO_MODE 0x01
148#define XREG_AUDIO_MODE 0x02
149#define XREG_RF_FREQ 0x03
150#define XREG_D_CODE 0x04
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300151#define XREG_DIRECTSITTING_MODE 0x05
152#define XREG_SEEK_MODE 0x06
153#define XREG_POWER_DOWN 0x08
154#define XREG_SIGNALSOURCE 0x0A
Istvan Varga30f544e2011-06-04 12:12:42 -0300155#define XREG_SMOOTHEDCVBS 0x0E
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300156#define XREG_AMPLITUDE 0x10
Davide Ferri8d009a02009-06-23 22:34:06 -0300157
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300158/* Registers (Read-only) */
Davide Ferri8d009a02009-06-23 22:34:06 -0300159#define XREG_ADC_ENV 0x00
160#define XREG_QUALITY 0x01
161#define XREG_FRAME_LINES 0x02
162#define XREG_HSYNC_FREQ 0x03
163#define XREG_LOCK 0x04
164#define XREG_FREQ_ERROR 0x05
165#define XREG_SNR 0x06
166#define XREG_VERSION 0x07
167#define XREG_PRODUCT_ID 0x08
Davide Ferri8d009a02009-06-23 22:34:06 -0300168
169/*
170 Basic firmware description. This will remain with
171 the driver for documentation purposes.
172
173 This represents an I2C firmware file encoded as a
174 string of unsigned char. Format is as follows:
175
176 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
177 char[1 ]=len0_LSB -> length of first write transaction
178 char[2 ]=data0 -> first byte to be sent
179 char[3 ]=data1
180 char[4 ]=data2
181 char[ ]=...
182 char[M ]=dataN -> last byte to be sent
183 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
184 char[M+2]=len1_LSB -> length of second write transaction
185 char[M+3]=data0
186 char[M+4]=data1
187 ...
188 etc.
189
190 The [len] value should be interpreted as follows:
191
192 len= len_MSB _ len_LSB
193 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
194 len=0000_0000_0000_0000 : Reset command: Do hardware reset
195 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
196 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
197
198 For the RESET and WAIT commands, the two following bytes will contain
199 immediately the length of the following transaction.
Davide Ferri8d009a02009-06-23 22:34:06 -0300200*/
Istvan Vargafbe4a292011-06-03 10:11:48 -0300201
Davide Ferri8d009a02009-06-23 22:34:06 -0300202struct XC_TV_STANDARD {
Istvan Vargafbe4a292011-06-03 10:11:48 -0300203 const char *Name;
204 u16 AudioMode;
205 u16 VideoMode;
Istvan Varga49110852011-06-03 10:55:24 -0300206 u16 int_freq;
Davide Ferri8d009a02009-06-23 22:34:06 -0300207};
208
209/* Tuner standards */
Devin Heitmuellered23db32009-10-05 01:27:14 -0300210#define XC4000_MN_NTSC_PAL_BTSC 0
211#define XC4000_MN_NTSC_PAL_A2 1
212#define XC4000_MN_NTSC_PAL_EIAJ 2
213#define XC4000_MN_NTSC_PAL_Mono 3
214#define XC4000_BG_PAL_A2 4
215#define XC4000_BG_PAL_NICAM 5
216#define XC4000_BG_PAL_MONO 6
217#define XC4000_I_PAL_NICAM 7
218#define XC4000_I_PAL_NICAM_MONO 8
219#define XC4000_DK_PAL_A2 9
220#define XC4000_DK_PAL_NICAM 10
221#define XC4000_DK_PAL_MONO 11
222#define XC4000_DK_SECAM_A2DK1 12
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300223#define XC4000_DK_SECAM_A2LDK3 13
224#define XC4000_DK_SECAM_A2MONO 14
Istvan Varga49110852011-06-03 10:55:24 -0300225#define XC4000_DK_SECAM_NICAM 15
226#define XC4000_L_SECAM_NICAM 16
227#define XC4000_LC_SECAM_NICAM 17
228#define XC4000_DTV6 18
229#define XC4000_DTV8 19
230#define XC4000_DTV7_8 20
231#define XC4000_DTV7 21
232#define XC4000_FM_Radio_INPUT2 22
233#define XC4000_FM_Radio_INPUT1 23
Davide Ferri8d009a02009-06-23 22:34:06 -0300234
Davide Ferri8d009a02009-06-23 22:34:06 -0300235static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
Istvan Varga49110852011-06-03 10:55:24 -0300236 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
237 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
238 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
239 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
240 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
241 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
242 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
243 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
244 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
245 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
246 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
247 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
248 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
249 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
250 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
251 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
252 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
253 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
254 {"DTV6", 0x00C0, 0x8002, 0},
255 {"DTV8", 0x00C0, 0x800B, 0},
256 {"DTV7/8", 0x00C0, 0x801B, 0},
257 {"DTV7", 0x00C0, 0x8007, 0},
258 {"FM Radio-INPUT2", 0x0008, 0x9800,10700},
259 {"FM Radio-INPUT1", 0x0008, 0x9000,10700}
Davide Ferri8d009a02009-06-23 22:34:06 -0300260};
261
Davide Ferri8d009a02009-06-23 22:34:06 -0300262static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
263static int xc4000_TunerReset(struct dvb_frontend *fe);
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300264static void xc_debug_dump(struct xc4000_priv *priv);
Davide Ferri8d009a02009-06-23 22:34:06 -0300265
266static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
267{
268 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
269 .flags = 0, .buf = buf, .len = len };
Davide Ferri8d009a02009-06-23 22:34:06 -0300270 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
Devin Heitmueller799ed112009-10-04 23:09:18 -0300271 if (priv->ignore_i2c_write_errors == 0) {
272 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
273 len);
274 if (len == 4) {
275 printk("bytes %02x %02x %02x %02x\n", buf[0],
276 buf[1], buf[2], buf[3]);
277 }
278 return XC_RESULT_I2C_WRITE_FAILURE;
279 }
Davide Ferri8d009a02009-06-23 22:34:06 -0300280 }
281 return XC_RESULT_SUCCESS;
282}
283
Davide Ferri8d009a02009-06-23 22:34:06 -0300284static void xc_wait(int wait_ms)
285{
286 msleep(wait_ms);
287}
288
289static int xc4000_TunerReset(struct dvb_frontend *fe)
290{
291 struct xc4000_priv *priv = fe->tuner_priv;
292 int ret;
293
294 dprintk(1, "%s()\n", __func__);
295
296 if (fe->callback) {
297 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
298 fe->dvb->priv :
299 priv->i2c_props.adap->algo_data,
300 DVB_FRONTEND_COMPONENT_TUNER,
301 XC4000_TUNER_RESET, 0);
302 if (ret) {
303 printk(KERN_ERR "xc4000: reset failed\n");
304 return XC_RESULT_RESET_FAILURE;
305 }
306 } else {
307 printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
308 return XC_RESULT_RESET_FAILURE;
309 }
310 return XC_RESULT_SUCCESS;
311}
312
313static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
314{
315 u8 buf[4];
Davide Ferri8d009a02009-06-23 22:34:06 -0300316 int result;
317
318 buf[0] = (regAddr >> 8) & 0xFF;
319 buf[1] = regAddr & 0xFF;
320 buf[2] = (i2cData >> 8) & 0xFF;
321 buf[3] = i2cData & 0xFF;
322 result = xc_send_i2c_data(priv, buf, 4);
Davide Ferri8d009a02009-06-23 22:34:06 -0300323
324 return result;
325}
326
327static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
328{
329 struct xc4000_priv *priv = fe->tuner_priv;
330
331 int i, nbytes_to_send, result;
332 unsigned int len, pos, index;
333 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
334
335 index = 0;
336 while ((i2c_sequence[index] != 0xFF) ||
337 (i2c_sequence[index + 1] != 0xFF)) {
338 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
339 if (len == 0x0000) {
340 /* RESET command */
341 result = xc4000_TunerReset(fe);
342 index += 2;
343 if (result != XC_RESULT_SUCCESS)
344 return result;
345 } else if (len & 0x8000) {
346 /* WAIT command */
347 xc_wait(len & 0x7FFF);
348 index += 2;
349 } else {
350 /* Send i2c data whilst ensuring individual transactions
351 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
352 */
353 index += 2;
354 buf[0] = i2c_sequence[index];
355 buf[1] = i2c_sequence[index + 1];
356 pos = 2;
357 while (pos < len) {
358 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
359 nbytes_to_send =
360 XC_MAX_I2C_WRITE_LENGTH;
361 else
362 nbytes_to_send = (len - pos + 2);
363 for (i = 2; i < nbytes_to_send; i++) {
364 buf[i] = i2c_sequence[index + pos +
365 i - 2];
366 }
367 result = xc_send_i2c_data(priv, buf,
368 nbytes_to_send);
369
370 if (result != XC_RESULT_SUCCESS)
371 return result;
372
373 pos += nbytes_to_send - 2;
374 }
375 index += len;
376 }
377 }
378 return XC_RESULT_SUCCESS;
379}
380
Davide Ferri8d009a02009-06-23 22:34:06 -0300381static int xc_SetTVStandard(struct xc4000_priv *priv,
382 u16 VideoMode, u16 AudioMode)
383{
384 int ret;
385 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
386 dprintk(1, "%s() Standard = %s\n",
387 __func__,
388 XC4000_Standard[priv->video_standard].Name);
389
Devin Heitmueller799ed112009-10-04 23:09:18 -0300390 /* Don't complain when the request fails because of i2c stretching */
391 priv->ignore_i2c_write_errors = 1;
392
Davide Ferri8d009a02009-06-23 22:34:06 -0300393 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
394 if (ret == XC_RESULT_SUCCESS)
395 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
396
Devin Heitmueller799ed112009-10-04 23:09:18 -0300397 priv->ignore_i2c_write_errors = 0;
398
Davide Ferri8d009a02009-06-23 22:34:06 -0300399 return ret;
400}
401
402static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
403{
404 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
405 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
406
407 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
408 rf_mode = XC_RF_MODE_CABLE;
409 printk(KERN_ERR
410 "%s(), Invalid mode, defaulting to CABLE",
411 __func__);
412 }
413 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
414}
415
416static const struct dvb_tuner_ops xc4000_tuner_ops;
417
418static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
419{
420 u16 freq_code;
421
422 dprintk(1, "%s(%u)\n", __func__, freq_hz);
423
424 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
425 (freq_hz < xc4000_tuner_ops.info.frequency_min))
426 return XC_RESULT_OUT_OF_RANGE;
427
428 freq_code = (u16)(freq_hz / 15625);
429
430 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
431 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
432 only be used for fast scanning for channel lock) */
433 return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
434}
435
Davide Ferri8d009a02009-06-23 22:34:06 -0300436static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
437{
438 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
439}
440
441static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
442{
443 int result;
444 u16 regData;
445 u32 tmp;
446
447 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
448 if (result != XC_RESULT_SUCCESS)
449 return result;
450
Istvan Varga1368ceb2011-06-03 12:27:30 -0300451 tmp = (u32)regData & 0xFFFFU;
452 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
453 (*freq_error_hz) = tmp * 15625;
Davide Ferri8d009a02009-06-23 22:34:06 -0300454 return result;
455}
456
457static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
458{
459 return xc4000_readreg(priv, XREG_LOCK, lock_status);
460}
461
462static int xc_get_version(struct xc4000_priv *priv,
463 u8 *hw_majorversion, u8 *hw_minorversion,
464 u8 *fw_majorversion, u8 *fw_minorversion)
465{
466 u16 data;
467 int result;
468
469 result = xc4000_readreg(priv, XREG_VERSION, &data);
470 if (result != XC_RESULT_SUCCESS)
471 return result;
472
473 (*hw_majorversion) = (data >> 12) & 0x0F;
474 (*hw_minorversion) = (data >> 8) & 0x0F;
475 (*fw_majorversion) = (data >> 4) & 0x0F;
476 (*fw_minorversion) = data & 0x0F;
477
478 return 0;
479}
480
Davide Ferri8d009a02009-06-23 22:34:06 -0300481static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
482{
483 u16 regData;
484 int result;
485
486 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
487 if (result != XC_RESULT_SUCCESS)
488 return result;
489
490 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
491 return result;
492}
493
494static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
495{
496 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
497}
498
499static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
500{
501 return xc4000_readreg(priv, XREG_QUALITY, quality);
502}
503
504static u16 WaitForLock(struct xc4000_priv *priv)
505{
506 u16 lockState = 0;
507 int watchDogCount = 40;
508
509 while ((lockState == 0) && (watchDogCount > 0)) {
510 xc_get_lock_status(priv, &lockState);
511 if (lockState != 1) {
512 xc_wait(5);
513 watchDogCount--;
514 }
515 }
516 return lockState;
517}
518
519#define XC_TUNE_ANALOG 0
520#define XC_TUNE_DIGITAL 1
521static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
522{
Istvan Vargafbe4a292011-06-03 10:11:48 -0300523 int found = 0;
524 int result = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -0300525
526 dprintk(1, "%s(%u)\n", __func__, freq_hz);
527
Devin Heitmueller799ed112009-10-04 23:09:18 -0300528 /* Don't complain when the request fails because of i2c stretching */
529 priv->ignore_i2c_write_errors = 1;
530 result = xc_set_RF_frequency(priv, freq_hz);
531 priv->ignore_i2c_write_errors = 0;
532
533 if (result != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -0300534 return 0;
535
536 if (mode == XC_TUNE_ANALOG) {
537 if (WaitForLock(priv) == 1)
538 found = 1;
539 }
540
Istvan Vargaf4312e2f2011-06-04 12:08:29 -0300541 /* Wait for stats to stabilize.
542 * Frame Lines needs two frame times after initial lock
543 * before it is valid.
544 */
545 xc_wait(debug ? 100 : 10);
546
547 if (debug)
548 xc_debug_dump(priv);
549
Davide Ferri8d009a02009-06-23 22:34:06 -0300550 return found;
551}
552
553static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
554{
555 u8 buf[2] = { reg >> 8, reg & 0xff };
556 u8 bval[2] = { 0, 0 };
557 struct i2c_msg msg[2] = {
558 { .addr = priv->i2c_props.addr,
559 .flags = 0, .buf = &buf[0], .len = 2 },
560 { .addr = priv->i2c_props.addr,
561 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
562 };
563
564 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
565 printk(KERN_WARNING "xc4000: I2C read failed\n");
566 return -EREMOTEIO;
567 }
568
569 *val = (bval[0] << 8) | bval[1];
570 return XC_RESULT_SUCCESS;
571}
572
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300573#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300574static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
575{
576 if (type & BASE)
577 printk("BASE ");
578 if (type & INIT1)
579 printk("INIT1 ");
580 if (type & F8MHZ)
581 printk("F8MHZ ");
582 if (type & MTS)
583 printk("MTS ");
584 if (type & D2620)
585 printk("D2620 ");
586 if (type & D2633)
587 printk("D2633 ");
588 if (type & DTV6)
589 printk("DTV6 ");
590 if (type & QAM)
591 printk("QAM ");
592 if (type & DTV7)
593 printk("DTV7 ");
594 if (type & DTV78)
595 printk("DTV78 ");
596 if (type & DTV8)
597 printk("DTV8 ");
598 if (type & FM)
599 printk("FM ");
600 if (type & INPUT1)
601 printk("INPUT1 ");
602 if (type & LCD)
603 printk("LCD ");
604 if (type & NOGD)
605 printk("NOGD ");
606 if (type & MONO)
607 printk("MONO ");
608 if (type & ATSC)
609 printk("ATSC ");
610 if (type & IF)
611 printk("IF ");
612 if (type & LG60)
613 printk("LG60 ");
614 if (type & ATI638)
615 printk("ATI638 ");
616 if (type & OREN538)
617 printk("OREN538 ");
618 if (type & OREN36)
619 printk("OREN36 ");
620 if (type & TOYOTA388)
621 printk("TOYOTA388 ");
622 if (type & TOYOTA794)
623 printk("TOYOTA794 ");
624 if (type & DIBCOM52)
625 printk("DIBCOM52 ");
626 if (type & ZARLINK456)
627 printk("ZARLINK456 ");
628 if (type & CHINA)
629 printk("CHINA ");
630 if (type & F6MHZ)
631 printk("F6MHZ ");
632 if (type & INPUT2)
633 printk("INPUT2 ");
634 if (type & SCODE)
635 printk("SCODE ");
636 if (type & HAS_IF)
637 printk("HAS_IF_%d ", int_freq);
638}
639
Devin Heitmueller11091a32009-07-20 00:54:57 -0300640static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
641 v4l2_std_id *id)
642{
643 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga3db95702011-06-04 11:52:34 -0300644 int i, best_i = -1;
645 unsigned int best_nr_diffs = 255U;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300646
Devin Heitmueller11091a32009-07-20 00:54:57 -0300647 if (!priv->firm) {
648 printk("Error! firmware not loaded\n");
649 return -EINVAL;
650 }
651
652 if (((type & ~SCODE) == 0) && (*id == 0))
653 *id = V4L2_STD_PAL;
654
Devin Heitmueller11091a32009-07-20 00:54:57 -0300655 /* Seek for generic video standard match */
656 for (i = 0; i < priv->firm_size; i++) {
Istvan Varga3db95702011-06-04 11:52:34 -0300657 v4l2_std_id id_diff_mask =
658 (priv->firm[i].id ^ (*id)) & (*id);
659 unsigned int type_diff_mask =
660 (priv->firm[i].type ^ type)
661 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
662 unsigned int nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300663
Istvan Varga3db95702011-06-04 11:52:34 -0300664 if (type_diff_mask
665 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
Devin Heitmueller11091a32009-07-20 00:54:57 -0300666 continue;
667
Istvan Varga3db95702011-06-04 11:52:34 -0300668 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
669 if (!nr_diffs) /* Supports all the requested standards */
670 goto found;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300671
Istvan Varga3db95702011-06-04 11:52:34 -0300672 if (nr_diffs < best_nr_diffs) {
673 best_nr_diffs = nr_diffs;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300674 best_i = i;
675 }
676 }
677
Istvan Varga3db95702011-06-04 11:52:34 -0300678 /* FIXME: Would make sense to seek for type "hint" match ? */
679 if (best_i < 0) {
680 i = -ENOENT;
681 goto ret;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300682 }
683
Istvan Varga3db95702011-06-04 11:52:34 -0300684 if (best_nr_diffs > 0U) {
685 printk("Selecting best matching firmware (%u bits differ) for "
686 "type=", best_nr_diffs);
687 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
688 i = best_i;
689 }
Devin Heitmueller11091a32009-07-20 00:54:57 -0300690
691found:
692 *id = priv->firm[i].id;
693
694ret:
Devin Heitmueller11091a32009-07-20 00:54:57 -0300695 if (debug) {
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300696 printk("%s firmware for type=", (i < 0) ? "Can't find" :
697 "Found");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300698 dump_firm_type(type);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300699 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
700 }
701 return i;
702}
703
704static int load_firmware(struct dvb_frontend *fe, unsigned int type,
705 v4l2_std_id *id)
706{
707 struct xc4000_priv *priv = fe->tuner_priv;
708 int pos, rc;
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300709 unsigned char *p;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300710
Devin Heitmueller11091a32009-07-20 00:54:57 -0300711 pos = seek_firmware(fe, type, id);
712 if (pos < 0)
713 return pos;
714
Devin Heitmueller11091a32009-07-20 00:54:57 -0300715 p = priv->firm[pos].ptr;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300716
Devin Heitmueller799ed112009-10-04 23:09:18 -0300717 /* Don't complain when the request fails because of i2c stretching */
718 priv->ignore_i2c_write_errors = 1;
719
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300720 rc = xc_load_i2c_sequence(fe, p);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300721
Devin Heitmueller799ed112009-10-04 23:09:18 -0300722 priv->ignore_i2c_write_errors = 0;
723
Devin Heitmueller31f880e2009-07-20 02:15:31 -0300724 return rc;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300725}
726
Davide Ferri8d009a02009-06-23 22:34:06 -0300727static int xc4000_fwupload(struct dvb_frontend *fe)
728{
729 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300730 const struct firmware *fw = NULL;
731 const unsigned char *p, *endp;
732 int rc = 0;
733 int n, n_array;
734 char name[33];
Istvan Vargafbe4a292011-06-03 10:11:48 -0300735 const char *fname;
Davide Ferri8d009a02009-06-23 22:34:06 -0300736
Istvan Vargafa285bc2011-06-04 11:48:16 -0300737 if (firmware_name[0] != '\0')
738 fname = firmware_name;
739 else
740 fname = XC4000_DEFAULT_FIRMWARE;
Devin Heitmueller11091a32009-07-20 00:54:57 -0300741
742 printk("Reading firmware %s\n", fname);
743 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
744 if (rc < 0) {
745 if (rc == -ENOENT)
746 printk("Error: firmware %s not found.\n",
747 fname);
748 else
749 printk("Error %d while requesting firmware %s \n",
750 rc, fname);
751
752 return rc;
753 }
754 p = fw->data;
755 endp = p + fw->size;
756
757 if (fw->size < sizeof(name) - 1 + 2 + 2) {
758 printk("Error: firmware file %s has invalid size!\n",
Istvan Vargafbe4a292011-06-03 10:11:48 -0300759 fname);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300760 goto corrupt;
Davide Ferri8d009a02009-06-23 22:34:06 -0300761 }
762
Devin Heitmueller11091a32009-07-20 00:54:57 -0300763 memcpy(name, p, sizeof(name) - 1);
764 name[sizeof(name) - 1] = 0;
765 p += sizeof(name) - 1;
766
767 priv->firm_version = get_unaligned_le16(p);
768 p += 2;
769
770 n_array = get_unaligned_le16(p);
771 p += 2;
772
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300773 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
774 n_array, fname, name,
775 priv->firm_version >> 8, priv->firm_version & 0xff);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300776
777 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
778 if (priv->firm == NULL) {
779 printk("Not enough memory to load firmware file.\n");
780 rc = -ENOMEM;
781 goto err;
782 }
783 priv->firm_size = n_array;
784
785 n = -1;
786 while (p < endp) {
787 __u32 type, size;
788 v4l2_std_id id;
789 __u16 int_freq = 0;
790
791 n++;
792 if (n >= n_array) {
793 printk("More firmware images in file than "
Istvan Vargafbe4a292011-06-03 10:11:48 -0300794 "were expected!\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300795 goto corrupt;
796 }
797
798 /* Checks if there's enough bytes to read */
799 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
800 goto header;
801
802 type = get_unaligned_le32(p);
803 p += sizeof(type);
804
805 id = get_unaligned_le64(p);
806 p += sizeof(id);
807
808 if (type & HAS_IF) {
809 int_freq = get_unaligned_le16(p);
810 p += sizeof(int_freq);
811 if (endp - p < sizeof(size))
812 goto header;
813 }
814
815 size = get_unaligned_le32(p);
816 p += sizeof(size);
817
818 if (!size || size > endp - p) {
Istvan Vargaffce6262011-06-04 11:56:18 -0300819 printk("Firmware type (%x), id %llx is corrupted "
Devin Heitmueller11091a32009-07-20 00:54:57 -0300820 "(size=%d, expected %d)\n",
821 type, (unsigned long long)id,
822 (unsigned)(endp - p), size);
823 goto corrupt;
824 }
825
826 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
827 if (priv->firm[n].ptr == NULL) {
828 printk("Not enough memory to load firmware file.\n");
829 rc = -ENOMEM;
830 goto err;
831 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300832
Devin Heitmueller11091a32009-07-20 00:54:57 -0300833 if (debug) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300834 printk("Reading firmware type ");
835 dump_firm_type_and_int_freq(type, int_freq);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300836 printk("(%x), id %llx, size=%d.\n",
837 type, (unsigned long long)id, size);
838 }
839
840 memcpy(priv->firm[n].ptr, p, size);
841 priv->firm[n].type = type;
842 priv->firm[n].id = id;
843 priv->firm[n].size = size;
844 priv->firm[n].int_freq = int_freq;
845
846 p += size;
Davide Ferri8d009a02009-06-23 22:34:06 -0300847 }
848
Devin Heitmueller11091a32009-07-20 00:54:57 -0300849 if (n + 1 != priv->firm_size) {
850 printk("Firmware file is incomplete!\n");
851 goto corrupt;
852 }
853
854 goto done;
855
856header:
857 printk("Firmware header is incomplete!\n");
858corrupt:
859 rc = -EINVAL;
860 printk("Error: firmware file is corrupted!\n");
861
862err:
863 printk("Releasing partially loaded firmware file.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300864
865done:
Davide Ferri8d009a02009-06-23 22:34:06 -0300866 release_firmware(fw);
Devin Heitmueller11091a32009-07-20 00:54:57 -0300867 if (rc == 0)
Devin Heitmuellerb6cdb5b2009-12-27 18:15:14 -0300868 dprintk(1, "Firmware files loaded.\n");
Devin Heitmueller11091a32009-07-20 00:54:57 -0300869
870 return rc;
Davide Ferri8d009a02009-06-23 22:34:06 -0300871}
872
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300873static int load_scode(struct dvb_frontend *fe, unsigned int type,
874 v4l2_std_id *id, __u16 int_freq, int scode)
875{
876 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaffce6262011-06-04 11:56:18 -0300877 int pos, rc;
878 unsigned char *p;
879 u8 scode_buf[13];
880 u8 indirect_mode[5];
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300881
Devin Heitmuellerfe830362009-07-28 00:04:27 -0300882 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300883
884 if (!int_freq) {
885 pos = seek_firmware(fe, type, id);
886 if (pos < 0)
887 return pos;
888 } else {
889 for (pos = 0; pos < priv->firm_size; pos++) {
890 if ((priv->firm[pos].int_freq == int_freq) &&
891 (priv->firm[pos].type & HAS_IF))
892 break;
893 }
894 if (pos == priv->firm_size)
895 return -ENOENT;
896 }
897
898 p = priv->firm[pos].ptr;
899
Istvan Vargaffce6262011-06-04 11:56:18 -0300900 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
901 return -EINVAL;
902 p += 12 * scode;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300903
904 tuner_info("Loading SCODE for type=");
905 dump_firm_type_and_int_freq(priv->firm[pos].type,
906 priv->firm[pos].int_freq);
907 printk("(%x), id %016llx.\n", priv->firm[pos].type,
908 (unsigned long long)*id);
909
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300910 scode_buf[0] = 0x00;
911 memcpy(&scode_buf[1], p, 12);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300912
913 /* Enter direct-mode */
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300914 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
915 if (rc < 0) {
916 printk("failed to put device into direct mode!\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300917 return -EIO;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300918 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300919
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300920 rc = xc_send_i2c_data(priv, scode_buf, 13);
921 if (rc != XC_RESULT_SUCCESS) {
922 /* Even if the send failed, make sure we set back to indirect
923 mode */
924 printk("Failed to set scode %d\n", rc);
925 }
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300926
927 /* Switch back to indirect-mode */
928 memset(indirect_mode, 0, sizeof(indirect_mode));
929 indirect_mode[4] = 0x88;
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -0300930 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
931 msleep(10);
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300932
933 return 0;
934}
935
936static int check_firmware(struct dvb_frontend *fe, unsigned int type,
937 v4l2_std_id std, __u16 int_freq)
938{
939 struct xc4000_priv *priv = fe->tuner_priv;
940 struct firmware_properties new_fw;
941 int rc = 0, is_retry = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300942 u16 version = 0, hwmodel;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300943 v4l2_std_id std0;
Mauro Carvalho Chehabe3bb7c62011-06-02 11:36:56 -0300944 u8 hw_major, hw_minor, fw_major, fw_minor;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300945
946 dprintk(1, "%s called\n", __func__);
947
948 if (!priv->firm) {
949 rc = xc4000_fwupload(fe);
950 if (rc < 0)
951 return rc;
952 }
953
954#ifdef DJH_DEBUG
955 if (priv->ctrl.mts && !(type & FM))
956 type |= MTS;
957#endif
958
959retry:
960 new_fw.type = type;
961 new_fw.id = std;
962 new_fw.std_req = std;
Istvan Vargafbe4a292011-06-03 10:11:48 -0300963 new_fw.scode_table = SCODE /* | priv->ctrl.scode_table */;
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300964 new_fw.scode_nr = 0;
965 new_fw.int_freq = int_freq;
966
967 dprintk(1, "checking firmware, user requested type=");
968 if (debug) {
969 dump_firm_type(new_fw.type);
970 printk("(%x), id %016llx, ", new_fw.type,
971 (unsigned long long)new_fw.std_req);
972 if (!int_freq) {
973 printk("scode_tbl ");
974#ifdef DJH_DEBUG
975 dump_firm_type(priv->ctrl.scode_table);
976 printk("(%x), ", priv->ctrl.scode_table);
977#endif
978 } else
979 printk("int_freq %d, ", new_fw.int_freq);
980 printk("scode_nr %d\n", new_fw.scode_nr);
981 }
982
983 /* No need to reload base firmware if it matches */
Istvan Varga595a83f2011-06-04 11:59:54 -0300984 if (priv->cur_fw.type & BASE) {
Devin Heitmuellerd0962382009-07-25 17:39:54 -0300985 dprintk(1, "BASE firmware not changed.\n");
986 goto skip_base;
987 }
988
989 /* Updating BASE - forget about all currently loaded firmware */
990 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
991
992 /* Reset is needed before loading firmware */
993 rc = xc4000_TunerReset(fe);
994 if (rc < 0)
995 goto fail;
996
997 /* BASE firmwares are all std0 */
998 std0 = 0;
Istvan Varga595a83f2011-06-04 11:59:54 -0300999 rc = load_firmware(fe, BASE, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001000 if (rc < 0) {
1001 printk("Error %d while loading base firmware\n", rc);
1002 goto fail;
1003 }
1004
1005 /* Load INIT1, if needed */
1006 dprintk(1, "Load init1 firmware, if exists\n");
1007
Istvan Varga595a83f2011-06-04 11:59:54 -03001008 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001009 if (rc == -ENOENT)
Istvan Varga595a83f2011-06-04 11:59:54 -03001010 rc = load_firmware(fe, BASE | INIT1, &std0);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001011 if (rc < 0 && rc != -ENOENT) {
1012 tuner_err("Error %d while loading init1 firmware\n",
1013 rc);
1014 goto fail;
1015 }
1016
1017skip_base:
1018 /*
1019 * No need to reload standard specific firmware if base firmware
1020 * was not reloaded and requested video standards have not changed.
1021 */
1022 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1023 priv->cur_fw.std_req == std) {
1024 dprintk(1, "Std-specific firmware already loaded.\n");
1025 goto skip_std_specific;
1026 }
1027
1028 /* Reloading std-specific firmware forces a SCODE update */
1029 priv->cur_fw.scode_table = 0;
1030
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001031 /* Load the standard firmware */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001032 rc = load_firmware(fe, new_fw.type, &new_fw.id);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001033
1034 if (rc < 0)
1035 goto fail;
1036
1037skip_std_specific:
1038 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1039 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1040 dprintk(1, "SCODE firmware already loaded.\n");
1041 goto check_device;
1042 }
1043
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001044 /* Load SCODE firmware, if exists */
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001045 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1046 new_fw.int_freq, new_fw.scode_nr);
Devin Heitmuelleree4c3cd2009-07-27 23:51:54 -03001047 if (rc != XC_RESULT_SUCCESS)
1048 dprintk(1, "load scode failed %d\n", rc);
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001049
1050check_device:
1051 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1052
Devin Heitmueller799ed112009-10-04 23:09:18 -03001053 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001054 &fw_minor) != XC_RESULT_SUCCESS) {
1055 printk("Unable to read tuner registers.\n");
1056 goto fail;
1057 }
1058
1059 dprintk(1, "Device is Xceive %d version %d.%d, "
1060 "firmware version %d.%d\n",
1061 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1062
1063 /* Check firmware version against what we downloaded. */
1064#ifdef DJH_DEBUG
1065 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1066 printk("Incorrect readback of firmware version %x.\n",
1067 (version & 0xff));
1068 goto fail;
1069 }
1070#endif
1071
1072 /* Check that the tuner hardware model remains consistent over time. */
1073 if (priv->hwmodel == 0 && hwmodel == 4000) {
1074 priv->hwmodel = hwmodel;
1075 priv->hwvers = version & 0xff00;
1076 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1077 priv->hwvers != (version & 0xff00)) {
1078 printk("Read invalid device hardware information - tuner "
Istvan Vargafbe4a292011-06-03 10:11:48 -03001079 "hung?\n");
Devin Heitmuellerd0962382009-07-25 17:39:54 -03001080 goto fail;
1081 }
1082
1083 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1084
1085 /*
1086 * By setting BASE in cur_fw.type only after successfully loading all
1087 * firmwares, we can:
1088 * 1. Identify that BASE firmware with type=0 has been loaded;
1089 * 2. Tell whether BASE firmware was just changed the next time through.
1090 */
1091 priv->cur_fw.type |= BASE;
1092
1093 return 0;
1094
1095fail:
1096 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1097 if (!is_retry) {
1098 msleep(50);
1099 is_retry = 1;
1100 dprintk(1, "Retrying firmware load\n");
1101 goto retry;
1102 }
1103
1104 if (rc == -ENOENT)
1105 rc = -EINVAL;
1106 return rc;
1107}
Devin Heitmueller11091a32009-07-20 00:54:57 -03001108
Davide Ferri8d009a02009-06-23 22:34:06 -03001109static void xc_debug_dump(struct xc4000_priv *priv)
1110{
Istvan Vargafbe4a292011-06-03 10:11:48 -03001111 u16 adc_envelope;
1112 u32 freq_error_hz = 0;
1113 u16 lock_status;
1114 u32 hsync_freq_hz = 0;
1115 u16 frame_lines;
1116 u16 quality;
1117 u8 hw_majorversion = 0, hw_minorversion = 0;
1118 u8 fw_majorversion = 0, fw_minorversion = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001119
Istvan Vargafbe4a292011-06-03 10:11:48 -03001120 xc_get_ADC_Envelope(priv, &adc_envelope);
Davide Ferri8d009a02009-06-23 22:34:06 -03001121 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1122
1123 xc_get_frequency_error(priv, &freq_error_hz);
1124 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1125
Istvan Vargafbe4a292011-06-03 10:11:48 -03001126 xc_get_lock_status(priv, &lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001127 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1128 lock_status);
1129
Istvan Vargafbe4a292011-06-03 10:11:48 -03001130 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1131 &fw_majorversion, &fw_minorversion);
Davide Ferri8d009a02009-06-23 22:34:06 -03001132 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1133 hw_majorversion, hw_minorversion,
1134 fw_majorversion, fw_minorversion);
1135
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001136 if (priv->video_standard < XC4000_DTV6) {
1137 xc_get_hsync_freq(priv, &hsync_freq_hz);
1138 dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
1139 hsync_freq_hz);
Davide Ferri8d009a02009-06-23 22:34:06 -03001140
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001141 xc_get_frame_lines(priv, &frame_lines);
1142 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1143 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001144
Istvan Vargafbe4a292011-06-03 10:11:48 -03001145 xc_get_quality(priv, &quality);
Davide Ferri8d009a02009-06-23 22:34:06 -03001146 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1147}
1148
1149static int xc4000_set_params(struct dvb_frontend *fe,
1150 struct dvb_frontend_parameters *params)
1151{
1152 struct xc4000_priv *priv = fe->tuner_priv;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001153 unsigned int type;
Istvan Varga56149422011-06-03 12:23:33 -03001154 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001155
Davide Ferri8d009a02009-06-23 22:34:06 -03001156 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
1157
Istvan Varga56149422011-06-03 12:23:33 -03001158 mutex_lock(&priv->lock);
1159
Davide Ferri8d009a02009-06-23 22:34:06 -03001160 if (fe->ops.info.type == FE_ATSC) {
1161 dprintk(1, "%s() ATSC\n", __func__);
1162 switch (params->u.vsb.modulation) {
1163 case VSB_8:
1164 case VSB_16:
1165 dprintk(1, "%s() VSB modulation\n", __func__);
1166 priv->rf_mode = XC_RF_MODE_AIR;
1167 priv->freq_hz = params->frequency - 1750000;
1168 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001169 priv->video_standard = XC4000_DTV6;
1170 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001171 break;
1172 case QAM_64:
1173 case QAM_256:
1174 case QAM_AUTO:
1175 dprintk(1, "%s() QAM modulation\n", __func__);
1176 priv->rf_mode = XC_RF_MODE_CABLE;
1177 priv->freq_hz = params->frequency - 1750000;
1178 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001179 priv->video_standard = XC4000_DTV6;
1180 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001181 break;
1182 default:
Istvan Varga56149422011-06-03 12:23:33 -03001183 ret = -EINVAL;
1184 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001185 }
1186 } else if (fe->ops.info.type == FE_OFDM) {
1187 dprintk(1, "%s() OFDM\n", __func__);
1188 switch (params->u.ofdm.bandwidth) {
1189 case BANDWIDTH_6_MHZ:
1190 priv->bandwidth = BANDWIDTH_6_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001191 priv->video_standard = XC4000_DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001192 priv->freq_hz = params->frequency - 1750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001193 type = DTV6;
Davide Ferri8d009a02009-06-23 22:34:06 -03001194 break;
1195 case BANDWIDTH_7_MHZ:
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001196 priv->bandwidth = BANDWIDTH_7_MHZ;
1197 priv->video_standard = XC4000_DTV7;
1198 priv->freq_hz = params->frequency - 2250000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001199 type = DTV7;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001200 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001201 case BANDWIDTH_8_MHZ:
1202 priv->bandwidth = BANDWIDTH_8_MHZ;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001203 priv->video_standard = XC4000_DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001204 priv->freq_hz = params->frequency - 2750000;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001205 type = DTV8;
Davide Ferri8d009a02009-06-23 22:34:06 -03001206 break;
Istvan Vargaf0ef7c82011-06-03 12:17:59 -03001207 case BANDWIDTH_AUTO:
1208 if (params->frequency < 400000000) {
1209 priv->bandwidth = BANDWIDTH_7_MHZ;
1210 priv->freq_hz = params->frequency - 2250000;
1211 } else {
1212 priv->bandwidth = BANDWIDTH_8_MHZ;
1213 priv->freq_hz = params->frequency - 2750000;
1214 }
1215 priv->video_standard = XC4000_DTV7_8;
1216 type = DTV78;
1217 break;
Davide Ferri8d009a02009-06-23 22:34:06 -03001218 default:
1219 printk(KERN_ERR "xc4000 bandwidth not set!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001220 ret = -EINVAL;
1221 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001222 }
1223 priv->rf_mode = XC_RF_MODE_AIR;
1224 } else {
1225 printk(KERN_ERR "xc4000 modulation type not supported!\n");
Istvan Varga56149422011-06-03 12:23:33 -03001226 ret = -EINVAL;
1227 goto fail;
Davide Ferri8d009a02009-06-23 22:34:06 -03001228 }
1229
1230 dprintk(1, "%s() frequency=%d (compensated)\n",
1231 __func__, priv->freq_hz);
1232
Devin Heitmuellered23db32009-10-05 01:27:14 -03001233 /* Make sure the correct firmware type is loaded */
Istvan Varga56149422011-06-03 12:23:33 -03001234 if (check_firmware(fe, type, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1235 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001236
Davide Ferri8d009a02009-06-23 22:34:06 -03001237 ret = xc_SetSignalSource(priv, priv->rf_mode);
1238 if (ret != XC_RESULT_SUCCESS) {
1239 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001240 "xc4000: xc_SetSignalSource(%d) failed\n",
1241 priv->rf_mode);
1242 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001243 } else {
1244 u16 video_mode, audio_mode;
1245 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1246 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1247 if (type == DTV6 && priv->firm_version != 0x0102)
1248 video_mode |= 0x0001;
1249 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1250 if (ret != XC_RESULT_SUCCESS) {
1251 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1252 /* DJH - do not return when it fails... */
1253 /* goto fail; */
1254 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001255 }
1256
Istvan Varga30f544e2011-06-04 12:12:42 -03001257 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1258 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1259 ret = 0;
1260 if (xc_write_reg(priv, XREG_AMPLITUDE,
1261 (priv->firm_version == 0x0102 ? 132 : 134))
1262 != 0)
1263 ret = -EREMOTEIO;
1264 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1265 ret = -EREMOTEIO;
1266 if (ret != 0) {
1267 printk(KERN_ERR "xc4000: setting registers failed\n");
1268 /* goto fail; */
1269 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001270 }
Istvan Varga30f544e2011-06-04 12:12:42 -03001271
Davide Ferri8d009a02009-06-23 22:34:06 -03001272 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
1273
Istvan Varga56149422011-06-03 12:23:33 -03001274 ret = 0;
1275
1276fail:
1277 mutex_unlock(&priv->lock);
1278
1279 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001280}
1281
Davide Ferri8d009a02009-06-23 22:34:06 -03001282static int xc4000_set_analog_params(struct dvb_frontend *fe,
1283 struct analog_parameters *params)
1284{
1285 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Varga56149422011-06-03 12:23:33 -03001286 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001287
Davide Ferri8d009a02009-06-23 22:34:06 -03001288 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1289 __func__, params->frequency);
1290
Istvan Varga56149422011-06-03 12:23:33 -03001291 mutex_lock(&priv->lock);
1292
Davide Ferri8d009a02009-06-23 22:34:06 -03001293 /* Fix me: it could be air. */
1294 priv->rf_mode = params->mode;
1295 if (params->mode > XC_RF_MODE_CABLE)
1296 priv->rf_mode = XC_RF_MODE_CABLE;
1297
1298 /* params->frequency is in units of 62.5khz */
1299 priv->freq_hz = params->frequency * 62500;
1300
1301 /* FIX ME: Some video standards may have several possible audio
1302 standards. We simply default to one of them here.
1303 */
1304 if (params->std & V4L2_STD_MN) {
1305 /* default to BTSC audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001306 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
Davide Ferri8d009a02009-06-23 22:34:06 -03001307 goto tune_channel;
1308 }
1309
1310 if (params->std & V4L2_STD_PAL_BG) {
1311 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001312 priv->video_standard = XC4000_BG_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001313 goto tune_channel;
1314 }
1315
1316 if (params->std & V4L2_STD_PAL_I) {
1317 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001318 priv->video_standard = XC4000_I_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001319 goto tune_channel;
1320 }
1321
1322 if (params->std & V4L2_STD_PAL_DK) {
1323 /* default to NICAM audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001324 priv->video_standard = XC4000_DK_PAL_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001325 goto tune_channel;
1326 }
1327
1328 if (params->std & V4L2_STD_SECAM_DK) {
1329 /* default to A2 DK1 audio standard */
Devin Heitmuellered23db32009-10-05 01:27:14 -03001330 priv->video_standard = XC4000_DK_SECAM_A2DK1;
Davide Ferri8d009a02009-06-23 22:34:06 -03001331 goto tune_channel;
1332 }
1333
1334 if (params->std & V4L2_STD_SECAM_L) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001335 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001336 goto tune_channel;
1337 }
1338
1339 if (params->std & V4L2_STD_SECAM_LC) {
Devin Heitmuellered23db32009-10-05 01:27:14 -03001340 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001341 goto tune_channel;
1342 }
1343
1344tune_channel:
Devin Heitmuellered23db32009-10-05 01:27:14 -03001345
1346 /* FIXME - firmware type not being set properly */
Istvan Varga56149422011-06-03 12:23:33 -03001347 if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
1348 goto fail;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001349
Davide Ferri8d009a02009-06-23 22:34:06 -03001350 ret = xc_SetSignalSource(priv, priv->rf_mode);
1351 if (ret != XC_RESULT_SUCCESS) {
1352 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001353 "xc4000: xc_SetSignalSource(%d) failed\n",
1354 priv->rf_mode);
1355 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001356 } else {
1357 u16 video_mode, audio_mode;
1358 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1359 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1360 if (priv->video_standard < XC4000_BG_PAL_A2) {
1361 if (0 /*type & NOGD*/)
1362 video_mode &= 0xFF7F;
1363 } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
1364 if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
1365 priv->firm_version == 0x0102)
1366 video_mode &= 0xFEFF;
Istvan Varga923137a2011-06-04 12:15:51 -03001367 if (audio_std & XC4000_AUDIO_STD_B)
1368 video_mode |= 0x0080;
Istvan Varga30f544e2011-06-04 12:12:42 -03001369 }
1370 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1371 if (ret != XC_RESULT_SUCCESS) {
1372 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1373 goto fail;
1374 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001375 }
1376
Istvan Varga30f544e2011-06-04 12:12:42 -03001377 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1378 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1379 ret = 0;
1380 if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
1381 ret = -EREMOTEIO;
1382 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1383 ret = -EREMOTEIO;
1384 if (ret != 0) {
1385 printk(KERN_ERR "xc4000: setting registers failed\n");
1386 goto fail;
1387 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001388 }
1389
1390 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
1391
Istvan Varga56149422011-06-03 12:23:33 -03001392 ret = 0;
1393
1394fail:
1395 mutex_unlock(&priv->lock);
1396
1397 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001398}
1399
1400static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1401{
1402 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001403
Davide Ferri8d009a02009-06-23 22:34:06 -03001404 *freq = priv->freq_hz;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001405
1406 if (debug) {
1407 mutex_lock(&priv->lock);
1408 if ((priv->cur_fw.type
1409 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1410 u16 snr = 0;
1411 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1412 mutex_unlock(&priv->lock);
1413 dprintk(1, "%s() freq = %u, SNR = %d\n",
1414 __func__, *freq, snr);
1415 return 0;
1416 }
1417 }
1418 mutex_unlock(&priv->lock);
1419 }
1420
1421 dprintk(1, "%s()\n", __func__);
1422
Davide Ferri8d009a02009-06-23 22:34:06 -03001423 return 0;
1424}
1425
1426static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1427{
1428 struct xc4000_priv *priv = fe->tuner_priv;
1429 dprintk(1, "%s()\n", __func__);
1430
1431 *bw = priv->bandwidth;
1432 return 0;
1433}
1434
1435static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1436{
1437 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001438 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001439
Istvan Varga56149422011-06-03 12:23:33 -03001440 mutex_lock(&priv->lock);
1441
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001442 if (priv->cur_fw.type & BASE)
1443 xc_get_lock_status(priv, &lock_status);
1444
1445 *status = (lock_status == 1 ?
1446 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1447 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1448 *status &= (~TUNER_STATUS_STEREO);
Davide Ferri8d009a02009-06-23 22:34:06 -03001449
Istvan Varga56149422011-06-03 12:23:33 -03001450 mutex_unlock(&priv->lock);
1451
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001452 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001453
1454 return 0;
1455}
1456
Davide Ferri8d009a02009-06-23 22:34:06 -03001457static int xc4000_sleep(struct dvb_frontend *fe)
1458{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001459 struct xc4000_priv *priv = fe->tuner_priv;
1460 int ret = XC_RESULT_SUCCESS;
1461
1462 dprintk(1, "%s()\n", __func__);
1463
1464 mutex_lock(&priv->lock);
1465
1466 /* Avoid firmware reload on slow devices */
1467 if ((no_poweroff == 2 ||
1468 (no_poweroff == 0 &&
1469 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1470 (priv->cur_fw.type & BASE) != 0) {
1471 /* force reset and firmware reload */
1472 priv->cur_fw.type = XC_POWERED_DOWN;
1473
1474 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1475 != XC_RESULT_SUCCESS) {
1476 printk(KERN_ERR
1477 "xc4000: %s() unable to shutdown tuner\n",
1478 __func__);
1479 ret = -EREMOTEIO;
1480 }
1481 xc_wait(20);
1482 }
1483
1484 mutex_unlock(&priv->lock);
1485
1486 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001487}
1488
1489static int xc4000_init(struct dvb_frontend *fe)
1490{
Davide Ferri8d009a02009-06-23 22:34:06 -03001491 dprintk(1, "%s()\n", __func__);
1492
Davide Ferri8d009a02009-06-23 22:34:06 -03001493 return 0;
1494}
1495
1496static int xc4000_release(struct dvb_frontend *fe)
1497{
1498 struct xc4000_priv *priv = fe->tuner_priv;
1499
1500 dprintk(1, "%s()\n", __func__);
1501
1502 mutex_lock(&xc4000_list_mutex);
1503
1504 if (priv)
1505 hybrid_tuner_release_state(priv);
1506
1507 mutex_unlock(&xc4000_list_mutex);
1508
1509 fe->tuner_priv = NULL;
1510
1511 return 0;
1512}
1513
1514static const struct dvb_tuner_ops xc4000_tuner_ops = {
1515 .info = {
1516 .name = "Xceive XC4000",
1517 .frequency_min = 1000000,
1518 .frequency_max = 1023000000,
1519 .frequency_step = 50000,
1520 },
1521
1522 .release = xc4000_release,
1523 .init = xc4000_init,
1524 .sleep = xc4000_sleep,
1525
1526 .set_params = xc4000_set_params,
1527 .set_analog_params = xc4000_set_analog_params,
1528 .get_frequency = xc4000_get_frequency,
1529 .get_bandwidth = xc4000_get_bandwidth,
1530 .get_status = xc4000_get_status
1531};
1532
1533struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1534 struct i2c_adapter *i2c,
1535 struct xc4000_config *cfg)
1536{
1537 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001538 int instance;
1539 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001540
Istvan Varga0b402132011-06-03 09:38:04 -03001541 if (cfg->card_type != XC4000_CARD_GENERIC) {
1542 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1543 cfg->i2c_address = 0x61;
1544 cfg->if_khz = 4560;
1545 } else { /* default to PCTV 340E */
1546 cfg->i2c_address = 0x61;
1547 cfg->if_khz = 5400;
1548 }
1549 }
1550
Davide Ferri8d009a02009-06-23 22:34:06 -03001551 dprintk(1, "%s(%d-%04x)\n", __func__,
1552 i2c ? i2c_adapter_id(i2c) : -1,
1553 cfg ? cfg->i2c_address : -1);
1554
1555 mutex_lock(&xc4000_list_mutex);
1556
1557 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1558 hybrid_tuner_instance_list,
1559 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001560 if (cfg->card_type != XC4000_CARD_GENERIC)
1561 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001562 switch (instance) {
1563 case 0:
1564 goto fail;
1565 break;
1566 case 1:
1567 /* new tuner instance */
1568 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001569 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001570 fe->tuner_priv = priv;
1571 break;
1572 default:
1573 /* existing tuner instance */
1574 fe->tuner_priv = priv;
1575 break;
1576 }
1577
Istvan Varga0b402132011-06-03 09:38:04 -03001578 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001579 /* If the IF hasn't been set yet, use the value provided by
1580 the caller (occurs in hybrid devices where the analog
1581 call to xc4000_attach occurs before the digital side) */
1582 priv->if_khz = cfg->if_khz;
1583 }
1584
1585 /* Check if firmware has been loaded. It is possible that another
1586 instance of the driver has loaded the firmware.
1587 */
1588
Istvan Varga027fd362011-06-04 12:04:51 -03001589 if (instance == 1) {
1590 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1591 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001592 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001593 } else {
1594 id = ((priv->cur_fw.type & BASE) != 0 ?
1595 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1596 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001597
1598 switch (id) {
1599 case XC_PRODUCT_ID_FW_LOADED:
1600 printk(KERN_INFO
1601 "xc4000: Successfully identified at address 0x%02x\n",
1602 cfg->i2c_address);
1603 printk(KERN_INFO
1604 "xc4000: Firmware has been loaded previously\n");
1605 break;
1606 case XC_PRODUCT_ID_FW_NOT_LOADED:
1607 printk(KERN_INFO
1608 "xc4000: Successfully identified at address 0x%02x\n",
1609 cfg->i2c_address);
1610 printk(KERN_INFO
1611 "xc4000: Firmware has not been loaded previously\n");
1612 break;
1613 default:
1614 printk(KERN_ERR
1615 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1616 cfg->i2c_address, id);
1617 goto fail;
1618 }
1619
1620 mutex_unlock(&xc4000_list_mutex);
1621
1622 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1623 sizeof(struct dvb_tuner_ops));
1624
Istvan Varga027fd362011-06-04 12:04:51 -03001625 if (instance == 1) {
1626 int ret;
1627 mutex_lock(&priv->lock);
1628 ret = xc4000_fwupload(fe);
1629 mutex_unlock(&priv->lock);
1630 if (ret != XC_RESULT_SUCCESS)
1631 goto fail2;
1632 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001633
Davide Ferri8d009a02009-06-23 22:34:06 -03001634 return fe;
1635fail:
1636 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001637fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001638 xc4000_release(fe);
1639 return NULL;
1640}
1641EXPORT_SYMBOL(xc4000_attach);
1642
1643MODULE_AUTHOR("Steven Toth, Davide Ferri");
1644MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1645MODULE_LICENSE("GPL");