blob: 8d3e31b6effc45ddb6191bbb2c83b99aa14c06c9 [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>
Steven Tothaacb9d32007-12-18 01:55:51 -03006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
Steven Toth49170192008-01-15 21:57:14 -030025#include <linux/videodev2.h>
Steven Tothaacb9d32007-12-18 01:55:51 -030026#include <linux/delay.h>
27#include <linux/dvb/frontend.h>
28#include <linux/i2c.h>
29
30#include "dvb_frontend.h"
31
32#include "xc5000.h"
Michael Krufky89fd2852008-09-06 11:44:53 -030033#include "tuner-i2c.h"
Steven Tothaacb9d32007-12-18 01:55:51 -030034
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
38
Michael Krufky89fd2852008-09-06 11:44:53 -030039static DEFINE_MUTEX(xc5000_list_mutex);
40static LIST_HEAD(hybrid_tuner_instance_list);
41
Steven Toth8f3cd532008-10-16 20:29:38 -030042#define dprintk(level, fmt, arg...) if (debug >= level) \
Steven Tothaacb9d32007-12-18 01:55:51 -030043 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
44
Devin Heitmueller361d4892009-04-02 21:50:11 -030045#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.4.68.fw"
46#define XC5000_DEFAULT_FIRMWARE_SIZE 12378
Steven Tothaacb9d32007-12-18 01:55:51 -030047
Michael Krufkyffb41232008-09-06 10:52:30 -030048struct xc5000_priv {
Michael Krufky89fd2852008-09-06 11:44:53 -030049 struct tuner_i2c_props i2c_props;
50 struct list_head hybrid_tuner_instance_list;
Michael Krufkyffb41232008-09-06 10:52:30 -030051
Michael Krufky2a6003c2008-09-06 13:54:45 -030052 u32 if_khz;
Michael Krufkyffb41232008-09-06 10:52:30 -030053 u32 freq_hz;
54 u32 bandwidth;
55 u8 video_standard;
56 u8 rf_mode;
Michael Krufkyffb41232008-09-06 10:52:30 -030057};
58
Steven Tothaacb9d32007-12-18 01:55:51 -030059/* Misc Defines */
60#define MAX_TV_STANDARD 23
61#define XC_MAX_I2C_WRITE_LENGTH 64
62
63/* Signal Types */
64#define XC_RF_MODE_AIR 0
65#define XC_RF_MODE_CABLE 1
66
67/* Result codes */
68#define XC_RESULT_SUCCESS 0
69#define XC_RESULT_RESET_FAILURE 1
70#define XC_RESULT_I2C_WRITE_FAILURE 2
71#define XC_RESULT_I2C_READ_FAILURE 3
72#define XC_RESULT_OUT_OF_RANGE 5
73
Steven Toth27c685a2008-01-05 16:50:14 -030074/* Product id */
75#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
76#define XC_PRODUCT_ID_FW_LOADED 0x1388
77
Steven Tothaacb9d32007-12-18 01:55:51 -030078/* Registers */
79#define XREG_INIT 0x00
80#define XREG_VIDEO_MODE 0x01
81#define XREG_AUDIO_MODE 0x02
82#define XREG_RF_FREQ 0x03
83#define XREG_D_CODE 0x04
84#define XREG_IF_OUT 0x05
85#define XREG_SEEK_MODE 0x07
Devin Heitmueller7f05b532009-04-02 22:02:39 -030086#define XREG_POWER_DOWN 0x0A /* Obsolete */
Steven Tothaacb9d32007-12-18 01:55:51 -030087#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
88#define XREG_SMOOTHEDCVBS 0x0E
89#define XREG_XTALFREQ 0x0F
90#define XREG_FINERFFREQ 0x10
91#define XREG_DDIMODE 0x11
92
93#define XREG_ADC_ENV 0x00
94#define XREG_QUALITY 0x01
95#define XREG_FRAME_LINES 0x02
96#define XREG_HSYNC_FREQ 0x03
97#define XREG_LOCK 0x04
98#define XREG_FREQ_ERROR 0x05
99#define XREG_SNR 0x06
100#define XREG_VERSION 0x07
101#define XREG_PRODUCT_ID 0x08
102#define XREG_BUSY 0x09
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300103#define XREG_BUILD 0x0D
Steven Tothaacb9d32007-12-18 01:55:51 -0300104
105/*
106 Basic firmware description. This will remain with
107 the driver for documentation purposes.
108
109 This represents an I2C firmware file encoded as a
110 string of unsigned char. Format is as follows:
111
112 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
113 char[1 ]=len0_LSB -> length of first write transaction
114 char[2 ]=data0 -> first byte to be sent
115 char[3 ]=data1
116 char[4 ]=data2
117 char[ ]=...
118 char[M ]=dataN -> last byte to be sent
119 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
120 char[M+2]=len1_LSB -> length of second write transaction
121 char[M+3]=data0
122 char[M+4]=data1
123 ...
124 etc.
125
126 The [len] value should be interpreted as follows:
127
128 len= len_MSB _ len_LSB
129 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
130 len=0000_0000_0000_0000 : Reset command: Do hardware reset
131 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
132 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
133
134 For the RESET and WAIT commands, the two following bytes will contain
135 immediately the length of the following transaction.
136
137*/
Steven Toth8f3cd532008-10-16 20:29:38 -0300138struct XC_TV_STANDARD {
Steven Tothaacb9d32007-12-18 01:55:51 -0300139 char *Name;
Steven Tothe12671c2007-12-20 01:14:43 -0300140 u16 AudioMode;
141 u16 VideoMode;
Steven Toth8f3cd532008-10-16 20:29:38 -0300142};
Steven Tothaacb9d32007-12-18 01:55:51 -0300143
144/* Tuner standards */
Steven Toth27c685a2008-01-05 16:50:14 -0300145#define MN_NTSC_PAL_BTSC 0
146#define MN_NTSC_PAL_A2 1
147#define MN_NTSC_PAL_EIAJ 2
148#define MN_NTSC_PAL_Mono 3
149#define BG_PAL_A2 4
150#define BG_PAL_NICAM 5
151#define BG_PAL_MONO 6
152#define I_PAL_NICAM 7
153#define I_PAL_NICAM_MONO 8
154#define DK_PAL_A2 9
155#define DK_PAL_NICAM 10
156#define DK_PAL_MONO 11
157#define DK_SECAM_A2DK1 12
158#define DK_SECAM_A2LDK3 13
159#define DK_SECAM_A2MONO 14
160#define L_SECAM_NICAM 15
161#define LC_SECAM_NICAM 16
162#define DTV6 17
163#define DTV8 18
164#define DTV7_8 19
165#define DTV7 20
166#define FM_Radio_INPUT2 21
167#define FM_Radio_INPUT1 22
Steven Tothaacb9d32007-12-18 01:55:51 -0300168
Steven Toth8f3cd532008-10-16 20:29:38 -0300169static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
Steven Tothaacb9d32007-12-18 01:55:51 -0300170 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
171 {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
172 {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
173 {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
174 {"B/G-PAL-A2", 0x0A00, 0x8049},
175 {"B/G-PAL-NICAM", 0x0C04, 0x8049},
176 {"B/G-PAL-MONO", 0x0878, 0x8059},
177 {"I-PAL-NICAM", 0x1080, 0x8009},
178 {"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
179 {"D/K-PAL-A2", 0x1600, 0x8009},
180 {"D/K-PAL-NICAM", 0x0E80, 0x8009},
181 {"D/K-PAL-MONO", 0x1478, 0x8009},
182 {"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
Steven Toth8f3cd532008-10-16 20:29:38 -0300183 {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
Steven Tothaacb9d32007-12-18 01:55:51 -0300184 {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
185 {"L-SECAM-NICAM", 0x8E82, 0x0009},
186 {"L'-SECAM-NICAM", 0x8E82, 0x4009},
187 {"DTV6", 0x00C0, 0x8002},
188 {"DTV8", 0x00C0, 0x800B},
189 {"DTV7/8", 0x00C0, 0x801B},
190 {"DTV7", 0x00C0, 0x8007},
191 {"FM Radio-INPUT2", 0x9802, 0x9002},
192 {"FM Radio-INPUT1", 0x0208, 0x9002}
193};
194
Devin Heitmueller8e4c6792008-11-16 20:41:07 -0300195static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300196static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300197static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300198static int xc5000_TunerReset(struct dvb_frontend *fe);
Steven Tothaacb9d32007-12-18 01:55:51 -0300199
Steven Tothe12671c2007-12-20 01:14:43 -0300200static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
Steven Tothaacb9d32007-12-18 01:55:51 -0300201{
Devin Heitmuellerd7800d42008-11-16 20:20:06 -0300202 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
203 .flags = 0, .buf = buf, .len = len };
204
205 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
206 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
207 return XC_RESULT_I2C_WRITE_FAILURE;
208 }
209 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300210}
211
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300212/* This routine is never used because the only time we read data from the
213 i2c bus is when we read registers, and we want that to be an atomic i2c
214 transaction in case we are on a multi-master bus */
Steven Tothe12671c2007-12-20 01:14:43 -0300215static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
Steven Tothaacb9d32007-12-18 01:55:51 -0300216{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300217 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
218 .flags = I2C_M_RD, .buf = buf, .len = len };
219
220 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
221 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
222 return -EREMOTEIO;
223 }
224 return 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300225}
226
Steven Tothe12671c2007-12-20 01:14:43 -0300227static void xc_wait(int wait_ms)
Steven Tothaacb9d32007-12-18 01:55:51 -0300228{
Steven Tothe12671c2007-12-20 01:14:43 -0300229 msleep(wait_ms);
Steven Tothaacb9d32007-12-18 01:55:51 -0300230}
231
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300232static int xc5000_TunerReset(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300233{
234 struct xc5000_priv *priv = fe->tuner_priv;
235 int ret;
236
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300237 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300238
Michael Krufkyd7cba042008-09-12 13:31:45 -0300239 if (fe->callback) {
240 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
Michael Krufky30650962008-09-06 14:56:58 -0300241 fe->dvb->priv :
242 priv->i2c_props.adap->algo_data,
Michael Krufkyd7cba042008-09-12 13:31:45 -0300243 DVB_FRONTEND_COMPONENT_TUNER,
Michael Krufky30650962008-09-06 14:56:58 -0300244 XC5000_TUNER_RESET, 0);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300245 if (ret) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300246 printk(KERN_ERR "xc5000: reset failed\n");
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300247 return XC_RESULT_RESET_FAILURE;
248 }
249 } else {
Steven Toth27c685a2008-01-05 16:50:14 -0300250 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300251 return XC_RESULT_RESET_FAILURE;
252 }
253 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300254}
255
Steven Tothe12671c2007-12-20 01:14:43 -0300256static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
Steven Tothaacb9d32007-12-18 01:55:51 -0300257{
Steven Tothe12671c2007-12-20 01:14:43 -0300258 u8 buf[4];
Steven Tothaacb9d32007-12-18 01:55:51 -0300259 int WatchDogTimer = 5;
260 int result;
261
262 buf[0] = (regAddr >> 8) & 0xFF;
263 buf[1] = regAddr & 0xFF;
264 buf[2] = (i2cData >> 8) & 0xFF;
265 buf[3] = i2cData & 0xFF;
266 result = xc_send_i2c_data(priv, buf, 4);
Steven Tothe12671c2007-12-20 01:14:43 -0300267 if (result == XC_RESULT_SUCCESS) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300268 /* wait for busy flag to clear */
269 while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
270 buf[0] = 0;
271 buf[1] = XREG_BUSY;
272
273 result = xc_send_i2c_data(priv, buf, 2);
274 if (result == XC_RESULT_SUCCESS) {
275 result = xc_read_i2c_data(priv, buf, 2);
276 if (result == XC_RESULT_SUCCESS) {
277 if ((buf[0] == 0) && (buf[1] == 0)) {
278 /* busy flag cleared */
279 break;
280 } else {
281 xc_wait(100); /* wait 5 ms */
282 WatchDogTimer--;
283 }
284 }
285 }
286 }
287 }
288 if (WatchDogTimer < 0)
289 result = XC_RESULT_I2C_WRITE_FAILURE;
290
291 return result;
292}
293
David Woodhousec63e87e2008-05-24 00:13:34 +0100294static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
Steven Tothaacb9d32007-12-18 01:55:51 -0300295{
296 struct xc5000_priv *priv = fe->tuner_priv;
297
298 int i, nbytes_to_send, result;
299 unsigned int len, pos, index;
Steven Tothe12671c2007-12-20 01:14:43 -0300300 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
Steven Tothaacb9d32007-12-18 01:55:51 -0300301
Steven Toth8f3cd532008-10-16 20:29:38 -0300302 index = 0;
303 while ((i2c_sequence[index] != 0xFF) ||
304 (i2c_sequence[index + 1] != 0xFF)) {
305 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
Steven Tothe12671c2007-12-20 01:14:43 -0300306 if (len == 0x0000) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300307 /* RESET command */
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300308 result = xc5000_TunerReset(fe);
Steven Tothaacb9d32007-12-18 01:55:51 -0300309 index += 2;
Steven Tothe12671c2007-12-20 01:14:43 -0300310 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300311 return result;
312 } else if (len & 0x8000) {
313 /* WAIT command */
314 xc_wait(len & 0x7FFF);
315 index += 2;
316 } else {
317 /* Send i2c data whilst ensuring individual transactions
318 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
319 */
320 index += 2;
321 buf[0] = i2c_sequence[index];
322 buf[1] = i2c_sequence[index + 1];
323 pos = 2;
324 while (pos < len) {
Steven Toth8f3cd532008-10-16 20:29:38 -0300325 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
326 nbytes_to_send =
327 XC_MAX_I2C_WRITE_LENGTH;
328 else
Steven Tothaacb9d32007-12-18 01:55:51 -0300329 nbytes_to_send = (len - pos + 2);
Steven Toth8f3cd532008-10-16 20:29:38 -0300330 for (i = 2; i < nbytes_to_send; i++) {
331 buf[i] = i2c_sequence[index + pos +
332 i - 2];
Steven Tothaacb9d32007-12-18 01:55:51 -0300333 }
Steven Toth8f3cd532008-10-16 20:29:38 -0300334 result = xc_send_i2c_data(priv, buf,
335 nbytes_to_send);
Steven Tothaacb9d32007-12-18 01:55:51 -0300336
Steven Tothe12671c2007-12-20 01:14:43 -0300337 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300338 return result;
339
340 pos += nbytes_to_send - 2;
341 }
342 index += len;
343 }
344 }
345 return XC_RESULT_SUCCESS;
346}
347
Steven Tothe12671c2007-12-20 01:14:43 -0300348static int xc_initialize(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300349{
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300350 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300351 return xc_write_reg(priv, XREG_INIT, 0);
352}
353
Steven Tothe12671c2007-12-20 01:14:43 -0300354static int xc_SetTVStandard(struct xc5000_priv *priv,
355 u16 VideoMode, u16 AudioMode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300356{
357 int ret;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300358 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
Steven Tothaacb9d32007-12-18 01:55:51 -0300359 dprintk(1, "%s() Standard = %s\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300360 __func__,
Steven Tothaacb9d32007-12-18 01:55:51 -0300361 XC5000_Standard[priv->video_standard].Name);
362
363 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
364 if (ret == XC_RESULT_SUCCESS)
365 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
366
367 return ret;
368}
369
Steven Tothe12671c2007-12-20 01:14:43 -0300370static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300371{
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300372 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
Steven Tothaacb9d32007-12-18 01:55:51 -0300373 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
374
Steven Toth8f3cd532008-10-16 20:29:38 -0300375 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300376 rf_mode = XC_RF_MODE_CABLE;
377 printk(KERN_ERR
378 "%s(), Invalid mode, defaulting to CABLE",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300379 __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300380 }
381 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
382}
383
Steven Tothe12671c2007-12-20 01:14:43 -0300384static const struct dvb_tuner_ops xc5000_tuner_ops;
385
386static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300387{
Steven Tothe12671c2007-12-20 01:14:43 -0300388 u16 freq_code;
Steven Tothaacb9d32007-12-18 01:55:51 -0300389
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300390 dprintk(1, "%s(%u)\n", __func__, freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300391
Steven Tothe12671c2007-12-20 01:14:43 -0300392 if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
393 (freq_hz < xc5000_tuner_ops.info.frequency_min))
394 return XC_RESULT_OUT_OF_RANGE;
Steven Tothaacb9d32007-12-18 01:55:51 -0300395
Steven Tothe12671c2007-12-20 01:14:43 -0300396 freq_code = (u16)(freq_hz / 15625);
397
398 return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
Steven Tothaacb9d32007-12-18 01:55:51 -0300399}
400
Steven Tothe12671c2007-12-20 01:14:43 -0300401
402static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300403{
Steven Tothe12671c2007-12-20 01:14:43 -0300404 u32 freq_code = (freq_khz * 1024)/1000;
405 dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300406 __func__, freq_khz, freq_code);
Steven Tothe12671c2007-12-20 01:14:43 -0300407
408 return xc_write_reg(priv, XREG_IF_OUT, freq_code);
Steven Tothaacb9d32007-12-18 01:55:51 -0300409}
410
Steven Tothe12671c2007-12-20 01:14:43 -0300411
412static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
Steven Tothaacb9d32007-12-18 01:55:51 -0300413{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300414 return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
Steven Tothaacb9d32007-12-18 01:55:51 -0300415}
416
Steven Tothe12671c2007-12-20 01:14:43 -0300417static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300418{
419 int result;
Steven Tothe12671c2007-12-20 01:14:43 -0300420 u16 regData;
Steven Tothaacb9d32007-12-18 01:55:51 -0300421 u32 tmp;
422
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300423 result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300424 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300425 return result;
426
427 tmp = (u32)regData;
Steven Tothe12671c2007-12-20 01:14:43 -0300428 (*freq_error_hz) = (tmp * 15625) / 1000;
Steven Tothaacb9d32007-12-18 01:55:51 -0300429 return result;
430}
431
Steven Tothe12671c2007-12-20 01:14:43 -0300432static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
Steven Tothaacb9d32007-12-18 01:55:51 -0300433{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300434 return xc5000_readreg(priv, XREG_LOCK, lock_status);
Steven Tothaacb9d32007-12-18 01:55:51 -0300435}
436
Steven Tothe12671c2007-12-20 01:14:43 -0300437static int xc_get_version(struct xc5000_priv *priv,
438 u8 *hw_majorversion, u8 *hw_minorversion,
439 u8 *fw_majorversion, u8 *fw_minorversion)
Steven Tothaacb9d32007-12-18 01:55:51 -0300440{
Steven Tothe12671c2007-12-20 01:14:43 -0300441 u16 data;
Steven Tothaacb9d32007-12-18 01:55:51 -0300442 int result;
443
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300444 result = xc5000_readreg(priv, XREG_VERSION, &data);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300445 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300446 return result;
447
Steven Tothe12671c2007-12-20 01:14:43 -0300448 (*hw_majorversion) = (data >> 12) & 0x0F;
449 (*hw_minorversion) = (data >> 8) & 0x0F;
450 (*fw_majorversion) = (data >> 4) & 0x0F;
451 (*fw_minorversion) = data & 0x0F;
Steven Tothaacb9d32007-12-18 01:55:51 -0300452
453 return 0;
454}
455
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300456static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
457{
458 return xc5000_readreg(priv, XREG_BUILD, buildrev);
459}
460
Steven Tothe12671c2007-12-20 01:14:43 -0300461static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300462{
Steven Tothe12671c2007-12-20 01:14:43 -0300463 u16 regData;
Steven Tothaacb9d32007-12-18 01:55:51 -0300464 int result;
465
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300466 result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300467 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300468 return result;
469
470 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
471 return result;
472}
473
Steven Tothe12671c2007-12-20 01:14:43 -0300474static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
Steven Tothaacb9d32007-12-18 01:55:51 -0300475{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300476 return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
Steven Tothaacb9d32007-12-18 01:55:51 -0300477}
478
Steven Tothe12671c2007-12-20 01:14:43 -0300479static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
Steven Tothaacb9d32007-12-18 01:55:51 -0300480{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300481 return xc5000_readreg(priv, XREG_QUALITY, quality);
Steven Tothaacb9d32007-12-18 01:55:51 -0300482}
483
Steven Tothe12671c2007-12-20 01:14:43 -0300484static u16 WaitForLock(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300485{
Steven Tothe12671c2007-12-20 01:14:43 -0300486 u16 lockState = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300487 int watchDogCount = 40;
Steven Tothe12671c2007-12-20 01:14:43 -0300488
489 while ((lockState == 0) && (watchDogCount > 0)) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300490 xc_get_lock_status(priv, &lockState);
Steven Tothe12671c2007-12-20 01:14:43 -0300491 if (lockState != 1) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300492 xc_wait(5);
493 watchDogCount--;
494 }
495 }
496 return lockState;
497}
498
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300499#define XC_TUNE_ANALOG 0
500#define XC_TUNE_DIGITAL 1
501static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300502{
503 int found = 0;
504
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300505 dprintk(1, "%s(%u)\n", __func__, freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300506
Steven Tothe12671c2007-12-20 01:14:43 -0300507 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300508 return 0;
509
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300510 if (mode == XC_TUNE_ANALOG) {
511 if (WaitForLock(priv) == 1)
512 found = 1;
513 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300514
515 return found;
516}
517
518static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
519{
520 u8 buf[2] = { reg >> 8, reg & 0xff };
521 u8 bval[2] = { 0, 0 };
522 struct i2c_msg msg[2] = {
Michael Krufky89fd2852008-09-06 11:44:53 -0300523 { .addr = priv->i2c_props.addr,
Steven Tothaacb9d32007-12-18 01:55:51 -0300524 .flags = 0, .buf = &buf[0], .len = 2 },
Michael Krufky89fd2852008-09-06 11:44:53 -0300525 { .addr = priv->i2c_props.addr,
Steven Tothaacb9d32007-12-18 01:55:51 -0300526 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
527 };
528
Michael Krufky89fd2852008-09-06 11:44:53 -0300529 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
Steven Toth27c685a2008-01-05 16:50:14 -0300530 printk(KERN_WARNING "xc5000: I2C read failed\n");
Steven Tothaacb9d32007-12-18 01:55:51 -0300531 return -EREMOTEIO;
532 }
533
534 *val = (bval[0] << 8) | bval[1];
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300535 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300536}
537
Steven Toth8f3cd532008-10-16 20:29:38 -0300538static int xc5000_fwupload(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300539{
540 struct xc5000_priv *priv = fe->tuner_priv;
541 const struct firmware *fw;
542 int ret;
543
Steven Tothe12671c2007-12-20 01:14:43 -0300544 /* request the firmware, this will block and timeout */
545 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
546 XC5000_DEFAULT_FIRMWARE);
547
Steven Toth8f3cd532008-10-16 20:29:38 -0300548 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
Jean Delvaree9785252009-04-26 05:43:59 -0300549 priv->i2c_props.adap->dev.parent);
Steven Tothaacb9d32007-12-18 01:55:51 -0300550 if (ret) {
551 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
552 ret = XC_RESULT_RESET_FAILURE;
Steven Toth5ea60532008-01-24 22:29:46 -0300553 goto out;
Steven Tothaacb9d32007-12-18 01:55:51 -0300554 } else {
Michael Krufky3f514512007-12-21 16:20:23 -0300555 printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n",
556 fw->size);
Steven Tothaacb9d32007-12-18 01:55:51 -0300557 ret = XC_RESULT_SUCCESS;
558 }
559
Steven Tothe12671c2007-12-20 01:14:43 -0300560 if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300561 printk(KERN_ERR "xc5000: firmware incorrect size\n");
562 ret = XC_RESULT_RESET_FAILURE;
563 } else {
564 printk(KERN_INFO "xc5000: firmware upload\n");
Steven Toth8f3cd532008-10-16 20:29:38 -0300565 ret = xc_load_i2c_sequence(fe, fw->data);
Steven Tothaacb9d32007-12-18 01:55:51 -0300566 }
567
Steven Toth5ea60532008-01-24 22:29:46 -0300568out:
Steven Tothaacb9d32007-12-18 01:55:51 -0300569 release_firmware(fw);
570 return ret;
571}
572
Steven Tothe12671c2007-12-20 01:14:43 -0300573static void xc_debug_dump(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300574{
Steven Tothe12671c2007-12-20 01:14:43 -0300575 u16 adc_envelope;
576 u32 freq_error_hz = 0;
577 u16 lock_status;
578 u32 hsync_freq_hz = 0;
579 u16 frame_lines;
580 u16 quality;
581 u8 hw_majorversion = 0, hw_minorversion = 0;
582 u8 fw_majorversion = 0, fw_minorversion = 0;
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300583 u16 fw_buildversion = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300584
585 /* Wait for stats to stabilize.
586 * Frame Lines needs two frame times after initial lock
587 * before it is valid.
588 */
Steven Tothe12671c2007-12-20 01:14:43 -0300589 xc_wait(100);
Steven Tothaacb9d32007-12-18 01:55:51 -0300590
Steven Tothe12671c2007-12-20 01:14:43 -0300591 xc_get_ADC_Envelope(priv, &adc_envelope);
592 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
Steven Tothaacb9d32007-12-18 01:55:51 -0300593
Steven Tothe12671c2007-12-20 01:14:43 -0300594 xc_get_frequency_error(priv, &freq_error_hz);
595 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300596
Steven Tothe12671c2007-12-20 01:14:43 -0300597 xc_get_lock_status(priv, &lock_status);
598 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
Steven Tothaacb9d32007-12-18 01:55:51 -0300599 lock_status);
600
601 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
Steven Tothe12671c2007-12-20 01:14:43 -0300602 &fw_majorversion, &fw_minorversion);
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300603 xc_get_buildversion(priv, &fw_buildversion);
604 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
Steven Tothaacb9d32007-12-18 01:55:51 -0300605 hw_majorversion, hw_minorversion,
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300606 fw_majorversion, fw_minorversion, fw_buildversion);
Steven Tothaacb9d32007-12-18 01:55:51 -0300607
Steven Tothe12671c2007-12-20 01:14:43 -0300608 xc_get_hsync_freq(priv, &hsync_freq_hz);
609 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300610
Steven Tothe12671c2007-12-20 01:14:43 -0300611 xc_get_frame_lines(priv, &frame_lines);
612 dprintk(1, "*** Frame lines = %d\n", frame_lines);
Steven Tothaacb9d32007-12-18 01:55:51 -0300613
Steven Tothe12671c2007-12-20 01:14:43 -0300614 xc_get_quality(priv, &quality);
615 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
Steven Tothaacb9d32007-12-18 01:55:51 -0300616}
617
618static int xc5000_set_params(struct dvb_frontend *fe,
619 struct dvb_frontend_parameters *params)
620{
621 struct xc5000_priv *priv = fe->tuner_priv;
Steven Tothe12671c2007-12-20 01:14:43 -0300622 int ret;
Steven Tothaacb9d32007-12-18 01:55:51 -0300623
Devin Heitmueller8e4c6792008-11-16 20:41:07 -0300624 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
625 xc_load_fw_and_init_tuner(fe);
626
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300627 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
Steven Tothaacb9d32007-12-18 01:55:51 -0300628
Steven Toth8f3cd532008-10-16 20:29:38 -0300629 switch (params->u.vsb.modulation) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300630 case VSB_8:
631 case VSB_16:
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300632 dprintk(1, "%s() VSB modulation\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300633 priv->rf_mode = XC_RF_MODE_AIR;
Steven Tothe12671c2007-12-20 01:14:43 -0300634 priv->freq_hz = params->frequency - 1750000;
635 priv->bandwidth = BANDWIDTH_6_MHZ;
636 priv->video_standard = DTV6;
Steven Tothaacb9d32007-12-18 01:55:51 -0300637 break;
638 case QAM_64:
639 case QAM_256:
640 case QAM_AUTO:
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300641 dprintk(1, "%s() QAM modulation\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300642 priv->rf_mode = XC_RF_MODE_CABLE;
Steven Tothe12671c2007-12-20 01:14:43 -0300643 priv->freq_hz = params->frequency - 1750000;
644 priv->bandwidth = BANDWIDTH_6_MHZ;
645 priv->video_standard = DTV6;
Steven Tothaacb9d32007-12-18 01:55:51 -0300646 break;
647 default:
648 return -EINVAL;
649 }
650
651 dprintk(1, "%s() frequency=%d (compensated)\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300652 __func__, priv->freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300653
Steven Tothe12671c2007-12-20 01:14:43 -0300654 ret = xc_SetSignalSource(priv, priv->rf_mode);
655 if (ret != XC_RESULT_SUCCESS) {
656 printk(KERN_ERR
657 "xc5000: xc_SetSignalSource(%d) failed\n",
658 priv->rf_mode);
659 return -EREMOTEIO;
660 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300661
Steven Tothe12671c2007-12-20 01:14:43 -0300662 ret = xc_SetTVStandard(priv,
Steven Tothaacb9d32007-12-18 01:55:51 -0300663 XC5000_Standard[priv->video_standard].VideoMode,
664 XC5000_Standard[priv->video_standard].AudioMode);
Steven Tothe12671c2007-12-20 01:14:43 -0300665 if (ret != XC_RESULT_SUCCESS) {
666 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
667 return -EREMOTEIO;
668 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300669
Michael Krufky2a6003c2008-09-06 13:54:45 -0300670 ret = xc_set_IF_frequency(priv, priv->if_khz);
Steven Tothe12671c2007-12-20 01:14:43 -0300671 if (ret != XC_RESULT_SUCCESS) {
672 printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
Michael Krufky2a6003c2008-09-06 13:54:45 -0300673 priv->if_khz);
Steven Tothe12671c2007-12-20 01:14:43 -0300674 return -EIO;
675 }
676
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300677 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
Steven Tothe12671c2007-12-20 01:14:43 -0300678
679 if (debug)
680 xc_debug_dump(priv);
Steven Tothaacb9d32007-12-18 01:55:51 -0300681
682 return 0;
683}
684
Steven Tothe470d812008-06-21 21:06:02 -0300685static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
686{
687 struct xc5000_priv *priv = fe->tuner_priv;
688 int ret;
689 u16 id;
690
691 ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
692 if (ret == XC_RESULT_SUCCESS) {
693 if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
694 ret = XC_RESULT_RESET_FAILURE;
695 else
696 ret = XC_RESULT_SUCCESS;
697 }
698
699 dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
700 ret == XC_RESULT_SUCCESS ? "True" : "False", id);
701 return ret;
702}
703
Steven Toth27c685a2008-01-05 16:50:14 -0300704static int xc5000_set_analog_params(struct dvb_frontend *fe,
705 struct analog_parameters *params)
706{
707 struct xc5000_priv *priv = fe->tuner_priv;
708 int ret;
709
Steven Tothe470d812008-06-21 21:06:02 -0300710 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
Steven Toth27c685a2008-01-05 16:50:14 -0300711 xc_load_fw_and_init_tuner(fe);
712
713 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300714 __func__, params->frequency);
Steven Toth27c685a2008-01-05 16:50:14 -0300715
Mauro Carvalho Chehab1fab14e2009-03-03 14:35:41 -0300716 /* Fix me: it could be air. */
717 priv->rf_mode = params->mode;
718 if (params->mode > XC_RF_MODE_CABLE)
719 priv->rf_mode = XC_RF_MODE_CABLE;
Steven Toth27c685a2008-01-05 16:50:14 -0300720
721 /* params->frequency is in units of 62.5khz */
722 priv->freq_hz = params->frequency * 62500;
723
724 /* FIX ME: Some video standards may have several possible audio
725 standards. We simply default to one of them here.
726 */
Steven Toth8f3cd532008-10-16 20:29:38 -0300727 if (params->std & V4L2_STD_MN) {
Steven Toth27c685a2008-01-05 16:50:14 -0300728 /* default to BTSC audio standard */
729 priv->video_standard = MN_NTSC_PAL_BTSC;
730 goto tune_channel;
731 }
732
Steven Toth8f3cd532008-10-16 20:29:38 -0300733 if (params->std & V4L2_STD_PAL_BG) {
Steven Toth27c685a2008-01-05 16:50:14 -0300734 /* default to NICAM audio standard */
735 priv->video_standard = BG_PAL_NICAM;
736 goto tune_channel;
737 }
738
Steven Toth8f3cd532008-10-16 20:29:38 -0300739 if (params->std & V4L2_STD_PAL_I) {
Steven Toth27c685a2008-01-05 16:50:14 -0300740 /* default to NICAM audio standard */
741 priv->video_standard = I_PAL_NICAM;
742 goto tune_channel;
743 }
744
Steven Toth8f3cd532008-10-16 20:29:38 -0300745 if (params->std & V4L2_STD_PAL_DK) {
Steven Toth27c685a2008-01-05 16:50:14 -0300746 /* default to NICAM audio standard */
747 priv->video_standard = DK_PAL_NICAM;
748 goto tune_channel;
749 }
750
Steven Toth8f3cd532008-10-16 20:29:38 -0300751 if (params->std & V4L2_STD_SECAM_DK) {
Steven Toth27c685a2008-01-05 16:50:14 -0300752 /* default to A2 DK1 audio standard */
753 priv->video_standard = DK_SECAM_A2DK1;
754 goto tune_channel;
755 }
756
Steven Toth8f3cd532008-10-16 20:29:38 -0300757 if (params->std & V4L2_STD_SECAM_L) {
Steven Toth27c685a2008-01-05 16:50:14 -0300758 priv->video_standard = L_SECAM_NICAM;
759 goto tune_channel;
760 }
761
Steven Toth8f3cd532008-10-16 20:29:38 -0300762 if (params->std & V4L2_STD_SECAM_LC) {
Steven Toth27c685a2008-01-05 16:50:14 -0300763 priv->video_standard = LC_SECAM_NICAM;
764 goto tune_channel;
765 }
766
767tune_channel:
768 ret = xc_SetSignalSource(priv, priv->rf_mode);
769 if (ret != XC_RESULT_SUCCESS) {
Steven Toth8f3cd532008-10-16 20:29:38 -0300770 printk(KERN_ERR
Steven Toth27c685a2008-01-05 16:50:14 -0300771 "xc5000: xc_SetSignalSource(%d) failed\n",
772 priv->rf_mode);
773 return -EREMOTEIO;
774 }
775
776 ret = xc_SetTVStandard(priv,
777 XC5000_Standard[priv->video_standard].VideoMode,
778 XC5000_Standard[priv->video_standard].AudioMode);
779 if (ret != XC_RESULT_SUCCESS) {
780 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
781 return -EREMOTEIO;
782 }
783
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300784 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
Steven Toth27c685a2008-01-05 16:50:14 -0300785
786 if (debug)
787 xc_debug_dump(priv);
788
789 return 0;
790}
791
Steven Tothaacb9d32007-12-18 01:55:51 -0300792static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
793{
794 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300795 dprintk(1, "%s()\n", __func__);
Steven Tothe12671c2007-12-20 01:14:43 -0300796 *freq = priv->freq_hz;
Steven Tothaacb9d32007-12-18 01:55:51 -0300797 return 0;
798}
799
800static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
801{
802 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300803 dprintk(1, "%s()\n", __func__);
Steven Toth27c685a2008-01-05 16:50:14 -0300804
Steven Tothaacb9d32007-12-18 01:55:51 -0300805 *bw = priv->bandwidth;
806 return 0;
807}
808
809static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
810{
811 struct xc5000_priv *priv = fe->tuner_priv;
Steven Tothe12671c2007-12-20 01:14:43 -0300812 u16 lock_status = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300813
814 xc_get_lock_status(priv, &lock_status);
815
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300816 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
Steven Tothaacb9d32007-12-18 01:55:51 -0300817
818 *status = lock_status;
819
820 return 0;
821}
822
Steven Tothe12671c2007-12-20 01:14:43 -0300823static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300824{
825 struct xc5000_priv *priv = fe->tuner_priv;
Steven Toth27c685a2008-01-05 16:50:14 -0300826 int ret = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300827
Steven Tothe470d812008-06-21 21:06:02 -0300828 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300829 ret = xc5000_fwupload(fe);
Steven Tothe12671c2007-12-20 01:14:43 -0300830 if (ret != XC_RESULT_SUCCESS)
831 return ret;
Steven Tothaacb9d32007-12-18 01:55:51 -0300832 }
833
834 /* Start the tuner self-calibration process */
835 ret |= xc_initialize(priv);
836
837 /* Wait for calibration to complete.
838 * We could continue but XC5000 will clock stretch subsequent
839 * I2C transactions until calibration is complete. This way we
840 * don't have to rely on clock stretching working.
841 */
Steven Toth8f3cd532008-10-16 20:29:38 -0300842 xc_wait(100);
Steven Tothaacb9d32007-12-18 01:55:51 -0300843
844 /* Default to "CABLE" mode */
845 ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
846
847 return ret;
848}
849
Steven Tothe12671c2007-12-20 01:14:43 -0300850static int xc5000_sleep(struct dvb_frontend *fe)
851{
Steven Toth27c685a2008-01-05 16:50:14 -0300852 int ret;
853
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300854 dprintk(1, "%s()\n", __func__);
Steven Tothe12671c2007-12-20 01:14:43 -0300855
Devin Heitmueller7f05b532009-04-02 22:02:39 -0300856 /* According to Xceive technical support, the "powerdown" register
857 was removed in newer versions of the firmware. The "supported"
858 way to sleep the tuner is to pull the reset pin low for 10ms */
859 ret = xc5000_TunerReset(fe);
Steven Toth8f3cd532008-10-16 20:29:38 -0300860 if (ret != XC_RESULT_SUCCESS) {
Steven Toth27c685a2008-01-05 16:50:14 -0300861 printk(KERN_ERR
862 "xc5000: %s() unable to shutdown tuner\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300863 __func__);
Steven Toth27c685a2008-01-05 16:50:14 -0300864 return -EREMOTEIO;
Steven Toth8f3cd532008-10-16 20:29:38 -0300865 } else
Steven Toth27c685a2008-01-05 16:50:14 -0300866 return XC_RESULT_SUCCESS;
Steven Tothe12671c2007-12-20 01:14:43 -0300867}
868
Steven Tothaacb9d32007-12-18 01:55:51 -0300869static int xc5000_init(struct dvb_frontend *fe)
870{
871 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300872 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300873
Steven Tothe12671c2007-12-20 01:14:43 -0300874 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
875 printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
876 return -EREMOTEIO;
877 }
878
879 if (debug)
880 xc_debug_dump(priv);
Steven Tothaacb9d32007-12-18 01:55:51 -0300881
882 return 0;
883}
884
885static int xc5000_release(struct dvb_frontend *fe)
886{
Michael Krufky89fd2852008-09-06 11:44:53 -0300887 struct xc5000_priv *priv = fe->tuner_priv;
888
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300889 dprintk(1, "%s()\n", __func__);
Michael Krufky89fd2852008-09-06 11:44:53 -0300890
891 mutex_lock(&xc5000_list_mutex);
892
893 if (priv)
894 hybrid_tuner_release_state(priv);
895
896 mutex_unlock(&xc5000_list_mutex);
897
Steven Tothaacb9d32007-12-18 01:55:51 -0300898 fe->tuner_priv = NULL;
Michael Krufky89fd2852008-09-06 11:44:53 -0300899
Steven Tothaacb9d32007-12-18 01:55:51 -0300900 return 0;
901}
902
903static const struct dvb_tuner_ops xc5000_tuner_ops = {
904 .info = {
905 .name = "Xceive XC5000",
906 .frequency_min = 1000000,
907 .frequency_max = 1023000000,
908 .frequency_step = 50000,
909 },
910
Steven Toth27c685a2008-01-05 16:50:14 -0300911 .release = xc5000_release,
912 .init = xc5000_init,
913 .sleep = xc5000_sleep,
Steven Tothaacb9d32007-12-18 01:55:51 -0300914
Steven Toth27c685a2008-01-05 16:50:14 -0300915 .set_params = xc5000_set_params,
916 .set_analog_params = xc5000_set_analog_params,
917 .get_frequency = xc5000_get_frequency,
918 .get_bandwidth = xc5000_get_bandwidth,
919 .get_status = xc5000_get_status
Steven Tothaacb9d32007-12-18 01:55:51 -0300920};
921
Michael Krufky48723542008-05-10 14:34:09 -0300922struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
923 struct i2c_adapter *i2c,
Michael Krufky30650962008-09-06 14:56:58 -0300924 struct xc5000_config *cfg)
Steven Tothaacb9d32007-12-18 01:55:51 -0300925{
926 struct xc5000_priv *priv = NULL;
Michael Krufky89fd2852008-09-06 11:44:53 -0300927 int instance;
Steven Tothaacb9d32007-12-18 01:55:51 -0300928 u16 id = 0;
929
Michael Krufky89fd2852008-09-06 11:44:53 -0300930 dprintk(1, "%s(%d-%04x)\n", __func__,
931 i2c ? i2c_adapter_id(i2c) : -1,
932 cfg ? cfg->i2c_address : -1);
Steven Tothaacb9d32007-12-18 01:55:51 -0300933
Michael Krufky89fd2852008-09-06 11:44:53 -0300934 mutex_lock(&xc5000_list_mutex);
Steven Tothaacb9d32007-12-18 01:55:51 -0300935
Michael Krufky89fd2852008-09-06 11:44:53 -0300936 instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
937 hybrid_tuner_instance_list,
938 i2c, cfg->i2c_address, "xc5000");
939 switch (instance) {
940 case 0:
941 goto fail;
942 break;
943 case 1:
944 /* new tuner instance */
Michael Krufky89fd2852008-09-06 11:44:53 -0300945 priv->bandwidth = BANDWIDTH_6_MHZ;
Michael Krufky89fd2852008-09-06 11:44:53 -0300946 fe->tuner_priv = priv;
947 break;
948 default:
949 /* existing tuner instance */
950 fe->tuner_priv = priv;
951 break;
952 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300953
Devin Heitmuellerea227862009-03-11 02:58:53 -0300954 if (priv->if_khz == 0) {
955 /* If the IF hasn't been set yet, use the value provided by
956 the caller (occurs in hybrid devices where the analog
957 call to xc5000_attach occurs before the digital side) */
958 priv->if_khz = cfg->if_khz;
959 }
960
Steven Toth27c685a2008-01-05 16:50:14 -0300961 /* Check if firmware has been loaded. It is possible that another
962 instance of the driver has loaded the firmware.
963 */
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300964 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
Michael Krufky89fd2852008-09-06 11:44:53 -0300965 goto fail;
Steven Tothaacb9d32007-12-18 01:55:51 -0300966
Steven Toth8f3cd532008-10-16 20:29:38 -0300967 switch (id) {
Steven Toth27c685a2008-01-05 16:50:14 -0300968 case XC_PRODUCT_ID_FW_LOADED:
969 printk(KERN_INFO
970 "xc5000: Successfully identified at address 0x%02x\n",
971 cfg->i2c_address);
972 printk(KERN_INFO
973 "xc5000: Firmware has been loaded previously\n");
Steven Toth27c685a2008-01-05 16:50:14 -0300974 break;
975 case XC_PRODUCT_ID_FW_NOT_LOADED:
976 printk(KERN_INFO
977 "xc5000: Successfully identified at address 0x%02x\n",
978 cfg->i2c_address);
979 printk(KERN_INFO
980 "xc5000: Firmware has not been loaded previously\n");
Steven Toth27c685a2008-01-05 16:50:14 -0300981 break;
982 default:
Steven Tothaacb9d32007-12-18 01:55:51 -0300983 printk(KERN_ERR
984 "xc5000: Device not found at addr 0x%02x (0x%x)\n",
985 cfg->i2c_address, id);
Michael Krufky89fd2852008-09-06 11:44:53 -0300986 goto fail;
Steven Tothaacb9d32007-12-18 01:55:51 -0300987 }
988
Michael Krufky89fd2852008-09-06 11:44:53 -0300989 mutex_unlock(&xc5000_list_mutex);
990
Steven Tothaacb9d32007-12-18 01:55:51 -0300991 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
992 sizeof(struct dvb_tuner_ops));
993
Steven Tothaacb9d32007-12-18 01:55:51 -0300994 return fe;
Michael Krufky89fd2852008-09-06 11:44:53 -0300995fail:
996 mutex_unlock(&xc5000_list_mutex);
997
998 xc5000_release(fe);
999 return NULL;
Steven Tothaacb9d32007-12-18 01:55:51 -03001000}
1001EXPORT_SYMBOL(xc5000_attach);
1002
1003MODULE_AUTHOR("Steven Toth");
Steven Tothe12671c2007-12-20 01:14:43 -03001004MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
Steven Tothaacb9d32007-12-18 01:55:51 -03001005MODULE_LICENSE("GPL");