blob: 215dad07f060db61fd478e050a5e8f8637283495 [file] [log] [blame]
Steven Tothaacb9d32007-12-18 01:55:51 -03001/*
2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Xceive Corporation
Steven Toth6d897612008-09-03 17:12:12 -03005 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
Devin Heitmuellere80858e2009-05-14 21:31:11 -03006 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
Steven Tothaacb9d32007-12-18 01:55:51 -03007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
Steven Toth49170192008-01-15 21:57:14 -030026#include <linux/videodev2.h>
Steven Tothaacb9d32007-12-18 01:55:51 -030027#include <linux/delay.h>
28#include <linux/dvb/frontend.h>
29#include <linux/i2c.h>
30
31#include "dvb_frontend.h"
32
33#include "xc5000.h"
Michael Krufky89fd2852008-09-06 11:44:53 -030034#include "tuner-i2c.h"
Steven Tothaacb9d32007-12-18 01:55:51 -030035
36static int debug;
37module_param(debug, int, 0644);
38MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
39
Devin Heitmuellerb6bd5eb2009-04-28 13:53:38 -030040static int no_poweroff;
41module_param(no_poweroff, int, 0644);
42MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
43 "\t\t1 keep device energized and with tuner ready all the times.\n"
44 "\t\tFaster, but consumes more power and keeps the device hotter");
45
Michael Krufky89fd2852008-09-06 11:44:53 -030046static DEFINE_MUTEX(xc5000_list_mutex);
47static LIST_HEAD(hybrid_tuner_instance_list);
48
Steven Toth8f3cd532008-10-16 20:29:38 -030049#define dprintk(level, fmt, arg...) if (debug >= level) \
Steven Tothaacb9d32007-12-18 01:55:51 -030050 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
51
Devin Heitmuellera6301d12009-05-04 22:04:20 -030052#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
53#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
Steven Tothaacb9d32007-12-18 01:55:51 -030054
Michael Krufkyffb41232008-09-06 10:52:30 -030055struct xc5000_priv {
Michael Krufky89fd2852008-09-06 11:44:53 -030056 struct tuner_i2c_props i2c_props;
57 struct list_head hybrid_tuner_instance_list;
Michael Krufkyffb41232008-09-06 10:52:30 -030058
Michael Krufky2a6003c2008-09-06 13:54:45 -030059 u32 if_khz;
Michael Krufkyffb41232008-09-06 10:52:30 -030060 u32 freq_hz;
61 u32 bandwidth;
62 u8 video_standard;
63 u8 rf_mode;
Devin Heitmueller496e9052009-09-24 13:27:24 -030064 u8 radio_input;
Michael Krufkyffb41232008-09-06 10:52:30 -030065};
66
Steven Tothaacb9d32007-12-18 01:55:51 -030067/* Misc Defines */
68#define MAX_TV_STANDARD 23
69#define XC_MAX_I2C_WRITE_LENGTH 64
70
71/* Signal Types */
72#define XC_RF_MODE_AIR 0
73#define XC_RF_MODE_CABLE 1
74
75/* Result codes */
76#define XC_RESULT_SUCCESS 0
77#define XC_RESULT_RESET_FAILURE 1
78#define XC_RESULT_I2C_WRITE_FAILURE 2
79#define XC_RESULT_I2C_READ_FAILURE 3
80#define XC_RESULT_OUT_OF_RANGE 5
81
Steven Toth27c685a2008-01-05 16:50:14 -030082/* Product id */
83#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
84#define XC_PRODUCT_ID_FW_LOADED 0x1388
85
Steven Tothaacb9d32007-12-18 01:55:51 -030086/* Registers */
87#define XREG_INIT 0x00
88#define XREG_VIDEO_MODE 0x01
89#define XREG_AUDIO_MODE 0x02
90#define XREG_RF_FREQ 0x03
91#define XREG_D_CODE 0x04
92#define XREG_IF_OUT 0x05
93#define XREG_SEEK_MODE 0x07
Devin Heitmueller7f05b532009-04-02 22:02:39 -030094#define XREG_POWER_DOWN 0x0A /* Obsolete */
Steven Tothaacb9d32007-12-18 01:55:51 -030095#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
96#define XREG_SMOOTHEDCVBS 0x0E
97#define XREG_XTALFREQ 0x0F
Devin Heitmueller81c4dfe2009-04-02 22:40:29 -030098#define XREG_FINERFREQ 0x10
Steven Tothaacb9d32007-12-18 01:55:51 -030099#define XREG_DDIMODE 0x11
100
101#define XREG_ADC_ENV 0x00
102#define XREG_QUALITY 0x01
103#define XREG_FRAME_LINES 0x02
104#define XREG_HSYNC_FREQ 0x03
105#define XREG_LOCK 0x04
106#define XREG_FREQ_ERROR 0x05
107#define XREG_SNR 0x06
108#define XREG_VERSION 0x07
109#define XREG_PRODUCT_ID 0x08
110#define XREG_BUSY 0x09
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300111#define XREG_BUILD 0x0D
Steven Tothaacb9d32007-12-18 01:55:51 -0300112
113/*
114 Basic firmware description. This will remain with
115 the driver for documentation purposes.
116
117 This represents an I2C firmware file encoded as a
118 string of unsigned char. Format is as follows:
119
120 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
121 char[1 ]=len0_LSB -> length of first write transaction
122 char[2 ]=data0 -> first byte to be sent
123 char[3 ]=data1
124 char[4 ]=data2
125 char[ ]=...
126 char[M ]=dataN -> last byte to be sent
127 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
128 char[M+2]=len1_LSB -> length of second write transaction
129 char[M+3]=data0
130 char[M+4]=data1
131 ...
132 etc.
133
134 The [len] value should be interpreted as follows:
135
136 len= len_MSB _ len_LSB
137 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
138 len=0000_0000_0000_0000 : Reset command: Do hardware reset
139 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
140 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
141
142 For the RESET and WAIT commands, the two following bytes will contain
143 immediately the length of the following transaction.
144
145*/
Steven Toth8f3cd532008-10-16 20:29:38 -0300146struct XC_TV_STANDARD {
Steven Tothaacb9d32007-12-18 01:55:51 -0300147 char *Name;
Steven Tothe12671c2007-12-20 01:14:43 -0300148 u16 AudioMode;
149 u16 VideoMode;
Steven Toth8f3cd532008-10-16 20:29:38 -0300150};
Steven Tothaacb9d32007-12-18 01:55:51 -0300151
152/* Tuner standards */
Steven Toth27c685a2008-01-05 16:50:14 -0300153#define MN_NTSC_PAL_BTSC 0
154#define MN_NTSC_PAL_A2 1
155#define MN_NTSC_PAL_EIAJ 2
156#define MN_NTSC_PAL_Mono 3
157#define BG_PAL_A2 4
158#define BG_PAL_NICAM 5
159#define BG_PAL_MONO 6
160#define I_PAL_NICAM 7
161#define I_PAL_NICAM_MONO 8
162#define DK_PAL_A2 9
163#define DK_PAL_NICAM 10
164#define DK_PAL_MONO 11
165#define DK_SECAM_A2DK1 12
166#define DK_SECAM_A2LDK3 13
167#define DK_SECAM_A2MONO 14
168#define L_SECAM_NICAM 15
169#define LC_SECAM_NICAM 16
170#define DTV6 17
171#define DTV8 18
172#define DTV7_8 19
173#define DTV7 20
174#define FM_Radio_INPUT2 21
175#define FM_Radio_INPUT1 22
Steven Tothaacb9d32007-12-18 01:55:51 -0300176
Steven Toth8f3cd532008-10-16 20:29:38 -0300177static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
Steven Tothaacb9d32007-12-18 01:55:51 -0300178 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
179 {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
180 {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
181 {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
182 {"B/G-PAL-A2", 0x0A00, 0x8049},
183 {"B/G-PAL-NICAM", 0x0C04, 0x8049},
184 {"B/G-PAL-MONO", 0x0878, 0x8059},
185 {"I-PAL-NICAM", 0x1080, 0x8009},
186 {"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
187 {"D/K-PAL-A2", 0x1600, 0x8009},
188 {"D/K-PAL-NICAM", 0x0E80, 0x8009},
189 {"D/K-PAL-MONO", 0x1478, 0x8009},
190 {"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
Steven Toth8f3cd532008-10-16 20:29:38 -0300191 {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
Steven Tothaacb9d32007-12-18 01:55:51 -0300192 {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
193 {"L-SECAM-NICAM", 0x8E82, 0x0009},
194 {"L'-SECAM-NICAM", 0x8E82, 0x4009},
195 {"DTV6", 0x00C0, 0x8002},
196 {"DTV8", 0x00C0, 0x800B},
197 {"DTV7/8", 0x00C0, 0x801B},
198 {"DTV7", 0x00C0, 0x8007},
199 {"FM Radio-INPUT2", 0x9802, 0x9002},
200 {"FM Radio-INPUT1", 0x0208, 0x9002}
201};
202
Devin Heitmueller8e4c6792008-11-16 20:41:07 -0300203static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300204static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300205static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300206static int xc5000_TunerReset(struct dvb_frontend *fe);
Steven Tothaacb9d32007-12-18 01:55:51 -0300207
Steven Tothe12671c2007-12-20 01:14:43 -0300208static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
Steven Tothaacb9d32007-12-18 01:55:51 -0300209{
Devin Heitmuellerd7800d42008-11-16 20:20:06 -0300210 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
211 .flags = 0, .buf = buf, .len = len };
212
213 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
214 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
215 return XC_RESULT_I2C_WRITE_FAILURE;
216 }
217 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300218}
219
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300220/* This routine is never used because the only time we read data from the
221 i2c bus is when we read registers, and we want that to be an atomic i2c
222 transaction in case we are on a multi-master bus */
Steven Tothe12671c2007-12-20 01:14:43 -0300223static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
Steven Tothaacb9d32007-12-18 01:55:51 -0300224{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300225 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
226 .flags = I2C_M_RD, .buf = buf, .len = len };
227
228 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
229 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
230 return -EREMOTEIO;
231 }
232 return 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300233}
234
Dmitri Belimov47433192010-05-18 04:30:11 -0300235static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
236{
237 u8 buf[2] = { reg >> 8, reg & 0xff };
238 u8 bval[2] = { 0, 0 };
239 struct i2c_msg msg[2] = {
240 { .addr = priv->i2c_props.addr,
241 .flags = 0, .buf = &buf[0], .len = 2 },
242 { .addr = priv->i2c_props.addr,
243 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
244 };
245
246 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
247 printk(KERN_WARNING "xc5000: I2C read failed\n");
248 return -EREMOTEIO;
249 }
250
251 *val = (bval[0] << 8) | bval[1];
252 return XC_RESULT_SUCCESS;
253}
254
Steven Tothe12671c2007-12-20 01:14:43 -0300255static void xc_wait(int wait_ms)
Steven Tothaacb9d32007-12-18 01:55:51 -0300256{
Steven Tothe12671c2007-12-20 01:14:43 -0300257 msleep(wait_ms);
Steven Tothaacb9d32007-12-18 01:55:51 -0300258}
259
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300260static int xc5000_TunerReset(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300261{
262 struct xc5000_priv *priv = fe->tuner_priv;
263 int ret;
264
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300265 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300266
Michael Krufkyd7cba042008-09-12 13:31:45 -0300267 if (fe->callback) {
268 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
Michael Krufky30650962008-09-06 14:56:58 -0300269 fe->dvb->priv :
270 priv->i2c_props.adap->algo_data,
Michael Krufkyd7cba042008-09-12 13:31:45 -0300271 DVB_FRONTEND_COMPONENT_TUNER,
Michael Krufky30650962008-09-06 14:56:58 -0300272 XC5000_TUNER_RESET, 0);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300273 if (ret) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300274 printk(KERN_ERR "xc5000: reset failed\n");
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300275 return XC_RESULT_RESET_FAILURE;
276 }
277 } else {
Steven Toth27c685a2008-01-05 16:50:14 -0300278 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300279 return XC_RESULT_RESET_FAILURE;
280 }
281 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300282}
283
Steven Tothe12671c2007-12-20 01:14:43 -0300284static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
Steven Tothaacb9d32007-12-18 01:55:51 -0300285{
Steven Tothe12671c2007-12-20 01:14:43 -0300286 u8 buf[4];
Devin Heitmuellera37791c2009-05-04 23:29:17 -0300287 int WatchDogTimer = 100;
Steven Tothaacb9d32007-12-18 01:55:51 -0300288 int result;
289
290 buf[0] = (regAddr >> 8) & 0xFF;
291 buf[1] = regAddr & 0xFF;
292 buf[2] = (i2cData >> 8) & 0xFF;
293 buf[3] = i2cData & 0xFF;
294 result = xc_send_i2c_data(priv, buf, 4);
Steven Tothe12671c2007-12-20 01:14:43 -0300295 if (result == XC_RESULT_SUCCESS) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300296 /* wait for busy flag to clear */
297 while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
Dmitri Belimov47433192010-05-18 04:30:11 -0300298 result = xc5000_readreg(priv, XREG_BUSY, buf);
Steven Tothaacb9d32007-12-18 01:55:51 -0300299 if (result == XC_RESULT_SUCCESS) {
Dmitri Belimov47433192010-05-18 04:30:11 -0300300 if ((buf[0] == 0) && (buf[1] == 0)) {
301 /* busy flag cleared */
Steven Tothaacb9d32007-12-18 01:55:51 -0300302 break;
Dmitri Belimov47433192010-05-18 04:30:11 -0300303 } else {
304 xc_wait(5); /* wait 5 ms */
305 WatchDogTimer--;
Steven Tothaacb9d32007-12-18 01:55:51 -0300306 }
307 }
308 }
309 }
310 if (WatchDogTimer < 0)
311 result = XC_RESULT_I2C_WRITE_FAILURE;
312
313 return result;
314}
315
David Woodhousec63e87e2008-05-24 00:13:34 +0100316static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
Steven Tothaacb9d32007-12-18 01:55:51 -0300317{
318 struct xc5000_priv *priv = fe->tuner_priv;
319
320 int i, nbytes_to_send, result;
321 unsigned int len, pos, index;
Steven Tothe12671c2007-12-20 01:14:43 -0300322 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
Steven Tothaacb9d32007-12-18 01:55:51 -0300323
Steven Toth8f3cd532008-10-16 20:29:38 -0300324 index = 0;
325 while ((i2c_sequence[index] != 0xFF) ||
326 (i2c_sequence[index + 1] != 0xFF)) {
327 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
Steven Tothe12671c2007-12-20 01:14:43 -0300328 if (len == 0x0000) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300329 /* RESET command */
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300330 result = xc5000_TunerReset(fe);
Steven Tothaacb9d32007-12-18 01:55:51 -0300331 index += 2;
Steven Tothe12671c2007-12-20 01:14:43 -0300332 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300333 return result;
334 } else if (len & 0x8000) {
335 /* WAIT command */
336 xc_wait(len & 0x7FFF);
337 index += 2;
338 } else {
339 /* Send i2c data whilst ensuring individual transactions
340 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
341 */
342 index += 2;
343 buf[0] = i2c_sequence[index];
344 buf[1] = i2c_sequence[index + 1];
345 pos = 2;
346 while (pos < len) {
Steven Toth8f3cd532008-10-16 20:29:38 -0300347 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
348 nbytes_to_send =
349 XC_MAX_I2C_WRITE_LENGTH;
350 else
Steven Tothaacb9d32007-12-18 01:55:51 -0300351 nbytes_to_send = (len - pos + 2);
Steven Toth8f3cd532008-10-16 20:29:38 -0300352 for (i = 2; i < nbytes_to_send; i++) {
353 buf[i] = i2c_sequence[index + pos +
354 i - 2];
Steven Tothaacb9d32007-12-18 01:55:51 -0300355 }
Steven Toth8f3cd532008-10-16 20:29:38 -0300356 result = xc_send_i2c_data(priv, buf,
357 nbytes_to_send);
Steven Tothaacb9d32007-12-18 01:55:51 -0300358
Steven Tothe12671c2007-12-20 01:14:43 -0300359 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300360 return result;
361
362 pos += nbytes_to_send - 2;
363 }
364 index += len;
365 }
366 }
367 return XC_RESULT_SUCCESS;
368}
369
Steven Tothe12671c2007-12-20 01:14:43 -0300370static int xc_initialize(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300371{
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300372 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300373 return xc_write_reg(priv, XREG_INIT, 0);
374}
375
Steven Tothe12671c2007-12-20 01:14:43 -0300376static int xc_SetTVStandard(struct xc5000_priv *priv,
377 u16 VideoMode, u16 AudioMode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300378{
379 int ret;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300380 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
Steven Tothaacb9d32007-12-18 01:55:51 -0300381 dprintk(1, "%s() Standard = %s\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300382 __func__,
Steven Tothaacb9d32007-12-18 01:55:51 -0300383 XC5000_Standard[priv->video_standard].Name);
384
385 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
386 if (ret == XC_RESULT_SUCCESS)
387 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
388
389 return ret;
390}
391
Steven Tothe12671c2007-12-20 01:14:43 -0300392static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300393{
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300394 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
Steven Tothaacb9d32007-12-18 01:55:51 -0300395 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
396
Steven Toth8f3cd532008-10-16 20:29:38 -0300397 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300398 rf_mode = XC_RF_MODE_CABLE;
399 printk(KERN_ERR
400 "%s(), Invalid mode, defaulting to CABLE",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300401 __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300402 }
403 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
404}
405
Steven Tothe12671c2007-12-20 01:14:43 -0300406static const struct dvb_tuner_ops xc5000_tuner_ops;
407
408static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300409{
Steven Tothe12671c2007-12-20 01:14:43 -0300410 u16 freq_code;
Steven Tothaacb9d32007-12-18 01:55:51 -0300411
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300412 dprintk(1, "%s(%u)\n", __func__, freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300413
Steven Tothe12671c2007-12-20 01:14:43 -0300414 if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
415 (freq_hz < xc5000_tuner_ops.info.frequency_min))
416 return XC_RESULT_OUT_OF_RANGE;
Steven Tothaacb9d32007-12-18 01:55:51 -0300417
Steven Tothe12671c2007-12-20 01:14:43 -0300418 freq_code = (u16)(freq_hz / 15625);
419
Devin Heitmueller81c4dfe2009-04-02 22:40:29 -0300420 /* Starting in firmware version 1.1.44, Xceive recommends using the
421 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
422 only be used for fast scanning for channel lock) */
423 return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
Steven Tothaacb9d32007-12-18 01:55:51 -0300424}
425
Steven Tothe12671c2007-12-20 01:14:43 -0300426
427static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300428{
Steven Tothe12671c2007-12-20 01:14:43 -0300429 u32 freq_code = (freq_khz * 1024)/1000;
430 dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300431 __func__, freq_khz, freq_code);
Steven Tothe12671c2007-12-20 01:14:43 -0300432
433 return xc_write_reg(priv, XREG_IF_OUT, freq_code);
Steven Tothaacb9d32007-12-18 01:55:51 -0300434}
435
Steven Tothe12671c2007-12-20 01:14:43 -0300436
437static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
Steven Tothaacb9d32007-12-18 01:55:51 -0300438{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300439 return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
Steven Tothaacb9d32007-12-18 01:55:51 -0300440}
441
Steven Tothe12671c2007-12-20 01:14:43 -0300442static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300443{
444 int result;
Steven Tothe12671c2007-12-20 01:14:43 -0300445 u16 regData;
Steven Tothaacb9d32007-12-18 01:55:51 -0300446 u32 tmp;
447
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300448 result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300449 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300450 return result;
451
452 tmp = (u32)regData;
Steven Tothe12671c2007-12-20 01:14:43 -0300453 (*freq_error_hz) = (tmp * 15625) / 1000;
Steven Tothaacb9d32007-12-18 01:55:51 -0300454 return result;
455}
456
Steven Tothe12671c2007-12-20 01:14:43 -0300457static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
Steven Tothaacb9d32007-12-18 01:55:51 -0300458{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300459 return xc5000_readreg(priv, XREG_LOCK, lock_status);
Steven Tothaacb9d32007-12-18 01:55:51 -0300460}
461
Steven Tothe12671c2007-12-20 01:14:43 -0300462static int xc_get_version(struct xc5000_priv *priv,
463 u8 *hw_majorversion, u8 *hw_minorversion,
464 u8 *fw_majorversion, u8 *fw_minorversion)
Steven Tothaacb9d32007-12-18 01:55:51 -0300465{
Steven Tothe12671c2007-12-20 01:14:43 -0300466 u16 data;
Steven Tothaacb9d32007-12-18 01:55:51 -0300467 int result;
468
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300469 result = xc5000_readreg(priv, XREG_VERSION, &data);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300470 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300471 return result;
472
Steven Tothe12671c2007-12-20 01:14:43 -0300473 (*hw_majorversion) = (data >> 12) & 0x0F;
474 (*hw_minorversion) = (data >> 8) & 0x0F;
475 (*fw_majorversion) = (data >> 4) & 0x0F;
476 (*fw_minorversion) = data & 0x0F;
Steven Tothaacb9d32007-12-18 01:55:51 -0300477
478 return 0;
479}
480
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300481static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
482{
483 return xc5000_readreg(priv, XREG_BUILD, buildrev);
484}
485
Steven Tothe12671c2007-12-20 01:14:43 -0300486static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300487{
Steven Tothe12671c2007-12-20 01:14:43 -0300488 u16 regData;
Steven Tothaacb9d32007-12-18 01:55:51 -0300489 int result;
490
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300491 result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300492 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300493 return result;
494
495 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
496 return result;
497}
498
Steven Tothe12671c2007-12-20 01:14:43 -0300499static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
Steven Tothaacb9d32007-12-18 01:55:51 -0300500{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300501 return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
Steven Tothaacb9d32007-12-18 01:55:51 -0300502}
503
Steven Tothe12671c2007-12-20 01:14:43 -0300504static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
Steven Tothaacb9d32007-12-18 01:55:51 -0300505{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300506 return xc5000_readreg(priv, XREG_QUALITY, quality);
Steven Tothaacb9d32007-12-18 01:55:51 -0300507}
508
Steven Tothe12671c2007-12-20 01:14:43 -0300509static u16 WaitForLock(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300510{
Steven Tothe12671c2007-12-20 01:14:43 -0300511 u16 lockState = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300512 int watchDogCount = 40;
Steven Tothe12671c2007-12-20 01:14:43 -0300513
514 while ((lockState == 0) && (watchDogCount > 0)) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300515 xc_get_lock_status(priv, &lockState);
Steven Tothe12671c2007-12-20 01:14:43 -0300516 if (lockState != 1) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300517 xc_wait(5);
518 watchDogCount--;
519 }
520 }
521 return lockState;
522}
523
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300524#define XC_TUNE_ANALOG 0
525#define XC_TUNE_DIGITAL 1
526static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300527{
528 int found = 0;
529
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300530 dprintk(1, "%s(%u)\n", __func__, freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300531
Steven Tothe12671c2007-12-20 01:14:43 -0300532 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300533 return 0;
534
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300535 if (mode == XC_TUNE_ANALOG) {
536 if (WaitForLock(priv) == 1)
537 found = 1;
538 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300539
540 return found;
541}
542
Steven Tothaacb9d32007-12-18 01:55:51 -0300543
Steven Toth8f3cd532008-10-16 20:29:38 -0300544static int xc5000_fwupload(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300545{
546 struct xc5000_priv *priv = fe->tuner_priv;
547 const struct firmware *fw;
548 int ret;
549
Steven Tothe12671c2007-12-20 01:14:43 -0300550 /* request the firmware, this will block and timeout */
551 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
552 XC5000_DEFAULT_FIRMWARE);
553
Steven Toth8f3cd532008-10-16 20:29:38 -0300554 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
Jean Delvaree9785252009-04-26 05:43:59 -0300555 priv->i2c_props.adap->dev.parent);
Steven Tothaacb9d32007-12-18 01:55:51 -0300556 if (ret) {
557 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
558 ret = XC_RESULT_RESET_FAILURE;
Steven Toth5ea60532008-01-24 22:29:46 -0300559 goto out;
Steven Tothaacb9d32007-12-18 01:55:51 -0300560 } else {
Devin Heitmueller34a0db92009-04-02 22:45:17 -0300561 printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
Michael Krufky3f514512007-12-21 16:20:23 -0300562 fw->size);
Steven Tothaacb9d32007-12-18 01:55:51 -0300563 ret = XC_RESULT_SUCCESS;
564 }
565
Steven Tothe12671c2007-12-20 01:14:43 -0300566 if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300567 printk(KERN_ERR "xc5000: firmware incorrect size\n");
568 ret = XC_RESULT_RESET_FAILURE;
569 } else {
Devin Heitmueller34a0db92009-04-02 22:45:17 -0300570 printk(KERN_INFO "xc5000: firmware uploading...\n");
Steven Toth8f3cd532008-10-16 20:29:38 -0300571 ret = xc_load_i2c_sequence(fe, fw->data);
Devin Heitmueller34a0db92009-04-02 22:45:17 -0300572 printk(KERN_INFO "xc5000: firmware upload complete...\n");
Steven Tothaacb9d32007-12-18 01:55:51 -0300573 }
574
Steven Toth5ea60532008-01-24 22:29:46 -0300575out:
Steven Tothaacb9d32007-12-18 01:55:51 -0300576 release_firmware(fw);
577 return ret;
578}
579
Steven Tothe12671c2007-12-20 01:14:43 -0300580static void xc_debug_dump(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300581{
Steven Tothe12671c2007-12-20 01:14:43 -0300582 u16 adc_envelope;
583 u32 freq_error_hz = 0;
584 u16 lock_status;
585 u32 hsync_freq_hz = 0;
586 u16 frame_lines;
587 u16 quality;
588 u8 hw_majorversion = 0, hw_minorversion = 0;
589 u8 fw_majorversion = 0, fw_minorversion = 0;
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300590 u16 fw_buildversion = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300591
592 /* Wait for stats to stabilize.
593 * Frame Lines needs two frame times after initial lock
594 * before it is valid.
595 */
Steven Tothe12671c2007-12-20 01:14:43 -0300596 xc_wait(100);
Steven Tothaacb9d32007-12-18 01:55:51 -0300597
Steven Tothe12671c2007-12-20 01:14:43 -0300598 xc_get_ADC_Envelope(priv, &adc_envelope);
599 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
Steven Tothaacb9d32007-12-18 01:55:51 -0300600
Steven Tothe12671c2007-12-20 01:14:43 -0300601 xc_get_frequency_error(priv, &freq_error_hz);
602 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300603
Steven Tothe12671c2007-12-20 01:14:43 -0300604 xc_get_lock_status(priv, &lock_status);
605 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
Steven Tothaacb9d32007-12-18 01:55:51 -0300606 lock_status);
607
608 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
Steven Tothe12671c2007-12-20 01:14:43 -0300609 &fw_majorversion, &fw_minorversion);
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300610 xc_get_buildversion(priv, &fw_buildversion);
611 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
Steven Tothaacb9d32007-12-18 01:55:51 -0300612 hw_majorversion, hw_minorversion,
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300613 fw_majorversion, fw_minorversion, fw_buildversion);
Steven Tothaacb9d32007-12-18 01:55:51 -0300614
Steven Tothe12671c2007-12-20 01:14:43 -0300615 xc_get_hsync_freq(priv, &hsync_freq_hz);
616 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300617
Steven Tothe12671c2007-12-20 01:14:43 -0300618 xc_get_frame_lines(priv, &frame_lines);
619 dprintk(1, "*** Frame lines = %d\n", frame_lines);
Steven Tothaacb9d32007-12-18 01:55:51 -0300620
Steven Tothe12671c2007-12-20 01:14:43 -0300621 xc_get_quality(priv, &quality);
622 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
Steven Tothaacb9d32007-12-18 01:55:51 -0300623}
624
625static int xc5000_set_params(struct dvb_frontend *fe,
626 struct dvb_frontend_parameters *params)
627{
628 struct xc5000_priv *priv = fe->tuner_priv;
Steven Tothe12671c2007-12-20 01:14:43 -0300629 int ret;
Steven Tothaacb9d32007-12-18 01:55:51 -0300630
Devin Heitmueller760c4662009-10-13 23:44:14 -0300631 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
632 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
633 dprintk(1, "Unable to load firmware and init tuner\n");
634 return -EINVAL;
635 }
636 }
Devin Heitmueller8e4c6792008-11-16 20:41:07 -0300637
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300638 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
Steven Tothaacb9d32007-12-18 01:55:51 -0300639
David T.L. Wong6c990802009-05-04 22:59:58 -0300640 if (fe->ops.info.type == FE_ATSC) {
641 dprintk(1, "%s() ATSC\n", __func__);
642 switch (params->u.vsb.modulation) {
643 case VSB_8:
644 case VSB_16:
645 dprintk(1, "%s() VSB modulation\n", __func__);
646 priv->rf_mode = XC_RF_MODE_AIR;
647 priv->freq_hz = params->frequency - 1750000;
648 priv->bandwidth = BANDWIDTH_6_MHZ;
649 priv->video_standard = DTV6;
650 break;
651 case QAM_64:
652 case QAM_256:
653 case QAM_AUTO:
654 dprintk(1, "%s() QAM modulation\n", __func__);
655 priv->rf_mode = XC_RF_MODE_CABLE;
656 priv->freq_hz = params->frequency - 1750000;
657 priv->bandwidth = BANDWIDTH_6_MHZ;
658 priv->video_standard = DTV6;
659 break;
660 default:
661 return -EINVAL;
662 }
663 } else if (fe->ops.info.type == FE_OFDM) {
664 dprintk(1, "%s() OFDM\n", __func__);
665 switch (params->u.ofdm.bandwidth) {
666 case BANDWIDTH_6_MHZ:
667 priv->bandwidth = BANDWIDTH_6_MHZ;
668 priv->video_standard = DTV6;
669 priv->freq_hz = params->frequency - 1750000;
670 break;
671 case BANDWIDTH_7_MHZ:
672 printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n");
673 return -EINVAL;
674 case BANDWIDTH_8_MHZ:
675 priv->bandwidth = BANDWIDTH_8_MHZ;
676 priv->video_standard = DTV8;
677 priv->freq_hz = params->frequency - 2750000;
678 break;
679 default:
680 printk(KERN_ERR "xc5000 bandwidth not set!\n");
681 return -EINVAL;
682 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300683 priv->rf_mode = XC_RF_MODE_AIR;
David T.L. Wong6c990802009-05-04 22:59:58 -0300684 } else {
685 printk(KERN_ERR "xc5000 modulation type not supported!\n");
Steven Tothaacb9d32007-12-18 01:55:51 -0300686 return -EINVAL;
687 }
688
689 dprintk(1, "%s() frequency=%d (compensated)\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300690 __func__, priv->freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300691
Steven Tothe12671c2007-12-20 01:14:43 -0300692 ret = xc_SetSignalSource(priv, priv->rf_mode);
693 if (ret != XC_RESULT_SUCCESS) {
694 printk(KERN_ERR
695 "xc5000: xc_SetSignalSource(%d) failed\n",
696 priv->rf_mode);
697 return -EREMOTEIO;
698 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300699
Steven Tothe12671c2007-12-20 01:14:43 -0300700 ret = xc_SetTVStandard(priv,
Steven Tothaacb9d32007-12-18 01:55:51 -0300701 XC5000_Standard[priv->video_standard].VideoMode,
702 XC5000_Standard[priv->video_standard].AudioMode);
Steven Tothe12671c2007-12-20 01:14:43 -0300703 if (ret != XC_RESULT_SUCCESS) {
704 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
705 return -EREMOTEIO;
706 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300707
Michael Krufky2a6003c2008-09-06 13:54:45 -0300708 ret = xc_set_IF_frequency(priv, priv->if_khz);
Steven Tothe12671c2007-12-20 01:14:43 -0300709 if (ret != XC_RESULT_SUCCESS) {
710 printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
Michael Krufky2a6003c2008-09-06 13:54:45 -0300711 priv->if_khz);
Steven Tothe12671c2007-12-20 01:14:43 -0300712 return -EIO;
713 }
714
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300715 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
Steven Tothe12671c2007-12-20 01:14:43 -0300716
717 if (debug)
718 xc_debug_dump(priv);
Steven Tothaacb9d32007-12-18 01:55:51 -0300719
720 return 0;
721}
722
Steven Tothe470d812008-06-21 21:06:02 -0300723static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
724{
725 struct xc5000_priv *priv = fe->tuner_priv;
726 int ret;
727 u16 id;
728
729 ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
730 if (ret == XC_RESULT_SUCCESS) {
731 if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
732 ret = XC_RESULT_RESET_FAILURE;
733 else
734 ret = XC_RESULT_SUCCESS;
735 }
736
737 dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
738 ret == XC_RESULT_SUCCESS ? "True" : "False", id);
739 return ret;
740}
741
Beholder Intl. Ltd. Dmitry Belimovd7009cd2009-09-24 13:13:28 -0300742static int xc5000_set_tv_freq(struct dvb_frontend *fe,
Steven Toth27c685a2008-01-05 16:50:14 -0300743 struct analog_parameters *params)
744{
745 struct xc5000_priv *priv = fe->tuner_priv;
746 int ret;
747
Steven Toth27c685a2008-01-05 16:50:14 -0300748 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300749 __func__, params->frequency);
Steven Toth27c685a2008-01-05 16:50:14 -0300750
Mauro Carvalho Chehab1fab14e2009-03-03 14:35:41 -0300751 /* Fix me: it could be air. */
752 priv->rf_mode = params->mode;
753 if (params->mode > XC_RF_MODE_CABLE)
754 priv->rf_mode = XC_RF_MODE_CABLE;
Steven Toth27c685a2008-01-05 16:50:14 -0300755
756 /* params->frequency is in units of 62.5khz */
757 priv->freq_hz = params->frequency * 62500;
758
759 /* FIX ME: Some video standards may have several possible audio
760 standards. We simply default to one of them here.
761 */
Steven Toth8f3cd532008-10-16 20:29:38 -0300762 if (params->std & V4L2_STD_MN) {
Steven Toth27c685a2008-01-05 16:50:14 -0300763 /* default to BTSC audio standard */
764 priv->video_standard = MN_NTSC_PAL_BTSC;
765 goto tune_channel;
766 }
767
Steven Toth8f3cd532008-10-16 20:29:38 -0300768 if (params->std & V4L2_STD_PAL_BG) {
Steven Toth27c685a2008-01-05 16:50:14 -0300769 /* default to NICAM audio standard */
770 priv->video_standard = BG_PAL_NICAM;
771 goto tune_channel;
772 }
773
Steven Toth8f3cd532008-10-16 20:29:38 -0300774 if (params->std & V4L2_STD_PAL_I) {
Steven Toth27c685a2008-01-05 16:50:14 -0300775 /* default to NICAM audio standard */
776 priv->video_standard = I_PAL_NICAM;
777 goto tune_channel;
778 }
779
Steven Toth8f3cd532008-10-16 20:29:38 -0300780 if (params->std & V4L2_STD_PAL_DK) {
Steven Toth27c685a2008-01-05 16:50:14 -0300781 /* default to NICAM audio standard */
782 priv->video_standard = DK_PAL_NICAM;
783 goto tune_channel;
784 }
785
Steven Toth8f3cd532008-10-16 20:29:38 -0300786 if (params->std & V4L2_STD_SECAM_DK) {
Steven Toth27c685a2008-01-05 16:50:14 -0300787 /* default to A2 DK1 audio standard */
788 priv->video_standard = DK_SECAM_A2DK1;
789 goto tune_channel;
790 }
791
Steven Toth8f3cd532008-10-16 20:29:38 -0300792 if (params->std & V4L2_STD_SECAM_L) {
Steven Toth27c685a2008-01-05 16:50:14 -0300793 priv->video_standard = L_SECAM_NICAM;
794 goto tune_channel;
795 }
796
Steven Toth8f3cd532008-10-16 20:29:38 -0300797 if (params->std & V4L2_STD_SECAM_LC) {
Steven Toth27c685a2008-01-05 16:50:14 -0300798 priv->video_standard = LC_SECAM_NICAM;
799 goto tune_channel;
800 }
801
802tune_channel:
803 ret = xc_SetSignalSource(priv, priv->rf_mode);
804 if (ret != XC_RESULT_SUCCESS) {
Steven Toth8f3cd532008-10-16 20:29:38 -0300805 printk(KERN_ERR
Steven Toth27c685a2008-01-05 16:50:14 -0300806 "xc5000: xc_SetSignalSource(%d) failed\n",
807 priv->rf_mode);
808 return -EREMOTEIO;
809 }
810
811 ret = xc_SetTVStandard(priv,
812 XC5000_Standard[priv->video_standard].VideoMode,
813 XC5000_Standard[priv->video_standard].AudioMode);
814 if (ret != XC_RESULT_SUCCESS) {
815 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
816 return -EREMOTEIO;
817 }
818
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300819 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
Steven Toth27c685a2008-01-05 16:50:14 -0300820
821 if (debug)
822 xc_debug_dump(priv);
823
824 return 0;
825}
826
Beholder Intl. Ltd. Dmitry Belimovd7009cd2009-09-24 13:13:28 -0300827static int xc5000_set_radio_freq(struct dvb_frontend *fe,
828 struct analog_parameters *params)
829{
830 struct xc5000_priv *priv = fe->tuner_priv;
831 int ret = -EINVAL;
Devin Heitmueller496e9052009-09-24 13:27:24 -0300832 u8 radio_input;
Beholder Intl. Ltd. Dmitry Belimovd7009cd2009-09-24 13:13:28 -0300833
834 dprintk(1, "%s() frequency=%d (in units of khz)\n",
835 __func__, params->frequency);
836
Devin Heitmueller496e9052009-09-24 13:27:24 -0300837 if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
838 dprintk(1, "%s() radio input not configured\n", __func__);
839 return -EINVAL;
840 }
841
842 if (priv->radio_input == XC5000_RADIO_FM1)
843 radio_input = FM_Radio_INPUT1;
844 else if (priv->radio_input == XC5000_RADIO_FM2)
845 radio_input = FM_Radio_INPUT2;
846 else {
847 dprintk(1, "%s() unknown radio input %d\n", __func__,
848 priv->radio_input);
849 return -EINVAL;
850 }
851
Beholder Intl. Ltd. Dmitry Belimovd7009cd2009-09-24 13:13:28 -0300852 priv->freq_hz = params->frequency * 125 / 2;
853
854 priv->rf_mode = XC_RF_MODE_AIR;
855
Devin Heitmueller496e9052009-09-24 13:27:24 -0300856 ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
857 XC5000_Standard[radio_input].AudioMode);
Beholder Intl. Ltd. Dmitry Belimovd7009cd2009-09-24 13:13:28 -0300858
859 if (ret != XC_RESULT_SUCCESS) {
860 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
861 return -EREMOTEIO;
862 }
863
864 ret = xc_SetSignalSource(priv, priv->rf_mode);
865 if (ret != XC_RESULT_SUCCESS) {
866 printk(KERN_ERR
867 "xc5000: xc_SetSignalSource(%d) failed\n",
868 priv->rf_mode);
869 return -EREMOTEIO;
870 }
871
872 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
873
874 return 0;
875}
876
877static int xc5000_set_analog_params(struct dvb_frontend *fe,
878 struct analog_parameters *params)
879{
880 struct xc5000_priv *priv = fe->tuner_priv;
881 int ret = -EINVAL;
882
883 if (priv->i2c_props.adap == NULL)
884 return -EINVAL;
885
Devin Heitmueller760c4662009-10-13 23:44:14 -0300886 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
887 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
888 dprintk(1, "Unable to load firmware and init tuner\n");
889 return -EINVAL;
890 }
891 }
Beholder Intl. Ltd. Dmitry Belimovd7009cd2009-09-24 13:13:28 -0300892
893 switch (params->mode) {
894 case V4L2_TUNER_RADIO:
895 ret = xc5000_set_radio_freq(fe, params);
896 break;
897 case V4L2_TUNER_ANALOG_TV:
898 case V4L2_TUNER_DIGITAL_TV:
899 ret = xc5000_set_tv_freq(fe, params);
900 break;
901 }
902
903 return ret;
904}
905
906
Steven Tothaacb9d32007-12-18 01:55:51 -0300907static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
908{
909 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300910 dprintk(1, "%s()\n", __func__);
Steven Tothe12671c2007-12-20 01:14:43 -0300911 *freq = priv->freq_hz;
Steven Tothaacb9d32007-12-18 01:55:51 -0300912 return 0;
913}
914
915static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
916{
917 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300918 dprintk(1, "%s()\n", __func__);
Steven Toth27c685a2008-01-05 16:50:14 -0300919
Steven Tothaacb9d32007-12-18 01:55:51 -0300920 *bw = priv->bandwidth;
921 return 0;
922}
923
924static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
925{
926 struct xc5000_priv *priv = fe->tuner_priv;
Steven Tothe12671c2007-12-20 01:14:43 -0300927 u16 lock_status = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300928
929 xc_get_lock_status(priv, &lock_status);
930
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300931 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
Steven Tothaacb9d32007-12-18 01:55:51 -0300932
933 *status = lock_status;
934
935 return 0;
936}
937
Steven Tothe12671c2007-12-20 01:14:43 -0300938static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300939{
940 struct xc5000_priv *priv = fe->tuner_priv;
Steven Toth27c685a2008-01-05 16:50:14 -0300941 int ret = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300942
Steven Tothe470d812008-06-21 21:06:02 -0300943 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300944 ret = xc5000_fwupload(fe);
Steven Tothe12671c2007-12-20 01:14:43 -0300945 if (ret != XC_RESULT_SUCCESS)
946 return ret;
Steven Tothaacb9d32007-12-18 01:55:51 -0300947 }
948
949 /* Start the tuner self-calibration process */
950 ret |= xc_initialize(priv);
951
952 /* Wait for calibration to complete.
953 * We could continue but XC5000 will clock stretch subsequent
954 * I2C transactions until calibration is complete. This way we
955 * don't have to rely on clock stretching working.
956 */
Steven Toth8f3cd532008-10-16 20:29:38 -0300957 xc_wait(100);
Steven Tothaacb9d32007-12-18 01:55:51 -0300958
959 /* Default to "CABLE" mode */
960 ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
961
962 return ret;
963}
964
Steven Tothe12671c2007-12-20 01:14:43 -0300965static int xc5000_sleep(struct dvb_frontend *fe)
966{
Steven Toth27c685a2008-01-05 16:50:14 -0300967 int ret;
968
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300969 dprintk(1, "%s()\n", __func__);
Steven Tothe12671c2007-12-20 01:14:43 -0300970
Devin Heitmuellerb6bd5eb2009-04-28 13:53:38 -0300971 /* Avoid firmware reload on slow devices */
972 if (no_poweroff)
973 return 0;
974
Devin Heitmueller7f05b532009-04-02 22:02:39 -0300975 /* According to Xceive technical support, the "powerdown" register
976 was removed in newer versions of the firmware. The "supported"
977 way to sleep the tuner is to pull the reset pin low for 10ms */
978 ret = xc5000_TunerReset(fe);
Steven Toth8f3cd532008-10-16 20:29:38 -0300979 if (ret != XC_RESULT_SUCCESS) {
Steven Toth27c685a2008-01-05 16:50:14 -0300980 printk(KERN_ERR
981 "xc5000: %s() unable to shutdown tuner\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300982 __func__);
Steven Toth27c685a2008-01-05 16:50:14 -0300983 return -EREMOTEIO;
Steven Toth8f3cd532008-10-16 20:29:38 -0300984 } else
Steven Toth27c685a2008-01-05 16:50:14 -0300985 return XC_RESULT_SUCCESS;
Steven Tothe12671c2007-12-20 01:14:43 -0300986}
987
Steven Tothaacb9d32007-12-18 01:55:51 -0300988static int xc5000_init(struct dvb_frontend *fe)
989{
990 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300991 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300992
Steven Tothe12671c2007-12-20 01:14:43 -0300993 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
994 printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
995 return -EREMOTEIO;
996 }
997
998 if (debug)
999 xc_debug_dump(priv);
Steven Tothaacb9d32007-12-18 01:55:51 -03001000
1001 return 0;
1002}
1003
1004static int xc5000_release(struct dvb_frontend *fe)
1005{
Michael Krufky89fd2852008-09-06 11:44:53 -03001006 struct xc5000_priv *priv = fe->tuner_priv;
1007
Harvey Harrison271ddbf2008-04-08 23:20:00 -03001008 dprintk(1, "%s()\n", __func__);
Michael Krufky89fd2852008-09-06 11:44:53 -03001009
1010 mutex_lock(&xc5000_list_mutex);
1011
1012 if (priv)
1013 hybrid_tuner_release_state(priv);
1014
1015 mutex_unlock(&xc5000_list_mutex);
1016
Steven Tothaacb9d32007-12-18 01:55:51 -03001017 fe->tuner_priv = NULL;
Michael Krufky89fd2852008-09-06 11:44:53 -03001018
Steven Tothaacb9d32007-12-18 01:55:51 -03001019 return 0;
1020}
1021
1022static const struct dvb_tuner_ops xc5000_tuner_ops = {
1023 .info = {
1024 .name = "Xceive XC5000",
1025 .frequency_min = 1000000,
1026 .frequency_max = 1023000000,
1027 .frequency_step = 50000,
1028 },
1029
Steven Toth27c685a2008-01-05 16:50:14 -03001030 .release = xc5000_release,
1031 .init = xc5000_init,
1032 .sleep = xc5000_sleep,
Steven Tothaacb9d32007-12-18 01:55:51 -03001033
Steven Toth27c685a2008-01-05 16:50:14 -03001034 .set_params = xc5000_set_params,
1035 .set_analog_params = xc5000_set_analog_params,
1036 .get_frequency = xc5000_get_frequency,
1037 .get_bandwidth = xc5000_get_bandwidth,
1038 .get_status = xc5000_get_status
Steven Tothaacb9d32007-12-18 01:55:51 -03001039};
1040
Michael Krufky48723542008-05-10 14:34:09 -03001041struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1042 struct i2c_adapter *i2c,
Michael Krufky30650962008-09-06 14:56:58 -03001043 struct xc5000_config *cfg)
Steven Tothaacb9d32007-12-18 01:55:51 -03001044{
1045 struct xc5000_priv *priv = NULL;
Michael Krufky89fd2852008-09-06 11:44:53 -03001046 int instance;
Steven Tothaacb9d32007-12-18 01:55:51 -03001047 u16 id = 0;
1048
Michael Krufky89fd2852008-09-06 11:44:53 -03001049 dprintk(1, "%s(%d-%04x)\n", __func__,
1050 i2c ? i2c_adapter_id(i2c) : -1,
1051 cfg ? cfg->i2c_address : -1);
Steven Tothaacb9d32007-12-18 01:55:51 -03001052
Michael Krufky89fd2852008-09-06 11:44:53 -03001053 mutex_lock(&xc5000_list_mutex);
Steven Tothaacb9d32007-12-18 01:55:51 -03001054
Michael Krufky89fd2852008-09-06 11:44:53 -03001055 instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
1056 hybrid_tuner_instance_list,
1057 i2c, cfg->i2c_address, "xc5000");
1058 switch (instance) {
1059 case 0:
1060 goto fail;
1061 break;
1062 case 1:
1063 /* new tuner instance */
Michael Krufky89fd2852008-09-06 11:44:53 -03001064 priv->bandwidth = BANDWIDTH_6_MHZ;
Michael Krufky89fd2852008-09-06 11:44:53 -03001065 fe->tuner_priv = priv;
1066 break;
1067 default:
1068 /* existing tuner instance */
1069 fe->tuner_priv = priv;
1070 break;
1071 }
Steven Tothaacb9d32007-12-18 01:55:51 -03001072
Devin Heitmuellerea227862009-03-11 02:58:53 -03001073 if (priv->if_khz == 0) {
1074 /* If the IF hasn't been set yet, use the value provided by
1075 the caller (occurs in hybrid devices where the analog
1076 call to xc5000_attach occurs before the digital side) */
1077 priv->if_khz = cfg->if_khz;
1078 }
1079
Devin Heitmueller496e9052009-09-24 13:27:24 -03001080 if (priv->radio_input == 0)
1081 priv->radio_input = cfg->radio_input;
1082
Steven Toth27c685a2008-01-05 16:50:14 -03001083 /* Check if firmware has been loaded. It is possible that another
1084 instance of the driver has loaded the firmware.
1085 */
Devin Heitmueller7988fc22008-11-16 20:23:19 -03001086 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
Michael Krufky89fd2852008-09-06 11:44:53 -03001087 goto fail;
Steven Tothaacb9d32007-12-18 01:55:51 -03001088
Steven Toth8f3cd532008-10-16 20:29:38 -03001089 switch (id) {
Steven Toth27c685a2008-01-05 16:50:14 -03001090 case XC_PRODUCT_ID_FW_LOADED:
1091 printk(KERN_INFO
1092 "xc5000: Successfully identified at address 0x%02x\n",
1093 cfg->i2c_address);
1094 printk(KERN_INFO
1095 "xc5000: Firmware has been loaded previously\n");
Steven Toth27c685a2008-01-05 16:50:14 -03001096 break;
1097 case XC_PRODUCT_ID_FW_NOT_LOADED:
1098 printk(KERN_INFO
1099 "xc5000: Successfully identified at address 0x%02x\n",
1100 cfg->i2c_address);
1101 printk(KERN_INFO
1102 "xc5000: Firmware has not been loaded previously\n");
Steven Toth27c685a2008-01-05 16:50:14 -03001103 break;
1104 default:
Steven Tothaacb9d32007-12-18 01:55:51 -03001105 printk(KERN_ERR
1106 "xc5000: Device not found at addr 0x%02x (0x%x)\n",
1107 cfg->i2c_address, id);
Michael Krufky89fd2852008-09-06 11:44:53 -03001108 goto fail;
Steven Tothaacb9d32007-12-18 01:55:51 -03001109 }
1110
Michael Krufky89fd2852008-09-06 11:44:53 -03001111 mutex_unlock(&xc5000_list_mutex);
1112
Steven Tothaacb9d32007-12-18 01:55:51 -03001113 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
1114 sizeof(struct dvb_tuner_ops));
1115
Steven Tothaacb9d32007-12-18 01:55:51 -03001116 return fe;
Michael Krufky89fd2852008-09-06 11:44:53 -03001117fail:
1118 mutex_unlock(&xc5000_list_mutex);
1119
1120 xc5000_release(fe);
1121 return NULL;
Steven Tothaacb9d32007-12-18 01:55:51 -03001122}
1123EXPORT_SYMBOL(xc5000_attach);
1124
1125MODULE_AUTHOR("Steven Toth");
Steven Tothe12671c2007-12-20 01:14:43 -03001126MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
Steven Tothaacb9d32007-12-18 01:55:51 -03001127MODULE_LICENSE("GPL");