blob: 52375498257c457a7cba0f5a9d57d51acccbe042 [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 Varga818a1772011-06-04 12:17:22 -03001286 unsigned int type = 0;
Istvan Varga56149422011-06-03 12:23:33 -03001287 int ret = -EREMOTEIO;
Davide Ferri8d009a02009-06-23 22:34:06 -03001288
Istvan Varga818a1772011-06-04 12:17:22 -03001289 if (params->mode == V4L2_TUNER_RADIO) {
1290 dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
1291 __func__, params->frequency);
1292
1293 mutex_lock(&priv->lock);
1294
1295 params->std = 0;
1296 priv->freq_hz = params->frequency * 125L / 2;
1297
1298 if (audio_std & XC4000_AUDIO_STD_INPUT1) {
1299 priv->video_standard = XC4000_FM_Radio_INPUT1;
1300 type = FM | INPUT1;
1301 } else {
1302 priv->video_standard = XC4000_FM_Radio_INPUT2;
1303 type = FM | INPUT2;
1304 }
1305
1306 goto tune_channel;
1307 }
1308
Davide Ferri8d009a02009-06-23 22:34:06 -03001309 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1310 __func__, params->frequency);
1311
Istvan Varga56149422011-06-03 12:23:33 -03001312 mutex_lock(&priv->lock);
1313
Davide Ferri8d009a02009-06-23 22:34:06 -03001314 /* params->frequency is in units of 62.5khz */
1315 priv->freq_hz = params->frequency * 62500;
1316
Istvan Varga818a1772011-06-04 12:17:22 -03001317 params->std &= V4L2_STD_ALL;
1318 /* if std is not defined, choose one */
1319 if (!params->std)
1320 params->std = V4L2_STD_PAL_BG;
1321
1322 if (audio_std & XC4000_AUDIO_STD_MONO)
1323 type = MONO;
1324
Davide Ferri8d009a02009-06-23 22:34:06 -03001325 if (params->std & V4L2_STD_MN) {
Istvan Varga818a1772011-06-04 12:17:22 -03001326 params->std = V4L2_STD_MN;
1327 if (audio_std & XC4000_AUDIO_STD_MONO) {
1328 priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
1329 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1330 params->std |= V4L2_STD_A2;
1331 priv->video_standard = XC4000_MN_NTSC_PAL_A2;
1332 } else {
1333 params->std |= V4L2_STD_BTSC;
1334 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
1335 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001336 goto tune_channel;
1337 }
1338
1339 if (params->std & V4L2_STD_PAL_BG) {
Istvan Varga818a1772011-06-04 12:17:22 -03001340 params->std = V4L2_STD_PAL_BG;
1341 if (audio_std & XC4000_AUDIO_STD_MONO) {
1342 priv->video_standard = XC4000_BG_PAL_MONO;
1343 } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
1344 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1345 params->std |= V4L2_STD_NICAM_A;
1346 priv->video_standard = XC4000_BG_PAL_NICAM;
1347 } else {
1348 params->std |= V4L2_STD_NICAM_B;
1349 priv->video_standard = XC4000_BG_PAL_NICAM;
1350 }
1351 } else {
1352 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1353 params->std |= V4L2_STD_A2_A;
1354 priv->video_standard = XC4000_BG_PAL_A2;
1355 } else {
1356 params->std |= V4L2_STD_A2_B;
1357 priv->video_standard = XC4000_BG_PAL_A2;
1358 }
1359 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001360 goto tune_channel;
1361 }
1362
1363 if (params->std & V4L2_STD_PAL_I) {
1364 /* default to NICAM audio standard */
Istvan Varga818a1772011-06-04 12:17:22 -03001365 params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
1366 if (audio_std & XC4000_AUDIO_STD_MONO) {
1367 priv->video_standard = XC4000_I_PAL_NICAM_MONO;
1368 } else {
1369 priv->video_standard = XC4000_I_PAL_NICAM;
1370 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001371 goto tune_channel;
1372 }
1373
1374 if (params->std & V4L2_STD_PAL_DK) {
Istvan Varga818a1772011-06-04 12:17:22 -03001375 params->std = V4L2_STD_PAL_DK;
1376 if (audio_std & XC4000_AUDIO_STD_MONO) {
1377 priv->video_standard = XC4000_DK_PAL_MONO;
1378 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1379 params->std |= V4L2_STD_A2;
1380 priv->video_standard = XC4000_DK_PAL_A2;
1381 } else {
1382 params->std |= V4L2_STD_NICAM;
1383 priv->video_standard = XC4000_DK_PAL_NICAM;
1384 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001385 goto tune_channel;
1386 }
1387
1388 if (params->std & V4L2_STD_SECAM_DK) {
Istvan Varga818a1772011-06-04 12:17:22 -03001389 /* default to A2 audio standard */
1390 params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
1391 if (audio_std & XC4000_AUDIO_STD_L) {
1392 type = 0;
1393 priv->video_standard = XC4000_DK_SECAM_NICAM;
1394 } else if (audio_std & XC4000_AUDIO_STD_MONO) {
1395 priv->video_standard = XC4000_DK_SECAM_A2MONO;
1396 } else if (audio_std & XC4000_AUDIO_STD_K3) {
1397 params->std |= V4L2_STD_SECAM_K3;
1398 priv->video_standard = XC4000_DK_SECAM_A2LDK3;
1399 } else {
1400 priv->video_standard = XC4000_DK_SECAM_A2DK1;
1401 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001402 goto tune_channel;
1403 }
1404
1405 if (params->std & V4L2_STD_SECAM_L) {
Istvan Varga818a1772011-06-04 12:17:22 -03001406 /* default to NICAM audio standard */
1407 type = 0;
1408 params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001409 priv->video_standard = XC4000_L_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001410 goto tune_channel;
1411 }
1412
1413 if (params->std & V4L2_STD_SECAM_LC) {
Istvan Varga818a1772011-06-04 12:17:22 -03001414 /* default to NICAM audio standard */
1415 type = 0;
1416 params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001417 priv->video_standard = XC4000_LC_SECAM_NICAM;
Davide Ferri8d009a02009-06-23 22:34:06 -03001418 goto tune_channel;
1419 }
1420
1421tune_channel:
Istvan Varga818a1772011-06-04 12:17:22 -03001422 /* Fix me: it could be air. */
1423 priv->rf_mode = XC_RF_MODE_CABLE;
Devin Heitmuellered23db32009-10-05 01:27:14 -03001424
Istvan Varga818a1772011-06-04 12:17:22 -03001425 if (check_firmware(fe, type, params->std,
1426 XC4000_Standard[priv->video_standard].int_freq)
1427 != XC_RESULT_SUCCESS) {
Istvan Varga56149422011-06-03 12:23:33 -03001428 goto fail;
Istvan Varga818a1772011-06-04 12:17:22 -03001429 }
Devin Heitmuellered23db32009-10-05 01:27:14 -03001430
Davide Ferri8d009a02009-06-23 22:34:06 -03001431 ret = xc_SetSignalSource(priv, priv->rf_mode);
1432 if (ret != XC_RESULT_SUCCESS) {
1433 printk(KERN_ERR
Istvan Varga56149422011-06-03 12:23:33 -03001434 "xc4000: xc_SetSignalSource(%d) failed\n",
1435 priv->rf_mode);
1436 goto fail;
Istvan Varga30f544e2011-06-04 12:12:42 -03001437 } else {
1438 u16 video_mode, audio_mode;
1439 video_mode = XC4000_Standard[priv->video_standard].VideoMode;
1440 audio_mode = XC4000_Standard[priv->video_standard].AudioMode;
1441 if (priv->video_standard < XC4000_BG_PAL_A2) {
1442 if (0 /*type & NOGD*/)
1443 video_mode &= 0xFF7F;
1444 } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
1445 if (priv->card_type == XC4000_CARD_WINFAST_CX88 &&
1446 priv->firm_version == 0x0102)
1447 video_mode &= 0xFEFF;
Istvan Varga923137a2011-06-04 12:15:51 -03001448 if (audio_std & XC4000_AUDIO_STD_B)
1449 video_mode |= 0x0080;
Istvan Varga30f544e2011-06-04 12:12:42 -03001450 }
1451 ret = xc_SetTVStandard(priv, video_mode, audio_mode);
1452 if (ret != XC_RESULT_SUCCESS) {
1453 printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
1454 goto fail;
1455 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001456 }
1457
Istvan Varga30f544e2011-06-04 12:12:42 -03001458 if (priv->card_type == XC4000_CARD_WINFAST_CX88) {
1459 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1460 ret = 0;
1461 if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
1462 ret = -EREMOTEIO;
1463 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1464 ret = -EREMOTEIO;
1465 if (ret != 0) {
1466 printk(KERN_ERR "xc4000: setting registers failed\n");
1467 goto fail;
1468 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001469 }
1470
1471 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
1472
Istvan Varga56149422011-06-03 12:23:33 -03001473 ret = 0;
1474
1475fail:
1476 mutex_unlock(&priv->lock);
1477
1478 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001479}
1480
1481static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1482{
1483 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001484
Davide Ferri8d009a02009-06-23 22:34:06 -03001485 *freq = priv->freq_hz;
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001486
1487 if (debug) {
1488 mutex_lock(&priv->lock);
1489 if ((priv->cur_fw.type
1490 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1491 u16 snr = 0;
1492 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1493 mutex_unlock(&priv->lock);
1494 dprintk(1, "%s() freq = %u, SNR = %d\n",
1495 __func__, *freq, snr);
1496 return 0;
1497 }
1498 }
1499 mutex_unlock(&priv->lock);
1500 }
1501
1502 dprintk(1, "%s()\n", __func__);
1503
Davide Ferri8d009a02009-06-23 22:34:06 -03001504 return 0;
1505}
1506
1507static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1508{
1509 struct xc4000_priv *priv = fe->tuner_priv;
1510 dprintk(1, "%s()\n", __func__);
1511
1512 *bw = priv->bandwidth;
1513 return 0;
1514}
1515
1516static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1517{
1518 struct xc4000_priv *priv = fe->tuner_priv;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001519 u16 lock_status = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001520
Istvan Varga56149422011-06-03 12:23:33 -03001521 mutex_lock(&priv->lock);
1522
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001523 if (priv->cur_fw.type & BASE)
1524 xc_get_lock_status(priv, &lock_status);
1525
1526 *status = (lock_status == 1 ?
1527 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1528 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1529 *status &= (~TUNER_STATUS_STEREO);
Davide Ferri8d009a02009-06-23 22:34:06 -03001530
Istvan Varga56149422011-06-03 12:23:33 -03001531 mutex_unlock(&priv->lock);
1532
Istvan Vargaf4312e2f2011-06-04 12:08:29 -03001533 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
Davide Ferri8d009a02009-06-23 22:34:06 -03001534
1535 return 0;
1536}
1537
Davide Ferri8d009a02009-06-23 22:34:06 -03001538static int xc4000_sleep(struct dvb_frontend *fe)
1539{
Istvan Varga5272f6b2011-06-04 12:03:03 -03001540 struct xc4000_priv *priv = fe->tuner_priv;
1541 int ret = XC_RESULT_SUCCESS;
1542
1543 dprintk(1, "%s()\n", __func__);
1544
1545 mutex_lock(&priv->lock);
1546
1547 /* Avoid firmware reload on slow devices */
1548 if ((no_poweroff == 2 ||
1549 (no_poweroff == 0 &&
1550 priv->card_type != XC4000_CARD_WINFAST_CX88)) &&
1551 (priv->cur_fw.type & BASE) != 0) {
1552 /* force reset and firmware reload */
1553 priv->cur_fw.type = XC_POWERED_DOWN;
1554
1555 if (xc_write_reg(priv, XREG_POWER_DOWN, 0)
1556 != XC_RESULT_SUCCESS) {
1557 printk(KERN_ERR
1558 "xc4000: %s() unable to shutdown tuner\n",
1559 __func__);
1560 ret = -EREMOTEIO;
1561 }
1562 xc_wait(20);
1563 }
1564
1565 mutex_unlock(&priv->lock);
1566
1567 return ret;
Davide Ferri8d009a02009-06-23 22:34:06 -03001568}
1569
1570static int xc4000_init(struct dvb_frontend *fe)
1571{
Davide Ferri8d009a02009-06-23 22:34:06 -03001572 dprintk(1, "%s()\n", __func__);
1573
Davide Ferri8d009a02009-06-23 22:34:06 -03001574 return 0;
1575}
1576
1577static int xc4000_release(struct dvb_frontend *fe)
1578{
1579 struct xc4000_priv *priv = fe->tuner_priv;
1580
1581 dprintk(1, "%s()\n", __func__);
1582
1583 mutex_lock(&xc4000_list_mutex);
1584
1585 if (priv)
1586 hybrid_tuner_release_state(priv);
1587
1588 mutex_unlock(&xc4000_list_mutex);
1589
1590 fe->tuner_priv = NULL;
1591
1592 return 0;
1593}
1594
1595static const struct dvb_tuner_ops xc4000_tuner_ops = {
1596 .info = {
1597 .name = "Xceive XC4000",
1598 .frequency_min = 1000000,
1599 .frequency_max = 1023000000,
1600 .frequency_step = 50000,
1601 },
1602
1603 .release = xc4000_release,
1604 .init = xc4000_init,
1605 .sleep = xc4000_sleep,
1606
1607 .set_params = xc4000_set_params,
1608 .set_analog_params = xc4000_set_analog_params,
1609 .get_frequency = xc4000_get_frequency,
1610 .get_bandwidth = xc4000_get_bandwidth,
1611 .get_status = xc4000_get_status
1612};
1613
1614struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1615 struct i2c_adapter *i2c,
1616 struct xc4000_config *cfg)
1617{
1618 struct xc4000_priv *priv = NULL;
Istvan Vargafbe4a292011-06-03 10:11:48 -03001619 int instance;
1620 u16 id = 0;
Davide Ferri8d009a02009-06-23 22:34:06 -03001621
Istvan Varga0b402132011-06-03 09:38:04 -03001622 if (cfg->card_type != XC4000_CARD_GENERIC) {
1623 if (cfg->card_type == XC4000_CARD_WINFAST_CX88) {
1624 cfg->i2c_address = 0x61;
1625 cfg->if_khz = 4560;
1626 } else { /* default to PCTV 340E */
1627 cfg->i2c_address = 0x61;
1628 cfg->if_khz = 5400;
1629 }
1630 }
1631
Davide Ferri8d009a02009-06-23 22:34:06 -03001632 dprintk(1, "%s(%d-%04x)\n", __func__,
1633 i2c ? i2c_adapter_id(i2c) : -1,
1634 cfg ? cfg->i2c_address : -1);
1635
1636 mutex_lock(&xc4000_list_mutex);
1637
1638 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1639 hybrid_tuner_instance_list,
1640 i2c, cfg->i2c_address, "xc4000");
Istvan Varga0b402132011-06-03 09:38:04 -03001641 if (cfg->card_type != XC4000_CARD_GENERIC)
1642 priv->card_type = cfg->card_type;
Davide Ferri8d009a02009-06-23 22:34:06 -03001643 switch (instance) {
1644 case 0:
1645 goto fail;
1646 break;
1647 case 1:
1648 /* new tuner instance */
1649 priv->bandwidth = BANDWIDTH_6_MHZ;
Istvan Varga56149422011-06-03 12:23:33 -03001650 mutex_init(&priv->lock);
Davide Ferri8d009a02009-06-23 22:34:06 -03001651 fe->tuner_priv = priv;
1652 break;
1653 default:
1654 /* existing tuner instance */
1655 fe->tuner_priv = priv;
1656 break;
1657 }
1658
Istvan Varga0b402132011-06-03 09:38:04 -03001659 if (cfg->if_khz != 0) {
Davide Ferri8d009a02009-06-23 22:34:06 -03001660 /* If the IF hasn't been set yet, use the value provided by
1661 the caller (occurs in hybrid devices where the analog
1662 call to xc4000_attach occurs before the digital side) */
1663 priv->if_khz = cfg->if_khz;
1664 }
1665
1666 /* Check if firmware has been loaded. It is possible that another
1667 instance of the driver has loaded the firmware.
1668 */
1669
Istvan Varga027fd362011-06-04 12:04:51 -03001670 if (instance == 1) {
1671 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id)
1672 != XC_RESULT_SUCCESS)
Davide Ferri8d009a02009-06-23 22:34:06 -03001673 goto fail;
Istvan Varga027fd362011-06-04 12:04:51 -03001674 } else {
1675 id = ((priv->cur_fw.type & BASE) != 0 ?
1676 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1677 }
Davide Ferri8d009a02009-06-23 22:34:06 -03001678
1679 switch (id) {
1680 case XC_PRODUCT_ID_FW_LOADED:
1681 printk(KERN_INFO
1682 "xc4000: Successfully identified at address 0x%02x\n",
1683 cfg->i2c_address);
1684 printk(KERN_INFO
1685 "xc4000: Firmware has been loaded previously\n");
1686 break;
1687 case XC_PRODUCT_ID_FW_NOT_LOADED:
1688 printk(KERN_INFO
1689 "xc4000: Successfully identified at address 0x%02x\n",
1690 cfg->i2c_address);
1691 printk(KERN_INFO
1692 "xc4000: Firmware has not been loaded previously\n");
1693 break;
1694 default:
1695 printk(KERN_ERR
1696 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1697 cfg->i2c_address, id);
1698 goto fail;
1699 }
1700
1701 mutex_unlock(&xc4000_list_mutex);
1702
1703 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1704 sizeof(struct dvb_tuner_ops));
1705
Istvan Varga027fd362011-06-04 12:04:51 -03001706 if (instance == 1) {
1707 int ret;
1708 mutex_lock(&priv->lock);
1709 ret = xc4000_fwupload(fe);
1710 mutex_unlock(&priv->lock);
1711 if (ret != XC_RESULT_SUCCESS)
1712 goto fail2;
1713 }
Devin Heitmueller11091a32009-07-20 00:54:57 -03001714
Davide Ferri8d009a02009-06-23 22:34:06 -03001715 return fe;
1716fail:
1717 mutex_unlock(&xc4000_list_mutex);
Istvan Varga027fd362011-06-04 12:04:51 -03001718fail2:
Davide Ferri8d009a02009-06-23 22:34:06 -03001719 xc4000_release(fe);
1720 return NULL;
1721}
1722EXPORT_SYMBOL(xc4000_attach);
1723
1724MODULE_AUTHOR("Steven Toth, Davide Ferri");
1725MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1726MODULE_LICENSE("GPL");