aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2008-05-01 06:04:09 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-05-14 01:56:39 -0400
commit5c1b20514f592af19974166f130b85346c1fbf3a (patch)
tree3d2a55ccbe6e84555b5a4931cd9d5eef7b9edac1 /drivers/media/common
parent7f5c3affef2883f49e820db62413e1dff1d4cebb (diff)
V4L/DVB (7870): mxl5005s: Basic digital support.
ATSC and QAM should be working but basic testing is required. Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/tuners/mxl5005s.c616
-rw-r--r--drivers/media/common/tuners/mxl5005s.h145
2 files changed, 389 insertions, 372 deletions
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index f7ed9a72db4a..64aa864c5dbf 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -1,69 +1,40 @@
1/* 1/*
2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver 2 * For the Realtek RTL chip RTL2831U
3 3 * Realtek Release Date: 2008-03-14, ver 080314
4 Copyright (C) 2008 MaxLinear 4 * Realtek version RTL2831 Linux driver version 080314
5 Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> 5 * ver 080314
6 Functions: 6 *
7 mxl5005s_reset() 7 * for linux kernel version 2.6.21.4 - 2.6.22-14
8 mxl5005s_writereg() 8 * support MXL5005s and MT2060 tuners (support tuner auto-detecting)
9 mxl5005s_writeregs() 9 * support two IR types -- RC5 and NEC
10 mxl5005s_init() 10 *
11 mxl5005s_reconfigure() 11 * Known boards with Realtek RTL chip RTL2821U
12 mxl5005s_AssignTunerMode() 12 * Freecom USB stick 14aa:0160 (version 4)
13 mxl5005s_set_params() 13 * Conceptronic CTVDIGRCU
14 mxl5005s_get_frequency() 14 *
15 mxl5005s_get_bandwidth() 15 * Copyright (c) 2008 Realtek
16 mxl5005s_release() 16 * Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper
17 mxl5005s_attach() 17 * This code is placed under the terms of the GNU General Public License
18 18 *
19 Copyright (c) 2008 Realtek 19 * Released by Realtek under GPLv2.
20 Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper 20 * Thanks to Realtek for a lot of support we received !
21 Functions: 21 *
22 mxl5005s_SetRfFreqHz() 22 * Revision: 080314 - original version
23 23 */
24 This program is free software; you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation; either version 2 of the License, or
27 (at your option) any later version.
28
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software
36 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37
38*/
39
40/*
41 History of this driver (Steven Toth):
42 I was given a public release of a linux driver that included
43 support for the MaxLinear MXL5005S silicon tuner. Analysis of
44 the tuner driver showed clearly three things.
45
46 1. The tuner driver didn't support the LinuxTV tuner API
47 so the code Realtek added had to be removed.
48
49 2. A significant amount of the driver is reference driver code
50 from MaxLinear, I felt it was important to identify and
51 preserve this.
52
53 3. New code has to be added to interface correctly with the
54 LinuxTV API, as a regular kernel module.
55
56 Other than the reference driver enum's, I've clearly marked
57 sections of the code and retained the copyright of the
58 respective owners.
59*/
60 24
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include "dvb_frontend.h"
61#include "mxl5005s.h" 32#include "mxl5005s.h"
62 33
63static int debug = 2; 34static int debug;
64 35
65#define dprintk(level, arg...) do { \ 36#define dprintk(level, arg...) do { \
66 if (level <= debug) \ 37 if (debug >= level) \
67 printk(arg); \ 38 printk(arg); \
68 } while (0) 39 } while (0)
69 40
@@ -79,6 +50,13 @@ static int debug = 2;
79#define MXLCTRL_NUM 189 50#define MXLCTRL_NUM 189
80#define MASTER_CONTROL_ADDR 9 51#define MASTER_CONTROL_ADDR 9
81 52
53/* Enumeration of AGC Mode */
54typedef enum
55{
56 MXL_DUAL_AGC = 0,
57 MXL_SINGLE_AGC
58} AGC_Mode;
59
82/* Enumeration of Master Control Register State */ 60/* Enumeration of Master Control Register State */
83typedef enum 61typedef enum
84{ 62{
@@ -88,6 +66,51 @@ typedef enum
88 MC_SEQ_OFF 66 MC_SEQ_OFF
89} Master_Control_State; 67} Master_Control_State;
90 68
69/* Enumeration of MXL5005 Tuner Mode */
70typedef enum
71{
72 MXL_ANALOG_MODE = 0,
73 MXL_DIGITAL_MODE
74} Tuner_Mode;
75
76/* Enumeration of MXL5005 Tuner IF Mode */
77typedef enum
78{
79 MXL_ZERO_IF = 0,
80 MXL_LOW_IF
81} Tuner_IF_Mode;
82
83/* Enumeration of MXL5005 Tuner Clock Out Mode */
84typedef enum
85{
86 MXL_CLOCK_OUT_DISABLE = 0,
87 MXL_CLOCK_OUT_ENABLE
88} Tuner_Clock_Out;
89
90/* Enumeration of MXL5005 Tuner Div Out Mode */
91typedef enum
92{
93 MXL_DIV_OUT_1 = 0,
94 MXL_DIV_OUT_4
95
96} Tuner_Div_Out;
97
98/* Enumeration of MXL5005 Tuner Pull-up Cap Select Mode */
99typedef enum
100{
101 MXL_CAP_SEL_DISABLE = 0,
102 MXL_CAP_SEL_ENABLE
103
104} Tuner_Cap_Select;
105
106/* Enumeration of MXL5005 Tuner RSSI Mode */
107typedef enum
108{
109 MXL_RSSI_DISABLE = 0,
110 MXL_RSSI_ENABLE
111
112} Tuner_RSSI;
113
91/* Enumeration of MXL5005 Tuner Modulation Type */ 114/* Enumeration of MXL5005 Tuner Modulation Type */
92typedef enum 115typedef enum
93{ 116{
@@ -99,6 +122,22 @@ typedef enum
99 MXL_ANALOG_OTA 122 MXL_ANALOG_OTA
100} Tuner_Modu_Type; 123} Tuner_Modu_Type;
101 124
125/* Enumeration of MXL5005 Tuner Tracking Filter Type */
126typedef enum
127{
128 MXL_TF_DEFAULT = 0,
129 MXL_TF_OFF,
130 MXL_TF_C,
131 MXL_TF_C_H,
132 MXL_TF_D,
133 MXL_TF_D_L,
134 MXL_TF_E,
135 MXL_TF_F,
136 MXL_TF_E_2,
137 MXL_TF_E_NA,
138 MXL_TF_G
139} Tuner_TF_Type;
140
102/* MXL5005 Tuner Register Struct */ 141/* MXL5005 Tuner Register Struct */
103typedef struct _TunerReg_struct 142typedef struct _TunerReg_struct
104{ 143{
@@ -229,6 +268,33 @@ enum
229}; 268};
230#define MXL5005S_BANDWIDTH_MODE_NUM 3 269#define MXL5005S_BANDWIDTH_MODE_NUM 3
231 270
271/* Top modes */
272enum
273{
274 MXL5005S_TOP_5P5 = 55,
275 MXL5005S_TOP_7P2 = 72,
276 MXL5005S_TOP_9P2 = 92,
277 MXL5005S_TOP_11P0 = 110,
278 MXL5005S_TOP_12P9 = 129,
279 MXL5005S_TOP_14P7 = 147,
280 MXL5005S_TOP_16P8 = 168,
281 MXL5005S_TOP_19P4 = 194,
282 MXL5005S_TOP_21P2 = 212,
283 MXL5005S_TOP_23P2 = 232,
284 MXL5005S_TOP_25P2 = 252,
285 MXL5005S_TOP_27P1 = 271,
286 MXL5005S_TOP_29P2 = 292,
287 MXL5005S_TOP_31P7 = 317,
288 MXL5005S_TOP_34P9 = 349,
289};
290
291/* IF output load */
292enum
293{
294 MXL5005S_IF_OUTPUT_LOAD_200_OHM = 200,
295 MXL5005S_IF_OUTPUT_LOAD_300_OHM = 300,
296};
297
232/* MXL5005 Tuner Control Struct */ 298/* MXL5005 Tuner Control Struct */
233typedef struct _TunerControl_struct { 299typedef struct _TunerControl_struct {
234 u16 Ctrl_Num; /* Control Number */ 300 u16 Ctrl_Num; /* Control Number */
@@ -283,15 +349,13 @@ struct mxl5005s_state
283 TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */ 349 TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
284 350
285 /* Linux driver framework specific */ 351 /* Linux driver framework specific */
286 struct mxl5005s_config *config; 352 const struct mxl5005s_config *config;
353
287 struct dvb_frontend *frontend; 354 struct dvb_frontend *frontend;
288 struct i2c_adapter *i2c; 355 struct i2c_adapter *i2c;
289
290 /* Cache values */
291 u32 current_mode;
292
293}; 356};
294 357
358// funcs
295u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value); 359u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
296u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value); 360u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
297u16 MXL_GetMasterControl(u8 *MasterReg, int state); 361u16 MXL_GetMasterControl(u8 *MasterReg, int state);
@@ -308,26 +372,14 @@ u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
308void MXL_SynthIFLO_Calc(struct dvb_frontend *fe); 372void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
309void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe); 373void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
310u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal, int *count); 374u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal, int *count);
311int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, u8 *datatable, u8 len); 375int mxl5005s_SetRegsWithTable(struct dvb_frontend *fe, u8 *pAddrTable, u8 *pByteTable, int TableLen);
312u16 MXL_IFSynthInit(struct dvb_frontend *fe); 376u16 MXL_IFSynthInit(struct dvb_frontend *fe);
313int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth); 377static int mxl5005s_init2(struct dvb_frontend *fe);
314int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth);
315
316/* ----------------------------------------------------------------
317 * Begin: Custom code salvaged from the Realtek driver.
318 * Copyright (c) 2008 Realtek
319 * Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper
320 * This code is placed under the terms of the GNU General Public License
321 *
322 * Released by Realtek under GPLv2.
323 * Thanks to Realtek for a lot of support we received !
324 *
325 * Revision: 080314 - original version
326 */
327 378
328int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz) 379int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
329{ 380{
330 struct mxl5005s_state *state = fe->tuner_priv; 381 struct mxl5005s_state *state = fe->tuner_priv;
382 u8 AgcMasterByte = state->config->AgcMasterByte;
331 unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 383 unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
332 unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 384 unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
333 int TableLen; 385 int TableLen;
@@ -344,7 +396,7 @@ int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
344 AddrTable[0] = MASTER_CONTROL_ADDR; 396 AddrTable[0] = MASTER_CONTROL_ADDR;
345 ByteTable[0] |= state->config->AgcMasterByte; 397 ByteTable[0] |= state->config->AgcMasterByte;
346 398
347 mxl5005s_writeregs(fe, AddrTable, ByteTable, 1); 399 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, 1);
348 400
349 // Tuner RF frequency setting stage 1 401 // Tuner RF frequency setting stage 1
350 MXL_TuneRF(fe, RfFreqHz); 402 MXL_TuneRF(fe, RfFreqHz);
@@ -358,13 +410,13 @@ int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
358 410
359 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ; 411 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ;
360 AddrTable[TableLen] = MASTER_CONTROL_ADDR ; 412 AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
361 ByteTable[TableLen] = MasterControlByte | state->config->AgcMasterByte; 413 ByteTable[TableLen] = MasterControlByte | AgcMasterByte;
362 TableLen += 1; 414 TableLen += 1;
363 415
364 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen); 416 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, TableLen);
365 417
366 // Wait 30 ms. 418 // Wait 30 ms.
367 msleep(150); 419 msleep(30);
368 420
369 // Tuner RF frequency setting stage 2 421 // Tuner RF frequency setting stage 2
370 MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1) ; 422 MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1) ;
@@ -373,21 +425,101 @@ int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
373 425
374 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ; 426 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ;
375 AddrTable[TableLen] = MASTER_CONTROL_ADDR ; 427 AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
376 ByteTable[TableLen] = MasterControlByte | state->config->AgcMasterByte ; 428 ByteTable[TableLen] = MasterControlByte | AgcMasterByte ;
377 TableLen += 1; 429 TableLen += 1;
378 430
379 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen); 431 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, TableLen);
380 432
381 msleep(100); 433 return 0;
434}
382 435
436/* Write a single byte to a single reg */
437static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val)
438{
439 struct mxl5005s_state *state = fe->tuner_priv;
440 u8 buf[2] = { reg, val };
441 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
442 .buf = buf, .len = 2 };
443
444 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
445 printk(KERN_WARNING "mxl5005s I2C write failed\n");
446 return -EREMOTEIO;
447 }
383 return 0; 448 return 0;
384} 449}
385/* End: Custom code taken from the Realtek driver */
386 450
387/* ---------------------------------------------------------------- 451/* Write a word to a single reg */
388 * Begin: Reference driver code found in the Realtek driver. 452static int mxl5005s_writereg16(struct dvb_frontend *fe, u8 reg, u16 val)
389 * Copyright (c) 2008 MaxLinear 453{
390 */ 454 struct mxl5005s_state *state = fe->tuner_priv;
455 u8 buf[3] = { reg, val >> 8 , val & 0xff };
456 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
457 .buf = buf, .len = 3 };
458
459 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
460 printk(KERN_WARNING "mxl5005s I2C write16 failed\n");
461 return -EREMOTEIO;
462 }
463 return 0;
464}
465
466int mxl5005s_SetRegsWithTable(struct dvb_frontend *fe, u8 *pAddrTable, u8 *pByteTable, int TableLen)
467{
468 int i, ret;
469 u8 end_two_bytes_buf[]={ 0 , 0 };
470
471 for( i = 0 ; i < TableLen - 1 ; i++)
472 {
473 ret = mxl5005s_writereg(fe, pAddrTable[i], pByteTable[i]);
474 if (!ret)
475 return ret;
476 }
477
478 end_two_bytes_buf[0] = pByteTable[i];
479 end_two_bytes_buf[1] = MXL5005S_LATCH_BYTE;
480
481 ret = mxl5005s_writereg16(fe, pAddrTable[i], (end_two_bytes_buf[0] << 8) | end_two_bytes_buf[1]);
482
483 return ret;
484}
485
486int mxl5005s_SetRegMaskBits(struct dvb_frontend *fe,
487 unsigned char RegAddr,
488 unsigned char Msb,
489 unsigned char Lsb,
490 const unsigned char WritingValue
491 )
492{
493 int i;
494
495 unsigned char Mask;
496 unsigned char Shift;
497 unsigned char RegByte;
498
499 /* Generate mask and shift according to MSB and LSB. */
500 Mask = 0;
501 for(i = Lsb; i < (unsigned char)(Msb + 1); i++)
502 Mask |= 0x1 << i;
503
504 Shift = Lsb;
505
506 /* Get tuner register byte according to register adddress. */
507 MXL_RegRead(fe, RegAddr, &RegByte);
508
509 /* Reserve register byte unmask bit with mask and inlay writing value into it. */
510 RegByte &= ~Mask;
511 RegByte |= (WritingValue << Shift) & Mask;
512
513 /* Update tuner register byte table. */
514 MXL_RegWrite(fe, RegAddr, RegByte);
515
516 /* Write tuner register byte with writing byte. */
517 return mxl5005s_SetRegsWithTable(fe, &RegAddr, &RegByte, 1);
518}
519
520// The following context is source code provided by MaxLinear.
521// MaxLinear source code - MXL5005_Initialize.cpp
522// DONE
391u16 MXL5005_RegisterInit(struct dvb_frontend *fe) 523u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
392{ 524{
393 struct mxl5005s_state *state = fe->tuner_priv; 525 struct mxl5005s_state *state = fe->tuner_priv;
@@ -709,6 +841,7 @@ u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
709 return 0 ; 841 return 0 ;
710} 842}
711 843
844// DONE
712u16 MXL5005_ControlInit(struct dvb_frontend *fe) 845u16 MXL5005_ControlInit(struct dvb_frontend *fe)
713{ 846{
714 struct mxl5005s_state *state = fe->tuner_priv; 847 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1652,6 +1785,7 @@ u16 MXL5005_ControlInit(struct dvb_frontend *fe)
1652// MaxLinear source code - MXL5005_c.cpp 1785// MaxLinear source code - MXL5005_c.cpp
1653// MXL5005.cpp : Defines the initialization routines for the DLL. 1786// MXL5005.cpp : Defines the initialization routines for the DLL.
1654// 2.6.12 1787// 2.6.12
1788// DONE
1655void InitTunerControls(struct dvb_frontend *fe) 1789void InitTunerControls(struct dvb_frontend *fe)
1656{ 1790{
1657 MXL5005_RegisterInit(fe); 1791 MXL5005_RegisterInit(fe);
@@ -1694,6 +1828,7 @@ void InitTunerControls(struct dvb_frontend *fe)
1694// > 0 : Failed // 1828// > 0 : Failed //
1695// // 1829// //
1696/////////////////////////////////////////////////////////////////////////////// 1830///////////////////////////////////////////////////////////////////////////////
1831// DONE
1697u16 MXL5005_TunerConfig(struct dvb_frontend *fe, 1832u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
1698 u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */ 1833 u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */
1699 u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */ 1834 u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */
@@ -1763,6 +1898,7 @@ u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
1763// > 0 : Failed // 1898// > 0 : Failed //
1764// // 1899// //
1765/////////////////////////////////////////////////////////////////////////////// 1900///////////////////////////////////////////////////////////////////////////////
1901// DONE
1766void MXL_SynthIFLO_Calc(struct dvb_frontend *fe) 1902void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
1767{ 1903{
1768 struct mxl5005s_state *state = fe->tuner_priv; 1904 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1801,6 +1937,7 @@ void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
1801// > 0 : Failed // 1937// > 0 : Failed //
1802// // 1938// //
1803/////////////////////////////////////////////////////////////////////////////// 1939///////////////////////////////////////////////////////////////////////////////
1940// DONE
1804void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe) 1941void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
1805{ 1942{
1806 struct mxl5005s_state *state = fe->tuner_priv; 1943 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1839,6 +1976,7 @@ void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
1839// > 0 : Failed // 1976// > 0 : Failed //
1840// // 1977// //
1841/////////////////////////////////////////////////////////////////////////////// 1978///////////////////////////////////////////////////////////////////////////////
1979// DONE
1842u16 MXL_OverwriteICDefault(struct dvb_frontend *fe) 1980u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
1843{ 1981{
1844 u16 status = 0; 1982 u16 status = 0;
@@ -1876,6 +2014,7 @@ u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
1876// > 0 : Failed // 2014// > 0 : Failed //
1877// // 2015// //
1878/////////////////////////////////////////////////////////////////////////////// 2016///////////////////////////////////////////////////////////////////////////////
2017// DONE
1879u16 MXL_BlockInit(struct dvb_frontend *fe) 2018u16 MXL_BlockInit(struct dvb_frontend *fe)
1880{ 2019{
1881 struct mxl5005s_state *state = fe->tuner_priv; 2020 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1903,7 +2042,6 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
1903 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2); 2042 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
1904 break; 2043 break;
1905 case 6000000: 2044 case 6000000:
1906 printk("%s() doing 6MHz digital\n", __func__);
1907 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 3); 2045 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 3);
1908 break; 2046 break;
1909 } 2047 }
@@ -1934,6 +2072,7 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
1934 else /* Single AGC Mode Dig Ana */ 2072 else /* Single AGC Mode Dig Ana */
1935 status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12); 2073 status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
1936 2074
2075
1937 if (state->TOP == 55) /* TOP == 5.5 */ 2076 if (state->TOP == 55) /* TOP == 5.5 */
1938 status += MXL_ControlWrite(fe, AGC_IF, 0x0); 2077 status += MXL_ControlWrite(fe, AGC_IF, 0x0);
1939 2078
@@ -2163,8 +2302,6 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
2163 status += MXL_ControlWrite(fe, BB_IQSWAP, 0); 2302 status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
2164 else /* High IF */ 2303 else /* High IF */
2165 status += MXL_ControlWrite(fe, BB_IQSWAP, 1); 2304 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2166 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
2167
2168 } 2305 }
2169 if (state->Mod_Type == MXL_ANALOG_CABLE) { 2306 if (state->Mod_Type == MXL_ANALOG_CABLE) {
2170 /* Analog Cable Mode */ 2307 /* Analog Cable Mode */
@@ -2201,7 +2338,7 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
2201 } 2338 }
2202 2339
2203 /* RSSI disable */ 2340 /* RSSI disable */
2204 if(state->EN_RSSI == 0) { 2341 if(state->EN_RSSI==0) {
2205 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); 2342 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2206 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); 2343 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2207 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0); 2344 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
@@ -2410,7 +2547,6 @@ u16 MXL_IFSynthInit(struct dvb_frontend *fe)
2410 Fref = 324000000UL ; 2547 Fref = 324000000UL ;
2411 } 2548 }
2412 if (state->IF_LO == 5380000UL) { 2549 if (state->IF_LO == 5380000UL) {
2413 printk("%s() doing 5.38\n", __func__);
2414 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07) ; 2550 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07) ;
2415 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C) ; 2551 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C) ;
2416 Fref = 322800000UL ; 2552 Fref = 322800000UL ;
@@ -3093,7 +3229,6 @@ u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
3093 3229
3094 if (state->TF_Type == MXL_TF_C_H) // Tracking Filter type C-H for Hauppauge only 3230 if (state->TF_Type == MXL_TF_C_H) // Tracking Filter type C-H for Hauppauge only
3095 { 3231 {
3096 printk("%s() CH filter\n", __func__);
3097 status += MXL_ControlWrite(fe, DAC_DIN_A, 0) ; 3232 status += MXL_ControlWrite(fe, DAC_DIN_A, 0) ;
3098 3233
3099 if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) 3234 if (state->RF_IN >= 43000000 && state->RF_IN < 150000000)
@@ -3632,6 +3767,7 @@ u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
3632 return status ; 3767 return status ;
3633} 3768}
3634 3769
3770// DONE
3635u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val) 3771u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
3636{ 3772{
3637 u16 status = 0; 3773 u16 status = 0;
@@ -3698,6 +3834,7 @@ u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
3698// >0 : Value exceed maximum allowed for control number // 3834// >0 : Value exceed maximum allowed for control number //
3699// // 3835// //
3700/////////////////////////////////////////////////////////////////////////////// 3836///////////////////////////////////////////////////////////////////////////////
3837// DONE
3701u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value) 3838u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
3702{ 3839{
3703 u16 status = 0; 3840 u16 status = 0;
@@ -3738,6 +3875,7 @@ u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
3738// 2 : Control name not found // 3875// 2 : Control name not found //
3739// // 3876// //
3740/////////////////////////////////////////////////////////////////////////////// 3877///////////////////////////////////////////////////////////////////////////////
3878// DONE
3741u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, u32 value, u16 controlGroup) 3879u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, u32 value, u16 controlGroup)
3742{ 3880{
3743 struct mxl5005s_state *state = fe->tuner_priv; 3881 struct mxl5005s_state *state = fe->tuner_priv;
@@ -3844,6 +3982,7 @@ u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, u32 value, u
3844// -1 : Invalid Register Address // 3982// -1 : Invalid Register Address //
3845// // 3983// //
3846/////////////////////////////////////////////////////////////////////////////// 3984///////////////////////////////////////////////////////////////////////////////
3985// DONE
3847u16 MXL_RegWrite(struct dvb_frontend *fe, u8 RegNum, u8 RegVal) 3986u16 MXL_RegWrite(struct dvb_frontend *fe, u8 RegNum, u8 RegVal)
3848{ 3987{
3849 struct mxl5005s_state *state = fe->tuner_priv; 3988 struct mxl5005s_state *state = fe->tuner_priv;
@@ -3883,6 +4022,7 @@ u16 MXL_RegWrite(struct dvb_frontend *fe, u8 RegNum, u8 RegVal)
3883// -1 : Invalid Register Address // 4022// -1 : Invalid Register Address //
3884// // 4023// //
3885/////////////////////////////////////////////////////////////////////////////// 4024///////////////////////////////////////////////////////////////////////////////
4025// DONE
3886u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal) 4026u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
3887{ 4027{
3888 struct mxl5005s_state *state = fe->tuner_priv; 4028 struct mxl5005s_state *state = fe->tuner_priv;
@@ -3919,6 +4059,7 @@ u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
3919// -1 : Invalid control name // 4059// -1 : Invalid control name //
3920// // 4060// //
3921/////////////////////////////////////////////////////////////////////////////// 4061///////////////////////////////////////////////////////////////////////////////
4062// DONE
3922u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value) 4063u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
3923{ 4064{
3924 struct mxl5005s_state *state = fe->tuner_priv; 4065 struct mxl5005s_state *state = fe->tuner_priv;
@@ -3990,6 +4131,7 @@ u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
3990// -1 : Invalid control name // 4131// -1 : Invalid control name //
3991// // 4132// //
3992/////////////////////////////////////////////////////////////////////////////// 4133///////////////////////////////////////////////////////////////////////////////
4134// DONE
3993u16 MXL_ControlRegRead(struct dvb_frontend *fe, u16 controlNum, u8 *RegNum, int * count) 4135u16 MXL_ControlRegRead(struct dvb_frontend *fe, u16 controlNum, u8 *RegNum, int * count)
3994{ 4136{
3995 struct mxl5005s_state *state = fe->tuner_priv; 4137 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4095,6 +4237,7 @@ u16 MXL_ControlRegRead(struct dvb_frontend *fe, u16 controlNum, u8 *RegNum, int
4095// NONE // 4237// NONE //
4096// // 4238// //
4097/////////////////////////////////////////////////////////////////////////////// 4239///////////////////////////////////////////////////////////////////////////////
4240// DONE
4098void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, u8 bitVal) 4241void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, u8 bitVal)
4099{ 4242{
4100 struct mxl5005s_state *state = fe->tuner_priv; 4243 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4142,6 +4285,7 @@ void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, u8 bitVal)
4142// Computed value // 4285// Computed value //
4143// // 4286// //
4144/////////////////////////////////////////////////////////////////////////////// 4287///////////////////////////////////////////////////////////////////////////////
4288// DONE
4145u32 MXL_Ceiling(u32 value, u32 resolution) 4289u32 MXL_Ceiling(u32 value, u32 resolution)
4146{ 4290{
4147 return (value/resolution + (value % resolution > 0 ? 1 : 0)); 4291 return (value/resolution + (value % resolution > 0 ? 1 : 0));
@@ -4150,6 +4294,7 @@ u32 MXL_Ceiling(u32 value, u32 resolution)
4150// 4294//
4151// Retrieve the Initialzation Registers 4295// Retrieve the Initialzation Registers
4152// 4296//
4297// DONE
4153u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4298u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4154{ 4299{
4155 u16 status = 0; 4300 u16 status = 0;
@@ -4172,6 +4317,7 @@ u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *c
4172 return status; 4317 return status;
4173} 4318}
4174 4319
4320// DONE
4175u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4321u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4176{ 4322{
4177 u16 status = 0; 4323 u16 status = 0;
@@ -4199,6 +4345,7 @@ u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *cou
4199 return status; 4345 return status;
4200} 4346}
4201 4347
4348// DONE
4202u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4349u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4203{ 4350{
4204 u16 status = 0; 4351 u16 status = 0;
@@ -4216,6 +4363,7 @@ u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, i
4216 return status; 4363 return status;
4217} 4364}
4218 4365
4366// DONE
4219u16 MXL_GetCHRegister_LowIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4367u16 MXL_GetCHRegister_LowIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4220{ 4368{
4221 u16 status = 0; 4369 u16 status = 0;
@@ -4233,6 +4381,7 @@ u16 MXL_GetCHRegister_LowIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, in
4233 return status; 4381 return status;
4234} 4382}
4235 4383
4384// DONE
4236u16 MXL_GetMasterControl(u8 *MasterReg, int state) 4385u16 MXL_GetMasterControl(u8 *MasterReg, int state)
4237{ 4386{
4238 if (state == 1) /* Load_Start */ 4387 if (state == 1) /* Load_Start */
@@ -4377,6 +4526,7 @@ u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
4377 return status; 4526 return status;
4378} 4527}
4379 4528
4529// DONE
4380u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis) 4530u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
4381{ 4531{
4382 struct mxl5005s_state *state = fe->tuner_priv; 4532 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4387,224 +4537,141 @@ u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
4387 4537
4388 return status; 4538 return status;
4389} 4539}
4540
4390#endif 4541#endif
4391/* End: Reference driver code found in the Realtek driver that
4392 * is copyright MaxLinear */
4393 4542
4394/* ---------------------------------------------------------------- 4543/* Linux driver related functions */
4395 * Begin: Everything after here is new code to adapt the 4544
4396 * proprietary Realtek driver into a Linux API tuner. 4545
4397 * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4546int mxl5005s_init(struct dvb_frontend *fe)
4398 */
4399static int mxl5005s_reset(struct dvb_frontend *fe)
4400{ 4547{
4401 struct mxl5005s_state *state = fe->tuner_priv; 4548 int MxlModMode;
4402 int ret = 0; 4549 int MxlIfMode;
4550 unsigned long MxlBandwitdh;
4551 unsigned long MxlIfFreqHz;
4552 unsigned long MxlCrystalFreqHz;
4553 int MxlAgcMode;
4554 unsigned short MxlTop;
4555 unsigned short MxlIfOutputLoad;
4556 int MxlClockOut;
4557 int MxlDivOut;
4558 int MxlCapSel;
4559 int MxlRssiOnOff;
4560 unsigned char MxlStandard;
4561 unsigned char MxlTfType;
4403 4562
4404 u8 buf[2] = { 0xff, 0x00 }; 4563 /* Set MxL5005S parameters. */
4405 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0, 4564 MxlModMode = MXL_DIGITAL_MODE;
4406 .buf = buf, .len = 2 }; 4565 MxlIfMode = MXL_ZERO_IF;
4566// steve
4567 //MxlBandwitdh = MXL5005S_BANDWIDTH_8MHZ;
4568 //MxlIfFreqHz = IF_FREQ_4570000HZ;
4569 MxlBandwitdh = MXL5005S_BANDWIDTH_6MHZ; // config
4570 MxlIfFreqHz = IF_FREQ_5380000HZ; // config
4571 MxlCrystalFreqHz = CRYSTAL_FREQ_16000000HZ; // config
4572 MxlAgcMode = MXL_SINGLE_AGC;
4573 MxlTop = MXL5005S_TOP_25P2;
4574 MxlIfOutputLoad = MXL5005S_IF_OUTPUT_LOAD_200_OHM;
4575 MxlClockOut = MXL_CLOCK_OUT_DISABLE;
4576 MxlDivOut = MXL_DIV_OUT_4;
4577 MxlCapSel = MXL_CAP_SEL_ENABLE;
4578 MxlRssiOnOff = MXL_RSSI_ENABLE; // config
4579 MxlTfType = MXL_TF_C_H; // config
4580
4581 MxlStandard = MXL_ATSC; // config
4582
4583 // TODO: this is bad, it trashes other configs
4584 // Set MxL5005S extra module.
4585 //pExtra->AgcMasterByte = (MxlAgcMode == MXL_DUAL_AGC) ? 0x4 : 0x0;
4407 4586
4408 dprintk(2, "%s()\n", __func__); 4587 MXL5005_TunerConfig(
4588 fe,
4589 (unsigned char)MxlModMode,
4590 (unsigned char)MxlIfMode,
4591 MxlBandwitdh,
4592 MxlIfFreqHz,
4593 MxlCrystalFreqHz,
4594 (unsigned char)MxlAgcMode,
4595 MxlTop,
4596 MxlIfOutputLoad,
4597 (unsigned char)MxlClockOut,
4598 (unsigned char)MxlDivOut,
4599 (unsigned char)MxlCapSel,
4600 (unsigned char)MxlRssiOnOff,
4601 MxlStandard, MxlTfType);
4602
4603 return mxl5005s_init2(fe);
4604}
4409 4605
4410 if (fe->ops.i2c_gate_ctrl) 4606static int mxl5005s_set_params(struct dvb_frontend *fe,
4411 fe->ops.i2c_gate_ctrl(fe, 1); 4607 struct dvb_frontend_parameters *params)
4608{
4609 u32 freq;
4610 u32 bw;
4412 4611
4413 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 4612 if (fe->ops.info.type == FE_OFDM)
4414 printk(KERN_WARNING "mxl5005s I2C reset failed\n"); 4613 bw = params->u.ofdm.bandwidth;
4415 ret = -EREMOTEIO; 4614 else
4416 } 4615 bw = MXL5005S_BANDWIDTH_6MHZ;
4417 4616
4418 if (fe->ops.i2c_gate_ctrl) 4617 freq = params->frequency; /* Hz */
4419 fe->ops.i2c_gate_ctrl(fe, 0); 4618 dprintk(1, "%s() freq=%d bw=%d\n", __func__, freq, bw);
4420 4619
4421 return ret; 4620 return mxl5005s_SetRfFreqHz(fe, freq);
4422} 4621}
4423 4622
4424/* Write a single byte to a single reg, latch the value if required by 4623static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
4425 * following the transaction with the latch byte.
4426 */
4427static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
4428{ 4624{
4429 struct mxl5005s_state *state = fe->tuner_priv; 4625 struct mxl5005s_state *state = fe->tuner_priv;
4430 u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE }; 4626 dprintk(1, "%s()\n", __func__);
4431 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
4432 .buf = buf, .len = 3 };
4433
4434 if (latch == 0)
4435 msg.len = 2;
4436 4627
4437 dprintk(2, "%s(reg = 0x%x val = 0x%x addr = 0x%x)\n", __func__, reg, val, msg.addr); 4628 *frequency = state->RF_IN;
4438 4629
4439 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
4440 printk(KERN_WARNING "mxl5005s I2C write failed\n");
4441 return -EREMOTEIO;
4442 }
4443 return 0; 4630 return 0;
4444} 4631}
4445 4632
4446int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, u8 *datatable, u8 len) 4633static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
4447{ 4634{
4448 int ret = 0, i; 4635 struct mxl5005s_state *state = fe->tuner_priv;
4449 4636 dprintk(1, "%s()\n", __func__);
4450 if (fe->ops.i2c_gate_ctrl)
4451 fe->ops.i2c_gate_ctrl(fe, 1);
4452
4453 for (i = 0 ; i < len-1; i++) {
4454 ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
4455 if (ret < 0)
4456 break;
4457 }
4458
4459 ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
4460 4637
4461 if (fe->ops.i2c_gate_ctrl) 4638 *bandwidth = state->Chan_Bandwidth;
4462 fe->ops.i2c_gate_ctrl(fe, 0);
4463 4639
4464 return ret; 4640 return 0;
4465} 4641}
4466 4642
4467 4643static int mxl5005s_get_status(struct dvb_frontend *fe, u32 *status)
4468int mxl5005s_init(struct dvb_frontend *fe)
4469{ 4644{
4470 dprintk(1, "%s()\n", __func__); 4645 dprintk(1, "%s()\n", __func__);
4471 return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ); 4646
4647 *status = 0;
4648 // *status = TUNER_STATUS_LOCKED;
4649
4650 return 0;
4472} 4651}
4473 4652
4474int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth) 4653static int mxl5005s_init2(struct dvb_frontend *fe)
4475{ 4654{
4476 struct mxl5005s_state *state = fe->tuner_priv; 4655 struct mxl5005s_state *state = fe->tuner_priv;
4477
4478 u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 4656 u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
4479 u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 4657 u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
4480 int TableLen; 4658 int TableLen;
4481 4659
4482 dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth); 4660 dprintk(1, "%s()\n", __func__);
4483 4661
4484 mxl5005s_reset(fe); 4662 /* Initialize MxL5005S tuner according to MxL5005S tuner example code. */
4485 4663
4486 /* Tuner initialization stage 0 */ 4664 /* Tuner initialization stage 0 */
4487 MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET); 4665 MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
4488 AddrTable[0] = MASTER_CONTROL_ADDR; 4666 AddrTable[0] = MASTER_CONTROL_ADDR;
4489 ByteTable[0] |= state->config->AgcMasterByte; 4667 ByteTable[0] |= state->config->AgcMasterByte;
4490 4668
4491 mxl5005s_writeregs(fe, AddrTable, ByteTable, 1); 4669 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, 1);
4492
4493 mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
4494 4670
4495 /* Tuner initialization stage 1 */ 4671 /* Tuner initialization stage 1 */
4496 MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen); 4672 MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
4497 4673
4498 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen); 4674 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, TableLen);
4499
4500 return 0;
4501}
4502
4503int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth)
4504{
4505 struct mxl5005s_state *state = fe->tuner_priv;
4506 struct mxl5005s_config *c = state->config;
4507
4508 InitTunerControls(fe);
4509
4510 /* Set MxL5005S parameters. */
4511 MXL5005_TunerConfig(
4512 fe,
4513 c->mod_mode,
4514 c->if_mode,
4515 bandwidth,
4516 c->if_freq,
4517 c->xtal_freq,
4518 c->agc_mode,
4519 c->top,
4520 c->output_load,
4521 c->clock_out,
4522 c->div_out,
4523 c->cap_select,
4524 c->rssi_enable,
4525 mod_type,
4526 c->tracking_filter);
4527
4528 return 0;
4529}
4530
4531static int mxl5005s_set_params(struct dvb_frontend *fe,
4532 struct dvb_frontend_parameters *params)
4533{
4534 struct mxl5005s_state *state = fe->tuner_priv;
4535 u32 req_mode, req_bw = 0;
4536 int ret;
4537
4538 dprintk(1, "%s()\n", __func__);
4539
4540 if (fe->ops.info.type == FE_ATSC) {
4541 switch (params->u.vsb.modulation) {
4542 case VSB_8:
4543 req_mode = MXL_ATSC; break;
4544 default:
4545 case QAM_64:
4546 case QAM_256:
4547 case QAM_AUTO:
4548 req_mode = MXL_QAM; break;
4549 }
4550 }
4551 else req_mode = MXL_DVBT;
4552
4553 /* Change tuner for new modulation type if reqd */
4554 if (req_mode != state->current_mode) {
4555 switch (req_mode) {
4556 case VSB_8:
4557 case QAM_64:
4558 case QAM_256:
4559 case QAM_AUTO:
4560 req_bw = MXL5005S_BANDWIDTH_6MHZ;
4561 break;
4562 default:
4563 /* Assume DVB-T */
4564 switch (params->u.ofdm.bandwidth) {
4565 case BANDWIDTH_6_MHZ:
4566 req_bw = MXL5005S_BANDWIDTH_6MHZ;
4567 break;
4568 case BANDWIDTH_7_MHZ:
4569 req_bw = MXL5005S_BANDWIDTH_7MHZ;
4570 break;
4571 case BANDWIDTH_AUTO:
4572 case BANDWIDTH_8_MHZ:
4573 req_bw = MXL5005S_BANDWIDTH_8MHZ;
4574 break;
4575 }
4576 }
4577
4578 state->current_mode = req_mode;
4579 ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
4580
4581 } else
4582 ret = 0;
4583
4584 if (ret == 0) {
4585 dprintk(1, "%s() freq=%d\n", __func__, params->frequency);
4586 ret = mxl5005s_SetRfFreqHz(fe, params->frequency);
4587 }
4588
4589 return ret;
4590}
4591
4592static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
4593{
4594 struct mxl5005s_state *state = fe->tuner_priv;
4595 dprintk(1, "%s()\n", __func__);
4596
4597 *frequency = state->RF_IN;
4598
4599 return 0;
4600}
4601
4602static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
4603{
4604 struct mxl5005s_state *state = fe->tuner_priv;
4605 dprintk(1, "%s()\n", __func__);
4606
4607 *bandwidth = state->Chan_Bandwidth;
4608 4675
4609 return 0; 4676 return 0;
4610} 4677}
@@ -4631,6 +4698,7 @@ static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
4631 .set_params = mxl5005s_set_params, 4698 .set_params = mxl5005s_set_params,
4632 .get_frequency = mxl5005s_get_frequency, 4699 .get_frequency = mxl5005s_get_frequency,
4633 .get_bandwidth = mxl5005s_get_bandwidth, 4700 .get_bandwidth = mxl5005s_get_bandwidth,
4701 .get_status = mxl5005s_get_status
4634}; 4702};
4635 4703
4636struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, 4704struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
@@ -4647,7 +4715,6 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
4647 state->frontend = fe; 4715 state->frontend = fe;
4648 state->config = config; 4716 state->config = config;
4649 state->i2c = i2c; 4717 state->i2c = i2c;
4650 state->current_mode = MXL_QAM;
4651 4718
4652 printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", config->i2c_address); 4719 printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", config->i2c_address);
4653 4720
@@ -4659,5 +4726,8 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
4659EXPORT_SYMBOL(mxl5005s_attach); 4726EXPORT_SYMBOL(mxl5005s_attach);
4660 4727
4661MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver"); 4728MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
4729MODULE_AUTHOR("Jan Hoogenraad");
4730MODULE_AUTHOR("Barnaby Shearer");
4731MODULE_AUTHOR("Andy Hasper");
4662MODULE_AUTHOR("Steven Toth"); 4732MODULE_AUTHOR("Steven Toth");
4663MODULE_LICENSE("GPL"); 4733MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 7658401f3cdd..7d0727d44536 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -1,119 +1,66 @@
1/* 1/*
2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver 2 * For the Realtek RTL chip RTL2831U
3 * Realtek Release Date: 2008-03-14, ver 080314
4 * Realtek version RTL2831 Linux driver version 080314
5 * ver 080314
6 *
7 * for linux kernel version 2.6.21.4 - 2.6.22-14
8 * support MXL5005s and MT2060 tuners (support tuner auto-detecting)
9 * support two IR types -- RC5 and NEC
10 *
11 * Known boards with Realtek RTL chip RTL2821U
12 * Freecom USB stick 14aa:0160 (version 4)
13 * Conceptronic CTVDIGRCU
14 *
15 * Copyright (c) 2008 Realtek
16 * Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper
17 * This code is placed under the terms of the GNU General Public License
18 *
19 * Released by Realtek under GPLv2.
20 * Thanks to Realtek for a lot of support we received !
21 *
22 * Revision: 080314 - original version
23 */
3 24
4 Copyright (C) 2008 MaxLinear
5 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
6 25
7 This program is free software; you can redistribute it and/or modify 26#ifndef __MXL5005S_H
8 it under the terms of the GNU General Public License as published by 27#define __MXL5005S_H
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 GNU General Public License for more details.
16 28
17 You should have received a copy of the GNU General Public License 29#include <linux/dvb/frontend.h>
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 30
21*/ 31/* IF frequency */
32enum IF_FREQ_HZ
33{
34 IF_FREQ_4570000HZ = 4570000, ///< IF frequency = 4.57 MHz
35 IF_FREQ_4571429HZ = 4571429, ///< IF frequency = 4.571 MHz
36 IF_FREQ_5380000HZ = 5380000, ///< IF frequency = 5.38 MHz
37 IF_FREQ_36000000HZ = 36000000, ///< IF frequency = 36.000 MHz
38 IF_FREQ_36125000HZ = 36125000, ///< IF frequency = 36.125 MHz
39 IF_FREQ_36166667HZ = 36166667, ///< IF frequency = 36.167 MHz
40 IF_FREQ_44000000HZ = 44000000, ///< IF frequency = 44.000 MHz
41};
22 42
23#ifndef __MXL5005S_H 43/* Crystal frequency */
24#define __MXL5005S_H 44enum CRYSTAL_FREQ_HZ
45{
46 CRYSTAL_FREQ_4000000HZ = 4000000, ///< Crystal frequency = 4.0 MHz
47 CRYSTAL_FREQ_16000000HZ = 16000000, ///< Crystal frequency = 16.0 MHz
48 CRYSTAL_FREQ_25000000HZ = 25000000, ///< Crystal frequency = 25.0 MHz
49 CRYSTAL_FREQ_28800000HZ = 28800000, ///< Crystal frequency = 28.8 MHz
50};
25 51
26struct mxl5005s_config 52struct mxl5005s_config
27{ 53{
28 /* 7 bit i2c address */
29 u8 i2c_address; 54 u8 i2c_address;
30 55
31#define IF_FREQ_4570000HZ 4570000
32#define IF_FREQ_4571429HZ 4571429
33#define IF_FREQ_5380000HZ 5380000
34#define IF_FREQ_36000000HZ 36000000
35#define IF_FREQ_36125000HZ 36125000
36#define IF_FREQ_36166667HZ 36166667
37#define IF_FREQ_44000000HZ 44000000
38 u32 if_freq;
39
40#define CRYSTAL_FREQ_4000000HZ 4000000
41#define CRYSTAL_FREQ_16000000HZ 16000000
42#define CRYSTAL_FREQ_25000000HZ 25000000
43#define CRYSTAL_FREQ_28800000HZ 28800000
44 u32 xtal_freq;
45
46#define MXL_DUAL_AGC 0
47#define MXL_SINGLE_AGC 1
48 u8 agc_mode;
49
50#define MXL_TF_DEFAULT 0
51#define MXL_TF_OFF 1
52#define MXL_TF_C 2
53#define MXL_TF_C_H 3
54#define MXL_TF_D 4
55#define MXL_TF_D_L 5
56#define MXL_TF_E 6
57#define MXL_TF_F 7
58#define MXL_TF_E_2 8
59#define MXL_TF_E_NA 9
60#define MXL_TF_G 10
61 u8 tracking_filter;
62
63#define MXL_RSSI_DISABLE 0
64#define MXL_RSSI_ENABLE 1
65 u8 rssi_enable;
66
67#define MXL_CAP_SEL_DISABLE 0
68#define MXL_CAP_SEL_ENABLE 1
69 u8 cap_select;
70
71#define MXL_DIV_OUT_1 0
72#define MXL_DIV_OUT_4 1
73 u8 div_out;
74
75#define MXL_CLOCK_OUT_DISABLE 0
76#define MXL_CLOCK_OUT_ENABLE 1
77 u8 clock_out;
78
79#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
80#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
81 u32 output_load;
82
83#define MXL5005S_TOP_5P5 55
84#define MXL5005S_TOP_7P2 72
85#define MXL5005S_TOP_9P2 92
86#define MXL5005S_TOP_11P0 110
87#define MXL5005S_TOP_12P9 129
88#define MXL5005S_TOP_14P7 147
89#define MXL5005S_TOP_16P8 168
90#define MXL5005S_TOP_19P4 194
91#define MXL5005S_TOP_21P2 212
92#define MXL5005S_TOP_23P2 232
93#define MXL5005S_TOP_25P2 252
94#define MXL5005S_TOP_27P1 271
95#define MXL5005S_TOP_29P2 292
96#define MXL5005S_TOP_31P7 317
97#define MXL5005S_TOP_34P9 349
98 u32 top;
99
100#define MXL_ANALOG_MODE 0
101#define MXL_DIGITAL_MODE 1
102 u8 mod_mode;
103
104#define MXL_ZERO_IF 0
105#define MXL_LOW_IF 1
106 u8 if_mode;
107
108 /* Stuff I don't know what to do with */ 56 /* Stuff I don't know what to do with */
109 u8 AgcMasterByte; 57 u8 AgcMasterByte;
110}; 58};
111 59
112#if defined(CONFIG_DVB_TUNER_MXL5005S) || \ 60#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || (defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
113 (defined(CONFIG_DVB_TUNER_MXL5005S_MODULE) && defined(MODULE))
114extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, 61extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
115 struct i2c_adapter *i2c, 62 struct i2c_adapter *i2c,
116 struct mxl5005s_config *config) 63 struct mxl5005s_config *config);
117#else 64#else
118static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, 65static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
119 struct i2c_adapter *i2c, 66 struct i2c_adapter *i2c,