blob: a75521caa41d78ee8d62e028860058c89ee053ac [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
Devin Heitmuellerb6bd5eb2009-04-28 13:53:38 -030039static int no_poweroff;
40module_param(no_poweroff, int, 0644);
41MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
42 "\t\t1 keep device energized and with tuner ready all the times.\n"
43 "\t\tFaster, but consumes more power and keeps the device hotter");
44
Michael Krufky89fd2852008-09-06 11:44:53 -030045static DEFINE_MUTEX(xc5000_list_mutex);
46static LIST_HEAD(hybrid_tuner_instance_list);
47
Steven Toth8f3cd532008-10-16 20:29:38 -030048#define dprintk(level, fmt, arg...) if (debug >= level) \
Steven Tothaacb9d32007-12-18 01:55:51 -030049 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
50
Devin Heitmuellera6301d12009-05-04 22:04:20 -030051#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
52#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
Steven Tothaacb9d32007-12-18 01:55:51 -030053
Michael Krufkyffb41232008-09-06 10:52:30 -030054struct xc5000_priv {
Michael Krufky89fd2852008-09-06 11:44:53 -030055 struct tuner_i2c_props i2c_props;
56 struct list_head hybrid_tuner_instance_list;
Michael Krufkyffb41232008-09-06 10:52:30 -030057
Michael Krufky2a6003c2008-09-06 13:54:45 -030058 u32 if_khz;
Michael Krufkyffb41232008-09-06 10:52:30 -030059 u32 freq_hz;
60 u32 bandwidth;
61 u8 video_standard;
62 u8 rf_mode;
Michael Krufkyffb41232008-09-06 10:52:30 -030063};
64
Steven Tothaacb9d32007-12-18 01:55:51 -030065/* Misc Defines */
66#define MAX_TV_STANDARD 23
67#define XC_MAX_I2C_WRITE_LENGTH 64
68
69/* Signal Types */
70#define XC_RF_MODE_AIR 0
71#define XC_RF_MODE_CABLE 1
72
73/* Result codes */
74#define XC_RESULT_SUCCESS 0
75#define XC_RESULT_RESET_FAILURE 1
76#define XC_RESULT_I2C_WRITE_FAILURE 2
77#define XC_RESULT_I2C_READ_FAILURE 3
78#define XC_RESULT_OUT_OF_RANGE 5
79
Steven Toth27c685a2008-01-05 16:50:14 -030080/* Product id */
81#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
82#define XC_PRODUCT_ID_FW_LOADED 0x1388
83
Steven Tothaacb9d32007-12-18 01:55:51 -030084/* Registers */
85#define XREG_INIT 0x00
86#define XREG_VIDEO_MODE 0x01
87#define XREG_AUDIO_MODE 0x02
88#define XREG_RF_FREQ 0x03
89#define XREG_D_CODE 0x04
90#define XREG_IF_OUT 0x05
91#define XREG_SEEK_MODE 0x07
Devin Heitmueller7f05b532009-04-02 22:02:39 -030092#define XREG_POWER_DOWN 0x0A /* Obsolete */
Steven Tothaacb9d32007-12-18 01:55:51 -030093#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
94#define XREG_SMOOTHEDCVBS 0x0E
95#define XREG_XTALFREQ 0x0F
Devin Heitmueller81c4dfe2009-04-02 22:40:29 -030096#define XREG_FINERFREQ 0x10
Steven Tothaacb9d32007-12-18 01:55:51 -030097#define XREG_DDIMODE 0x11
98
99#define XREG_ADC_ENV 0x00
100#define XREG_QUALITY 0x01
101#define XREG_FRAME_LINES 0x02
102#define XREG_HSYNC_FREQ 0x03
103#define XREG_LOCK 0x04
104#define XREG_FREQ_ERROR 0x05
105#define XREG_SNR 0x06
106#define XREG_VERSION 0x07
107#define XREG_PRODUCT_ID 0x08
108#define XREG_BUSY 0x09
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300109#define XREG_BUILD 0x0D
Steven Tothaacb9d32007-12-18 01:55:51 -0300110
111/*
112 Basic firmware description. This will remain with
113 the driver for documentation purposes.
114
115 This represents an I2C firmware file encoded as a
116 string of unsigned char. Format is as follows:
117
118 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
119 char[1 ]=len0_LSB -> length of first write transaction
120 char[2 ]=data0 -> first byte to be sent
121 char[3 ]=data1
122 char[4 ]=data2
123 char[ ]=...
124 char[M ]=dataN -> last byte to be sent
125 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
126 char[M+2]=len1_LSB -> length of second write transaction
127 char[M+3]=data0
128 char[M+4]=data1
129 ...
130 etc.
131
132 The [len] value should be interpreted as follows:
133
134 len= len_MSB _ len_LSB
135 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
136 len=0000_0000_0000_0000 : Reset command: Do hardware reset
137 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
138 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
139
140 For the RESET and WAIT commands, the two following bytes will contain
141 immediately the length of the following transaction.
142
143*/
Steven Toth8f3cd532008-10-16 20:29:38 -0300144struct XC_TV_STANDARD {
Steven Tothaacb9d32007-12-18 01:55:51 -0300145 char *Name;
Steven Tothe12671cf2007-12-20 01:14:43 -0300146 u16 AudioMode;
147 u16 VideoMode;
Steven Toth8f3cd532008-10-16 20:29:38 -0300148};
Steven Tothaacb9d32007-12-18 01:55:51 -0300149
150/* Tuner standards */
Steven Toth27c685a2008-01-05 16:50:14 -0300151#define MN_NTSC_PAL_BTSC 0
152#define MN_NTSC_PAL_A2 1
153#define MN_NTSC_PAL_EIAJ 2
154#define MN_NTSC_PAL_Mono 3
155#define BG_PAL_A2 4
156#define BG_PAL_NICAM 5
157#define BG_PAL_MONO 6
158#define I_PAL_NICAM 7
159#define I_PAL_NICAM_MONO 8
160#define DK_PAL_A2 9
161#define DK_PAL_NICAM 10
162#define DK_PAL_MONO 11
163#define DK_SECAM_A2DK1 12
164#define DK_SECAM_A2LDK3 13
165#define DK_SECAM_A2MONO 14
166#define L_SECAM_NICAM 15
167#define LC_SECAM_NICAM 16
168#define DTV6 17
169#define DTV8 18
170#define DTV7_8 19
171#define DTV7 20
172#define FM_Radio_INPUT2 21
173#define FM_Radio_INPUT1 22
Steven Tothaacb9d32007-12-18 01:55:51 -0300174
Steven Toth8f3cd532008-10-16 20:29:38 -0300175static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
Steven Tothaacb9d32007-12-18 01:55:51 -0300176 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
177 {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
178 {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
179 {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
180 {"B/G-PAL-A2", 0x0A00, 0x8049},
181 {"B/G-PAL-NICAM", 0x0C04, 0x8049},
182 {"B/G-PAL-MONO", 0x0878, 0x8059},
183 {"I-PAL-NICAM", 0x1080, 0x8009},
184 {"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
185 {"D/K-PAL-A2", 0x1600, 0x8009},
186 {"D/K-PAL-NICAM", 0x0E80, 0x8009},
187 {"D/K-PAL-MONO", 0x1478, 0x8009},
188 {"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
Steven Toth8f3cd532008-10-16 20:29:38 -0300189 {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
Steven Tothaacb9d32007-12-18 01:55:51 -0300190 {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
191 {"L-SECAM-NICAM", 0x8E82, 0x0009},
192 {"L'-SECAM-NICAM", 0x8E82, 0x4009},
193 {"DTV6", 0x00C0, 0x8002},
194 {"DTV8", 0x00C0, 0x800B},
195 {"DTV7/8", 0x00C0, 0x801B},
196 {"DTV7", 0x00C0, 0x8007},
197 {"FM Radio-INPUT2", 0x9802, 0x9002},
198 {"FM Radio-INPUT1", 0x0208, 0x9002}
199};
200
Devin Heitmueller8e4c6792008-11-16 20:41:07 -0300201static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300202static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300203static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300204static int xc5000_TunerReset(struct dvb_frontend *fe);
Steven Tothaacb9d32007-12-18 01:55:51 -0300205
Steven Tothe12671cf2007-12-20 01:14:43 -0300206static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
Steven Tothaacb9d32007-12-18 01:55:51 -0300207{
Devin Heitmuellerd7800d42008-11-16 20:20:06 -0300208 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
209 .flags = 0, .buf = buf, .len = len };
210
211 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
212 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
213 return XC_RESULT_I2C_WRITE_FAILURE;
214 }
215 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300216}
217
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300218/* This routine is never used because the only time we read data from the
219 i2c bus is when we read registers, and we want that to be an atomic i2c
220 transaction in case we are on a multi-master bus */
Steven Tothe12671cf2007-12-20 01:14:43 -0300221static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
Steven Tothaacb9d32007-12-18 01:55:51 -0300222{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300223 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
224 .flags = I2C_M_RD, .buf = buf, .len = len };
225
226 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
227 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
228 return -EREMOTEIO;
229 }
230 return 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300231}
232
Steven Tothe12671cf2007-12-20 01:14:43 -0300233static void xc_wait(int wait_ms)
Steven Tothaacb9d32007-12-18 01:55:51 -0300234{
Steven Tothe12671cf2007-12-20 01:14:43 -0300235 msleep(wait_ms);
Steven Tothaacb9d32007-12-18 01:55:51 -0300236}
237
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300238static int xc5000_TunerReset(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300239{
240 struct xc5000_priv *priv = fe->tuner_priv;
241 int ret;
242
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300243 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300244
Michael Krufkyd7cba042008-09-12 13:31:45 -0300245 if (fe->callback) {
246 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
Michael Krufky30650962008-09-06 14:56:58 -0300247 fe->dvb->priv :
248 priv->i2c_props.adap->algo_data,
Michael Krufkyd7cba042008-09-12 13:31:45 -0300249 DVB_FRONTEND_COMPONENT_TUNER,
Michael Krufky30650962008-09-06 14:56:58 -0300250 XC5000_TUNER_RESET, 0);
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300251 if (ret) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300252 printk(KERN_ERR "xc5000: reset failed\n");
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300253 return XC_RESULT_RESET_FAILURE;
254 }
255 } else {
Steven Toth27c685a2008-01-05 16:50:14 -0300256 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300257 return XC_RESULT_RESET_FAILURE;
258 }
259 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300260}
261
Steven Tothe12671cf2007-12-20 01:14:43 -0300262static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
Steven Tothaacb9d32007-12-18 01:55:51 -0300263{
Steven Tothe12671cf2007-12-20 01:14:43 -0300264 u8 buf[4];
Steven Tothaacb9d32007-12-18 01:55:51 -0300265 int WatchDogTimer = 5;
266 int result;
267
268 buf[0] = (regAddr >> 8) & 0xFF;
269 buf[1] = regAddr & 0xFF;
270 buf[2] = (i2cData >> 8) & 0xFF;
271 buf[3] = i2cData & 0xFF;
272 result = xc_send_i2c_data(priv, buf, 4);
Steven Tothe12671cf2007-12-20 01:14:43 -0300273 if (result == XC_RESULT_SUCCESS) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300274 /* wait for busy flag to clear */
275 while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
276 buf[0] = 0;
277 buf[1] = XREG_BUSY;
278
279 result = xc_send_i2c_data(priv, buf, 2);
280 if (result == XC_RESULT_SUCCESS) {
281 result = xc_read_i2c_data(priv, buf, 2);
282 if (result == XC_RESULT_SUCCESS) {
283 if ((buf[0] == 0) && (buf[1] == 0)) {
284 /* busy flag cleared */
285 break;
286 } else {
287 xc_wait(100); /* wait 5 ms */
288 WatchDogTimer--;
289 }
290 }
291 }
292 }
293 }
294 if (WatchDogTimer < 0)
295 result = XC_RESULT_I2C_WRITE_FAILURE;
296
297 return result;
298}
299
David Woodhousec63e87e2008-05-24 00:13:34 +0100300static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
Steven Tothaacb9d32007-12-18 01:55:51 -0300301{
302 struct xc5000_priv *priv = fe->tuner_priv;
303
304 int i, nbytes_to_send, result;
305 unsigned int len, pos, index;
Steven Tothe12671cf2007-12-20 01:14:43 -0300306 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
Steven Tothaacb9d32007-12-18 01:55:51 -0300307
Steven Toth8f3cd532008-10-16 20:29:38 -0300308 index = 0;
309 while ((i2c_sequence[index] != 0xFF) ||
310 (i2c_sequence[index + 1] != 0xFF)) {
311 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
Steven Tothe12671cf2007-12-20 01:14:43 -0300312 if (len == 0x0000) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300313 /* RESET command */
Devin Heitmueller91bd6252008-11-15 23:29:11 -0300314 result = xc5000_TunerReset(fe);
Steven Tothaacb9d32007-12-18 01:55:51 -0300315 index += 2;
Steven Tothe12671cf2007-12-20 01:14:43 -0300316 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300317 return result;
318 } else if (len & 0x8000) {
319 /* WAIT command */
320 xc_wait(len & 0x7FFF);
321 index += 2;
322 } else {
323 /* Send i2c data whilst ensuring individual transactions
324 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
325 */
326 index += 2;
327 buf[0] = i2c_sequence[index];
328 buf[1] = i2c_sequence[index + 1];
329 pos = 2;
330 while (pos < len) {
Steven Toth8f3cd532008-10-16 20:29:38 -0300331 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
332 nbytes_to_send =
333 XC_MAX_I2C_WRITE_LENGTH;
334 else
Steven Tothaacb9d32007-12-18 01:55:51 -0300335 nbytes_to_send = (len - pos + 2);
Steven Toth8f3cd532008-10-16 20:29:38 -0300336 for (i = 2; i < nbytes_to_send; i++) {
337 buf[i] = i2c_sequence[index + pos +
338 i - 2];
Steven Tothaacb9d32007-12-18 01:55:51 -0300339 }
Steven Toth8f3cd532008-10-16 20:29:38 -0300340 result = xc_send_i2c_data(priv, buf,
341 nbytes_to_send);
Steven Tothaacb9d32007-12-18 01:55:51 -0300342
Steven Tothe12671cf2007-12-20 01:14:43 -0300343 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300344 return result;
345
346 pos += nbytes_to_send - 2;
347 }
348 index += len;
349 }
350 }
351 return XC_RESULT_SUCCESS;
352}
353
Steven Tothe12671cf2007-12-20 01:14:43 -0300354static int xc_initialize(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300355{
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300356 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300357 return xc_write_reg(priv, XREG_INIT, 0);
358}
359
Steven Tothe12671cf2007-12-20 01:14:43 -0300360static int xc_SetTVStandard(struct xc5000_priv *priv,
361 u16 VideoMode, u16 AudioMode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300362{
363 int ret;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300364 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
Steven Tothaacb9d32007-12-18 01:55:51 -0300365 dprintk(1, "%s() Standard = %s\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300366 __func__,
Steven Tothaacb9d32007-12-18 01:55:51 -0300367 XC5000_Standard[priv->video_standard].Name);
368
369 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
370 if (ret == XC_RESULT_SUCCESS)
371 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
372
373 return ret;
374}
375
Steven Tothe12671cf2007-12-20 01:14:43 -0300376static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300377{
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300378 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
Steven Tothaacb9d32007-12-18 01:55:51 -0300379 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
380
Steven Toth8f3cd532008-10-16 20:29:38 -0300381 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300382 rf_mode = XC_RF_MODE_CABLE;
383 printk(KERN_ERR
384 "%s(), Invalid mode, defaulting to CABLE",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300385 __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300386 }
387 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
388}
389
Steven Tothe12671cf2007-12-20 01:14:43 -0300390static const struct dvb_tuner_ops xc5000_tuner_ops;
391
392static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300393{
Steven Tothe12671cf2007-12-20 01:14:43 -0300394 u16 freq_code;
Steven Tothaacb9d32007-12-18 01:55:51 -0300395
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300396 dprintk(1, "%s(%u)\n", __func__, freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300397
Steven Tothe12671cf2007-12-20 01:14:43 -0300398 if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
399 (freq_hz < xc5000_tuner_ops.info.frequency_min))
400 return XC_RESULT_OUT_OF_RANGE;
Steven Tothaacb9d32007-12-18 01:55:51 -0300401
Steven Tothe12671cf2007-12-20 01:14:43 -0300402 freq_code = (u16)(freq_hz / 15625);
403
Devin Heitmueller81c4dfe2009-04-02 22:40:29 -0300404 /* Starting in firmware version 1.1.44, Xceive recommends using the
405 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
406 only be used for fast scanning for channel lock) */
407 return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
Steven Tothaacb9d32007-12-18 01:55:51 -0300408}
409
Steven Tothe12671cf2007-12-20 01:14:43 -0300410
411static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300412{
Steven Tothe12671cf2007-12-20 01:14:43 -0300413 u32 freq_code = (freq_khz * 1024)/1000;
414 dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300415 __func__, freq_khz, freq_code);
Steven Tothe12671cf2007-12-20 01:14:43 -0300416
417 return xc_write_reg(priv, XREG_IF_OUT, freq_code);
Steven Tothaacb9d32007-12-18 01:55:51 -0300418}
419
Steven Tothe12671cf2007-12-20 01:14:43 -0300420
421static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
Steven Tothaacb9d32007-12-18 01:55:51 -0300422{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300423 return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
Steven Tothaacb9d32007-12-18 01:55:51 -0300424}
425
Steven Tothe12671cf2007-12-20 01:14:43 -0300426static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300427{
428 int result;
Steven Tothe12671cf2007-12-20 01:14:43 -0300429 u16 regData;
Steven Tothaacb9d32007-12-18 01:55:51 -0300430 u32 tmp;
431
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300432 result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300433 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300434 return result;
435
436 tmp = (u32)regData;
Steven Tothe12671cf2007-12-20 01:14:43 -0300437 (*freq_error_hz) = (tmp * 15625) / 1000;
Steven Tothaacb9d32007-12-18 01:55:51 -0300438 return result;
439}
440
Steven Tothe12671cf2007-12-20 01:14:43 -0300441static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
Steven Tothaacb9d32007-12-18 01:55:51 -0300442{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300443 return xc5000_readreg(priv, XREG_LOCK, lock_status);
Steven Tothaacb9d32007-12-18 01:55:51 -0300444}
445
Steven Tothe12671cf2007-12-20 01:14:43 -0300446static int xc_get_version(struct xc5000_priv *priv,
447 u8 *hw_majorversion, u8 *hw_minorversion,
448 u8 *fw_majorversion, u8 *fw_minorversion)
Steven Tothaacb9d32007-12-18 01:55:51 -0300449{
Steven Tothe12671cf2007-12-20 01:14:43 -0300450 u16 data;
Steven Tothaacb9d32007-12-18 01:55:51 -0300451 int result;
452
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300453 result = xc5000_readreg(priv, XREG_VERSION, &data);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300454 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300455 return result;
456
Steven Tothe12671cf2007-12-20 01:14:43 -0300457 (*hw_majorversion) = (data >> 12) & 0x0F;
458 (*hw_minorversion) = (data >> 8) & 0x0F;
459 (*fw_majorversion) = (data >> 4) & 0x0F;
460 (*fw_minorversion) = data & 0x0F;
Steven Tothaacb9d32007-12-18 01:55:51 -0300461
462 return 0;
463}
464
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300465static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
466{
467 return xc5000_readreg(priv, XREG_BUILD, buildrev);
468}
469
Steven Tothe12671cf2007-12-20 01:14:43 -0300470static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
Steven Tothaacb9d32007-12-18 01:55:51 -0300471{
Steven Tothe12671cf2007-12-20 01:14:43 -0300472 u16 regData;
Steven Tothaacb9d32007-12-18 01:55:51 -0300473 int result;
474
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300475 result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300476 if (result != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300477 return result;
478
479 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
480 return result;
481}
482
Steven Tothe12671cf2007-12-20 01:14:43 -0300483static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
Steven Tothaacb9d32007-12-18 01:55:51 -0300484{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300485 return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
Steven Tothaacb9d32007-12-18 01:55:51 -0300486}
487
Steven Tothe12671cf2007-12-20 01:14:43 -0300488static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
Steven Tothaacb9d32007-12-18 01:55:51 -0300489{
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300490 return xc5000_readreg(priv, XREG_QUALITY, quality);
Steven Tothaacb9d32007-12-18 01:55:51 -0300491}
492
Steven Tothe12671cf2007-12-20 01:14:43 -0300493static u16 WaitForLock(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300494{
Steven Tothe12671cf2007-12-20 01:14:43 -0300495 u16 lockState = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300496 int watchDogCount = 40;
Steven Tothe12671cf2007-12-20 01:14:43 -0300497
498 while ((lockState == 0) && (watchDogCount > 0)) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300499 xc_get_lock_status(priv, &lockState);
Steven Tothe12671cf2007-12-20 01:14:43 -0300500 if (lockState != 1) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300501 xc_wait(5);
502 watchDogCount--;
503 }
504 }
505 return lockState;
506}
507
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300508#define XC_TUNE_ANALOG 0
509#define XC_TUNE_DIGITAL 1
510static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
Steven Tothaacb9d32007-12-18 01:55:51 -0300511{
512 int found = 0;
513
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300514 dprintk(1, "%s(%u)\n", __func__, freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300515
Steven Tothe12671cf2007-12-20 01:14:43 -0300516 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
Steven Tothaacb9d32007-12-18 01:55:51 -0300517 return 0;
518
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300519 if (mode == XC_TUNE_ANALOG) {
520 if (WaitForLock(priv) == 1)
521 found = 1;
522 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300523
524 return found;
525}
526
527static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
528{
529 u8 buf[2] = { reg >> 8, reg & 0xff };
530 u8 bval[2] = { 0, 0 };
531 struct i2c_msg msg[2] = {
Michael Krufky89fd2852008-09-06 11:44:53 -0300532 { .addr = priv->i2c_props.addr,
Steven Tothaacb9d32007-12-18 01:55:51 -0300533 .flags = 0, .buf = &buf[0], .len = 2 },
Michael Krufky89fd2852008-09-06 11:44:53 -0300534 { .addr = priv->i2c_props.addr,
Steven Tothaacb9d32007-12-18 01:55:51 -0300535 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
536 };
537
Michael Krufky89fd2852008-09-06 11:44:53 -0300538 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
Steven Toth27c685a2008-01-05 16:50:14 -0300539 printk(KERN_WARNING "xc5000: I2C read failed\n");
Steven Tothaacb9d32007-12-18 01:55:51 -0300540 return -EREMOTEIO;
541 }
542
543 *val = (bval[0] << 8) | bval[1];
Devin Heitmuellerbdd33562008-11-16 20:17:14 -0300544 return XC_RESULT_SUCCESS;
Steven Tothaacb9d32007-12-18 01:55:51 -0300545}
546
Steven Toth8f3cd532008-10-16 20:29:38 -0300547static int xc5000_fwupload(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300548{
549 struct xc5000_priv *priv = fe->tuner_priv;
550 const struct firmware *fw;
551 int ret;
552
Steven Tothe12671cf2007-12-20 01:14:43 -0300553 /* request the firmware, this will block and timeout */
554 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
555 XC5000_DEFAULT_FIRMWARE);
556
Steven Toth8f3cd532008-10-16 20:29:38 -0300557 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
Jean Delvaree9785252009-04-26 05:43:59 -0300558 priv->i2c_props.adap->dev.parent);
Steven Tothaacb9d32007-12-18 01:55:51 -0300559 if (ret) {
560 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
561 ret = XC_RESULT_RESET_FAILURE;
Steven Toth5ea60532008-01-24 22:29:46 -0300562 goto out;
Steven Tothaacb9d32007-12-18 01:55:51 -0300563 } else {
Devin Heitmueller34a0db92009-04-02 22:45:17 -0300564 printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
Michael Krufky3f514512007-12-21 16:20:23 -0300565 fw->size);
Steven Tothaacb9d32007-12-18 01:55:51 -0300566 ret = XC_RESULT_SUCCESS;
567 }
568
Steven Tothe12671cf2007-12-20 01:14:43 -0300569 if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300570 printk(KERN_ERR "xc5000: firmware incorrect size\n");
571 ret = XC_RESULT_RESET_FAILURE;
572 } else {
Devin Heitmueller34a0db92009-04-02 22:45:17 -0300573 printk(KERN_INFO "xc5000: firmware uploading...\n");
Steven Toth8f3cd532008-10-16 20:29:38 -0300574 ret = xc_load_i2c_sequence(fe, fw->data);
Devin Heitmueller34a0db92009-04-02 22:45:17 -0300575 printk(KERN_INFO "xc5000: firmware upload complete...\n");
Steven Tothaacb9d32007-12-18 01:55:51 -0300576 }
577
Steven Toth5ea60532008-01-24 22:29:46 -0300578out:
Steven Tothaacb9d32007-12-18 01:55:51 -0300579 release_firmware(fw);
580 return ret;
581}
582
Steven Tothe12671cf2007-12-20 01:14:43 -0300583static void xc_debug_dump(struct xc5000_priv *priv)
Steven Tothaacb9d32007-12-18 01:55:51 -0300584{
Steven Tothe12671cf2007-12-20 01:14:43 -0300585 u16 adc_envelope;
586 u32 freq_error_hz = 0;
587 u16 lock_status;
588 u32 hsync_freq_hz = 0;
589 u16 frame_lines;
590 u16 quality;
591 u8 hw_majorversion = 0, hw_minorversion = 0;
592 u8 fw_majorversion = 0, fw_minorversion = 0;
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300593 u16 fw_buildversion = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300594
595 /* Wait for stats to stabilize.
596 * Frame Lines needs two frame times after initial lock
597 * before it is valid.
598 */
Steven Tothe12671cf2007-12-20 01:14:43 -0300599 xc_wait(100);
Steven Tothaacb9d32007-12-18 01:55:51 -0300600
Steven Tothe12671cf2007-12-20 01:14:43 -0300601 xc_get_ADC_Envelope(priv, &adc_envelope);
602 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
Steven Tothaacb9d32007-12-18 01:55:51 -0300603
Steven Tothe12671cf2007-12-20 01:14:43 -0300604 xc_get_frequency_error(priv, &freq_error_hz);
605 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300606
Steven Tothe12671cf2007-12-20 01:14:43 -0300607 xc_get_lock_status(priv, &lock_status);
608 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
Steven Tothaacb9d32007-12-18 01:55:51 -0300609 lock_status);
610
611 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
Steven Tothe12671cf2007-12-20 01:14:43 -0300612 &fw_majorversion, &fw_minorversion);
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300613 xc_get_buildversion(priv, &fw_buildversion);
614 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
Steven Tothaacb9d32007-12-18 01:55:51 -0300615 hw_majorversion, hw_minorversion,
Devin Heitmuellerbae7b7d2009-04-02 22:24:38 -0300616 fw_majorversion, fw_minorversion, fw_buildversion);
Steven Tothaacb9d32007-12-18 01:55:51 -0300617
Steven Tothe12671cf2007-12-20 01:14:43 -0300618 xc_get_hsync_freq(priv, &hsync_freq_hz);
619 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300620
Steven Tothe12671cf2007-12-20 01:14:43 -0300621 xc_get_frame_lines(priv, &frame_lines);
622 dprintk(1, "*** Frame lines = %d\n", frame_lines);
Steven Tothaacb9d32007-12-18 01:55:51 -0300623
Steven Tothe12671cf2007-12-20 01:14:43 -0300624 xc_get_quality(priv, &quality);
625 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
Steven Tothaacb9d32007-12-18 01:55:51 -0300626}
627
628static int xc5000_set_params(struct dvb_frontend *fe,
629 struct dvb_frontend_parameters *params)
630{
631 struct xc5000_priv *priv = fe->tuner_priv;
Steven Tothe12671cf2007-12-20 01:14:43 -0300632 int ret;
Steven Tothaacb9d32007-12-18 01:55:51 -0300633
Devin Heitmueller8e4c6792008-11-16 20:41:07 -0300634 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
635 xc_load_fw_and_init_tuner(fe);
636
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300637 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
Steven Tothaacb9d32007-12-18 01:55:51 -0300638
Steven Toth8f3cd532008-10-16 20:29:38 -0300639 switch (params->u.vsb.modulation) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300640 case VSB_8:
641 case VSB_16:
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300642 dprintk(1, "%s() VSB modulation\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300643 priv->rf_mode = XC_RF_MODE_AIR;
Steven Tothe12671cf2007-12-20 01:14:43 -0300644 priv->freq_hz = params->frequency - 1750000;
645 priv->bandwidth = BANDWIDTH_6_MHZ;
646 priv->video_standard = DTV6;
Steven Tothaacb9d32007-12-18 01:55:51 -0300647 break;
648 case QAM_64:
649 case QAM_256:
650 case QAM_AUTO:
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300651 dprintk(1, "%s() QAM modulation\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300652 priv->rf_mode = XC_RF_MODE_CABLE;
Steven Tothe12671cf2007-12-20 01:14:43 -0300653 priv->freq_hz = params->frequency - 1750000;
654 priv->bandwidth = BANDWIDTH_6_MHZ;
655 priv->video_standard = DTV6;
Steven Tothaacb9d32007-12-18 01:55:51 -0300656 break;
657 default:
658 return -EINVAL;
659 }
660
661 dprintk(1, "%s() frequency=%d (compensated)\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300662 __func__, priv->freq_hz);
Steven Tothaacb9d32007-12-18 01:55:51 -0300663
Steven Tothe12671cf2007-12-20 01:14:43 -0300664 ret = xc_SetSignalSource(priv, priv->rf_mode);
665 if (ret != XC_RESULT_SUCCESS) {
666 printk(KERN_ERR
667 "xc5000: xc_SetSignalSource(%d) failed\n",
668 priv->rf_mode);
669 return -EREMOTEIO;
670 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300671
Steven Tothe12671cf2007-12-20 01:14:43 -0300672 ret = xc_SetTVStandard(priv,
Steven Tothaacb9d32007-12-18 01:55:51 -0300673 XC5000_Standard[priv->video_standard].VideoMode,
674 XC5000_Standard[priv->video_standard].AudioMode);
Steven Tothe12671cf2007-12-20 01:14:43 -0300675 if (ret != XC_RESULT_SUCCESS) {
676 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
677 return -EREMOTEIO;
678 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300679
Michael Krufky2a6003c2008-09-06 13:54:45 -0300680 ret = xc_set_IF_frequency(priv, priv->if_khz);
Steven Tothe12671cf2007-12-20 01:14:43 -0300681 if (ret != XC_RESULT_SUCCESS) {
682 printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
Michael Krufky2a6003c2008-09-06 13:54:45 -0300683 priv->if_khz);
Steven Tothe12671cf2007-12-20 01:14:43 -0300684 return -EIO;
685 }
686
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300687 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
Steven Tothe12671cf2007-12-20 01:14:43 -0300688
689 if (debug)
690 xc_debug_dump(priv);
Steven Tothaacb9d32007-12-18 01:55:51 -0300691
692 return 0;
693}
694
Steven Tothe470d812008-06-21 21:06:02 -0300695static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
696{
697 struct xc5000_priv *priv = fe->tuner_priv;
698 int ret;
699 u16 id;
700
701 ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
702 if (ret == XC_RESULT_SUCCESS) {
703 if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
704 ret = XC_RESULT_RESET_FAILURE;
705 else
706 ret = XC_RESULT_SUCCESS;
707 }
708
709 dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
710 ret == XC_RESULT_SUCCESS ? "True" : "False", id);
711 return ret;
712}
713
Steven Toth27c685a2008-01-05 16:50:14 -0300714static int xc5000_set_analog_params(struct dvb_frontend *fe,
715 struct analog_parameters *params)
716{
717 struct xc5000_priv *priv = fe->tuner_priv;
718 int ret;
719
Steven Tothe470d812008-06-21 21:06:02 -0300720 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
Steven Toth27c685a2008-01-05 16:50:14 -0300721 xc_load_fw_and_init_tuner(fe);
722
723 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300724 __func__, params->frequency);
Steven Toth27c685a2008-01-05 16:50:14 -0300725
Mauro Carvalho Chehab1fab14e2009-03-03 14:35:41 -0300726 /* Fix me: it could be air. */
727 priv->rf_mode = params->mode;
728 if (params->mode > XC_RF_MODE_CABLE)
729 priv->rf_mode = XC_RF_MODE_CABLE;
Steven Toth27c685a2008-01-05 16:50:14 -0300730
731 /* params->frequency is in units of 62.5khz */
732 priv->freq_hz = params->frequency * 62500;
733
734 /* FIX ME: Some video standards may have several possible audio
735 standards. We simply default to one of them here.
736 */
Steven Toth8f3cd532008-10-16 20:29:38 -0300737 if (params->std & V4L2_STD_MN) {
Steven Toth27c685a2008-01-05 16:50:14 -0300738 /* default to BTSC audio standard */
739 priv->video_standard = MN_NTSC_PAL_BTSC;
740 goto tune_channel;
741 }
742
Steven Toth8f3cd532008-10-16 20:29:38 -0300743 if (params->std & V4L2_STD_PAL_BG) {
Steven Toth27c685a2008-01-05 16:50:14 -0300744 /* default to NICAM audio standard */
745 priv->video_standard = BG_PAL_NICAM;
746 goto tune_channel;
747 }
748
Steven Toth8f3cd532008-10-16 20:29:38 -0300749 if (params->std & V4L2_STD_PAL_I) {
Steven Toth27c685a2008-01-05 16:50:14 -0300750 /* default to NICAM audio standard */
751 priv->video_standard = I_PAL_NICAM;
752 goto tune_channel;
753 }
754
Steven Toth8f3cd532008-10-16 20:29:38 -0300755 if (params->std & V4L2_STD_PAL_DK) {
Steven Toth27c685a2008-01-05 16:50:14 -0300756 /* default to NICAM audio standard */
757 priv->video_standard = DK_PAL_NICAM;
758 goto tune_channel;
759 }
760
Steven Toth8f3cd532008-10-16 20:29:38 -0300761 if (params->std & V4L2_STD_SECAM_DK) {
Steven Toth27c685a2008-01-05 16:50:14 -0300762 /* default to A2 DK1 audio standard */
763 priv->video_standard = DK_SECAM_A2DK1;
764 goto tune_channel;
765 }
766
Steven Toth8f3cd532008-10-16 20:29:38 -0300767 if (params->std & V4L2_STD_SECAM_L) {
Steven Toth27c685a2008-01-05 16:50:14 -0300768 priv->video_standard = L_SECAM_NICAM;
769 goto tune_channel;
770 }
771
Steven Toth8f3cd532008-10-16 20:29:38 -0300772 if (params->std & V4L2_STD_SECAM_LC) {
Steven Toth27c685a2008-01-05 16:50:14 -0300773 priv->video_standard = LC_SECAM_NICAM;
774 goto tune_channel;
775 }
776
777tune_channel:
778 ret = xc_SetSignalSource(priv, priv->rf_mode);
779 if (ret != XC_RESULT_SUCCESS) {
Steven Toth8f3cd532008-10-16 20:29:38 -0300780 printk(KERN_ERR
Steven Toth27c685a2008-01-05 16:50:14 -0300781 "xc5000: xc_SetSignalSource(%d) failed\n",
782 priv->rf_mode);
783 return -EREMOTEIO;
784 }
785
786 ret = xc_SetTVStandard(priv,
787 XC5000_Standard[priv->video_standard].VideoMode,
788 XC5000_Standard[priv->video_standard].AudioMode);
789 if (ret != XC_RESULT_SUCCESS) {
790 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
791 return -EREMOTEIO;
792 }
793
Devin Heitmuellera78baac2008-11-16 20:48:31 -0300794 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
Steven Toth27c685a2008-01-05 16:50:14 -0300795
796 if (debug)
797 xc_debug_dump(priv);
798
799 return 0;
800}
801
Steven Tothaacb9d32007-12-18 01:55:51 -0300802static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
803{
804 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300805 dprintk(1, "%s()\n", __func__);
Steven Tothe12671cf2007-12-20 01:14:43 -0300806 *freq = priv->freq_hz;
Steven Tothaacb9d32007-12-18 01:55:51 -0300807 return 0;
808}
809
810static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
811{
812 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300813 dprintk(1, "%s()\n", __func__);
Steven Toth27c685a2008-01-05 16:50:14 -0300814
Steven Tothaacb9d32007-12-18 01:55:51 -0300815 *bw = priv->bandwidth;
816 return 0;
817}
818
819static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
820{
821 struct xc5000_priv *priv = fe->tuner_priv;
Steven Tothe12671cf2007-12-20 01:14:43 -0300822 u16 lock_status = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300823
824 xc_get_lock_status(priv, &lock_status);
825
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300826 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
Steven Tothaacb9d32007-12-18 01:55:51 -0300827
828 *status = lock_status;
829
830 return 0;
831}
832
Steven Tothe12671cf2007-12-20 01:14:43 -0300833static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
Steven Tothaacb9d32007-12-18 01:55:51 -0300834{
835 struct xc5000_priv *priv = fe->tuner_priv;
Steven Toth27c685a2008-01-05 16:50:14 -0300836 int ret = 0;
Steven Tothaacb9d32007-12-18 01:55:51 -0300837
Steven Tothe470d812008-06-21 21:06:02 -0300838 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
Steven Tothaacb9d32007-12-18 01:55:51 -0300839 ret = xc5000_fwupload(fe);
Steven Tothe12671cf2007-12-20 01:14:43 -0300840 if (ret != XC_RESULT_SUCCESS)
841 return ret;
Steven Tothaacb9d32007-12-18 01:55:51 -0300842 }
843
844 /* Start the tuner self-calibration process */
845 ret |= xc_initialize(priv);
846
847 /* Wait for calibration to complete.
848 * We could continue but XC5000 will clock stretch subsequent
849 * I2C transactions until calibration is complete. This way we
850 * don't have to rely on clock stretching working.
851 */
Steven Toth8f3cd532008-10-16 20:29:38 -0300852 xc_wait(100);
Steven Tothaacb9d32007-12-18 01:55:51 -0300853
854 /* Default to "CABLE" mode */
855 ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
856
857 return ret;
858}
859
Steven Tothe12671cf2007-12-20 01:14:43 -0300860static int xc5000_sleep(struct dvb_frontend *fe)
861{
Steven Toth27c685a2008-01-05 16:50:14 -0300862 int ret;
863
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300864 dprintk(1, "%s()\n", __func__);
Steven Tothe12671cf2007-12-20 01:14:43 -0300865
Devin Heitmuellerb6bd5eb2009-04-28 13:53:38 -0300866 /* Avoid firmware reload on slow devices */
867 if (no_poweroff)
868 return 0;
869
Devin Heitmueller7f05b532009-04-02 22:02:39 -0300870 /* According to Xceive technical support, the "powerdown" register
871 was removed in newer versions of the firmware. The "supported"
872 way to sleep the tuner is to pull the reset pin low for 10ms */
873 ret = xc5000_TunerReset(fe);
Steven Toth8f3cd532008-10-16 20:29:38 -0300874 if (ret != XC_RESULT_SUCCESS) {
Steven Toth27c685a2008-01-05 16:50:14 -0300875 printk(KERN_ERR
876 "xc5000: %s() unable to shutdown tuner\n",
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300877 __func__);
Steven Toth27c685a2008-01-05 16:50:14 -0300878 return -EREMOTEIO;
Steven Toth8f3cd532008-10-16 20:29:38 -0300879 } else
Steven Toth27c685a2008-01-05 16:50:14 -0300880 return XC_RESULT_SUCCESS;
Steven Tothe12671cf2007-12-20 01:14:43 -0300881}
882
Steven Tothaacb9d32007-12-18 01:55:51 -0300883static int xc5000_init(struct dvb_frontend *fe)
884{
885 struct xc5000_priv *priv = fe->tuner_priv;
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300886 dprintk(1, "%s()\n", __func__);
Steven Tothaacb9d32007-12-18 01:55:51 -0300887
Steven Tothe12671cf2007-12-20 01:14:43 -0300888 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
889 printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
890 return -EREMOTEIO;
891 }
892
893 if (debug)
894 xc_debug_dump(priv);
Steven Tothaacb9d32007-12-18 01:55:51 -0300895
896 return 0;
897}
898
899static int xc5000_release(struct dvb_frontend *fe)
900{
Michael Krufky89fd2852008-09-06 11:44:53 -0300901 struct xc5000_priv *priv = fe->tuner_priv;
902
Harvey Harrison271ddbf2008-04-08 23:20:00 -0300903 dprintk(1, "%s()\n", __func__);
Michael Krufky89fd2852008-09-06 11:44:53 -0300904
905 mutex_lock(&xc5000_list_mutex);
906
907 if (priv)
908 hybrid_tuner_release_state(priv);
909
910 mutex_unlock(&xc5000_list_mutex);
911
Steven Tothaacb9d32007-12-18 01:55:51 -0300912 fe->tuner_priv = NULL;
Michael Krufky89fd2852008-09-06 11:44:53 -0300913
Steven Tothaacb9d32007-12-18 01:55:51 -0300914 return 0;
915}
916
917static const struct dvb_tuner_ops xc5000_tuner_ops = {
918 .info = {
919 .name = "Xceive XC5000",
920 .frequency_min = 1000000,
921 .frequency_max = 1023000000,
922 .frequency_step = 50000,
923 },
924
Steven Toth27c685a2008-01-05 16:50:14 -0300925 .release = xc5000_release,
926 .init = xc5000_init,
927 .sleep = xc5000_sleep,
Steven Tothaacb9d32007-12-18 01:55:51 -0300928
Steven Toth27c685a2008-01-05 16:50:14 -0300929 .set_params = xc5000_set_params,
930 .set_analog_params = xc5000_set_analog_params,
931 .get_frequency = xc5000_get_frequency,
932 .get_bandwidth = xc5000_get_bandwidth,
933 .get_status = xc5000_get_status
Steven Tothaacb9d32007-12-18 01:55:51 -0300934};
935
Michael Krufky48723542008-05-10 14:34:09 -0300936struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
937 struct i2c_adapter *i2c,
Michael Krufky30650962008-09-06 14:56:58 -0300938 struct xc5000_config *cfg)
Steven Tothaacb9d32007-12-18 01:55:51 -0300939{
940 struct xc5000_priv *priv = NULL;
Michael Krufky89fd2852008-09-06 11:44:53 -0300941 int instance;
Steven Tothaacb9d32007-12-18 01:55:51 -0300942 u16 id = 0;
943
Michael Krufky89fd2852008-09-06 11:44:53 -0300944 dprintk(1, "%s(%d-%04x)\n", __func__,
945 i2c ? i2c_adapter_id(i2c) : -1,
946 cfg ? cfg->i2c_address : -1);
Steven Tothaacb9d32007-12-18 01:55:51 -0300947
Michael Krufky89fd2852008-09-06 11:44:53 -0300948 mutex_lock(&xc5000_list_mutex);
Steven Tothaacb9d32007-12-18 01:55:51 -0300949
Michael Krufky89fd2852008-09-06 11:44:53 -0300950 instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
951 hybrid_tuner_instance_list,
952 i2c, cfg->i2c_address, "xc5000");
953 switch (instance) {
954 case 0:
955 goto fail;
956 break;
957 case 1:
958 /* new tuner instance */
Michael Krufky89fd2852008-09-06 11:44:53 -0300959 priv->bandwidth = BANDWIDTH_6_MHZ;
Michael Krufky89fd2852008-09-06 11:44:53 -0300960 fe->tuner_priv = priv;
961 break;
962 default:
963 /* existing tuner instance */
964 fe->tuner_priv = priv;
965 break;
966 }
Steven Tothaacb9d32007-12-18 01:55:51 -0300967
Devin Heitmuellerea227862009-03-11 02:58:53 -0300968 if (priv->if_khz == 0) {
969 /* If the IF hasn't been set yet, use the value provided by
970 the caller (occurs in hybrid devices where the analog
971 call to xc5000_attach occurs before the digital side) */
972 priv->if_khz = cfg->if_khz;
973 }
974
Steven Toth27c685a2008-01-05 16:50:14 -0300975 /* Check if firmware has been loaded. It is possible that another
976 instance of the driver has loaded the firmware.
977 */
Devin Heitmueller7988fc22008-11-16 20:23:19 -0300978 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
Michael Krufky89fd2852008-09-06 11:44:53 -0300979 goto fail;
Steven Tothaacb9d32007-12-18 01:55:51 -0300980
Steven Toth8f3cd532008-10-16 20:29:38 -0300981 switch (id) {
Steven Toth27c685a2008-01-05 16:50:14 -0300982 case XC_PRODUCT_ID_FW_LOADED:
983 printk(KERN_INFO
984 "xc5000: Successfully identified at address 0x%02x\n",
985 cfg->i2c_address);
986 printk(KERN_INFO
987 "xc5000: Firmware has been loaded previously\n");
Steven Toth27c685a2008-01-05 16:50:14 -0300988 break;
989 case XC_PRODUCT_ID_FW_NOT_LOADED:
990 printk(KERN_INFO
991 "xc5000: Successfully identified at address 0x%02x\n",
992 cfg->i2c_address);
993 printk(KERN_INFO
994 "xc5000: Firmware has not been loaded previously\n");
Steven Toth27c685a2008-01-05 16:50:14 -0300995 break;
996 default:
Steven Tothaacb9d32007-12-18 01:55:51 -0300997 printk(KERN_ERR
998 "xc5000: Device not found at addr 0x%02x (0x%x)\n",
999 cfg->i2c_address, id);
Michael Krufky89fd2852008-09-06 11:44:53 -03001000 goto fail;
Steven Tothaacb9d32007-12-18 01:55:51 -03001001 }
1002
Michael Krufky89fd2852008-09-06 11:44:53 -03001003 mutex_unlock(&xc5000_list_mutex);
1004
Steven Tothaacb9d32007-12-18 01:55:51 -03001005 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
1006 sizeof(struct dvb_tuner_ops));
1007
Steven Tothaacb9d32007-12-18 01:55:51 -03001008 return fe;
Michael Krufky89fd2852008-09-06 11:44:53 -03001009fail:
1010 mutex_unlock(&xc5000_list_mutex);
1011
1012 xc5000_release(fe);
1013 return NULL;
Steven Tothaacb9d32007-12-18 01:55:51 -03001014}
1015EXPORT_SYMBOL(xc5000_attach);
1016
1017MODULE_AUTHOR("Steven Toth");
Steven Tothe12671cf2007-12-20 01:14:43 -03001018MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
Steven Tothaacb9d32007-12-18 01:55:51 -03001019MODULE_LICENSE("GPL");