aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2008-05-01 06:15:38 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-05-14 01:56:39 -0400
commit48937295a63b4e81db907605afcbd81e0464b00f (patch)
tree7ac1544b2a4a413289b386fab93b64e1d09f86fa /drivers/media
parent5c1b20514f592af19974166f130b85346c1fbf3a (diff)
V4L/DVB(7871): mxl5005s: Re-org code and update copyrights
Re-org code and update copyrights Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/common/tuners/mxl5005s.c608
-rw-r--r--drivers/media/common/tuners/mxl5005s.h143
2 files changed, 371 insertions, 380 deletions
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 64aa864c5dbf..45ac6a9e71a3 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -1,27 +1,62 @@
1/* 1/*
2 * For the Realtek RTL chip RTL2831U 2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
3 * Realtek Release Date: 2008-03-14, ver 080314 3
4 * Realtek version RTL2831 Linux driver version 080314 4 Copyright (C) 2008 MaxLinear
5 * ver 080314 5 Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
6 * 6 Functions:
7 * for linux kernel version 2.6.21.4 - 2.6.22-14 7 mxl5005s_reset()
8 * support MXL5005s and MT2060 tuners (support tuner auto-detecting) 8 mxl5005s_writereg()
9 * support two IR types -- RC5 and NEC 9 mxl5005s_writeregs()
10 * 10 mxl5005s_init()
11 * Known boards with Realtek RTL chip RTL2821U 11 mxl5005s_reconfigure()
12 * Freecom USB stick 14aa:0160 (version 4) 12 mxl5005s_AssignTunerMode()
13 * Conceptronic CTVDIGRCU 13 mxl5005s_set_params()
14 * 14 mxl5005s_get_frequency()
15 * Copyright (c) 2008 Realtek 15 mxl5005s_get_bandwidth()
16 * Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper 16 mxl5005s_release()
17 * This code is placed under the terms of the GNU General Public License 17 mxl5005s_attach()
18 * 18
19 * Released by Realtek under GPLv2. 19 Copyright (c) 2008 Realtek
20 * Thanks to Realtek for a lot of support we received ! 20 Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper
21 * 21 Functions:
22 * Revision: 080314 - original version 22 mxl5005s_SetRfFreqHz()
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.
24 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*/
25#include <linux/kernel.h> 60#include <linux/kernel.h>
26#include <linux/init.h> 61#include <linux/init.h>
27#include <linux/module.h> 62#include <linux/module.h>
@@ -31,10 +66,10 @@
31#include "dvb_frontend.h" 66#include "dvb_frontend.h"
32#include "mxl5005s.h" 67#include "mxl5005s.h"
33 68
34static int debug; 69static int debug = 2;
35 70
36#define dprintk(level, arg...) do { \ 71#define dprintk(level, arg...) do { \
37 if (debug >= level) \ 72 if (level <= debug) \
38 printk(arg); \ 73 printk(arg); \
39 } while (0) 74 } while (0)
40 75
@@ -50,13 +85,6 @@ static int debug;
50#define MXLCTRL_NUM 189 85#define MXLCTRL_NUM 189
51#define MASTER_CONTROL_ADDR 9 86#define MASTER_CONTROL_ADDR 9
52 87
53/* Enumeration of AGC Mode */
54typedef enum
55{
56 MXL_DUAL_AGC = 0,
57 MXL_SINGLE_AGC
58} AGC_Mode;
59
60/* Enumeration of Master Control Register State */ 88/* Enumeration of Master Control Register State */
61typedef enum 89typedef enum
62{ 90{
@@ -66,51 +94,6 @@ typedef enum
66 MC_SEQ_OFF 94 MC_SEQ_OFF
67} Master_Control_State; 95} Master_Control_State;
68 96
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
114/* Enumeration of MXL5005 Tuner Modulation Type */ 97/* Enumeration of MXL5005 Tuner Modulation Type */
115typedef enum 98typedef enum
116{ 99{
@@ -122,22 +105,6 @@ typedef enum
122 MXL_ANALOG_OTA 105 MXL_ANALOG_OTA
123} Tuner_Modu_Type; 106} Tuner_Modu_Type;
124 107
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
141/* MXL5005 Tuner Register Struct */ 108/* MXL5005 Tuner Register Struct */
142typedef struct _TunerReg_struct 109typedef struct _TunerReg_struct
143{ 110{
@@ -268,33 +235,6 @@ enum
268}; 235};
269#define MXL5005S_BANDWIDTH_MODE_NUM 3 236#define MXL5005S_BANDWIDTH_MODE_NUM 3
270 237
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
298/* MXL5005 Tuner Control Struct */ 238/* MXL5005 Tuner Control Struct */
299typedef struct _TunerControl_struct { 239typedef struct _TunerControl_struct {
300 u16 Ctrl_Num; /* Control Number */ 240 u16 Ctrl_Num; /* Control Number */
@@ -349,13 +289,15 @@ struct mxl5005s_state
349 TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */ 289 TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
350 290
351 /* Linux driver framework specific */ 291 /* Linux driver framework specific */
352 const struct mxl5005s_config *config; 292 struct mxl5005s_config *config;
353
354 struct dvb_frontend *frontend; 293 struct dvb_frontend *frontend;
355 struct i2c_adapter *i2c; 294 struct i2c_adapter *i2c;
295
296 /* Cache values */
297 u32 current_mode;
298
356}; 299};
357 300
358// funcs
359u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value); 301u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
360u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value); 302u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
361u16 MXL_GetMasterControl(u8 *MasterReg, int state); 303u16 MXL_GetMasterControl(u8 *MasterReg, int state);
@@ -372,14 +314,26 @@ u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
372void MXL_SynthIFLO_Calc(struct dvb_frontend *fe); 314void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
373void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe); 315void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
374u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal, int *count); 316u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal, int *count);
375int mxl5005s_SetRegsWithTable(struct dvb_frontend *fe, u8 *pAddrTable, u8 *pByteTable, int TableLen); 317int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, u8 *datatable, u8 len);
376u16 MXL_IFSynthInit(struct dvb_frontend *fe); 318u16 MXL_IFSynthInit(struct dvb_frontend *fe);
377static int mxl5005s_init2(struct dvb_frontend *fe); 319int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth);
320int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth);
321
322/* ----------------------------------------------------------------
323 * Begin: Custom code salvaged from the Realtek driver.
324 * Copyright (c) 2008 Realtek
325 * Copyright (c) 2008 Jan Hoogenraad, Barnaby Shearer, Andy Hasper
326 * This code is placed under the terms of the GNU General Public License
327 *
328 * Released by Realtek under GPLv2.
329 * Thanks to Realtek for a lot of support we received !
330 *
331 * Revision: 080314 - original version
332 */
378 333
379int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz) 334int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
380{ 335{
381 struct mxl5005s_state *state = fe->tuner_priv; 336 struct mxl5005s_state *state = fe->tuner_priv;
382 u8 AgcMasterByte = state->config->AgcMasterByte;
383 unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 337 unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
384 unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 338 unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
385 int TableLen; 339 int TableLen;
@@ -396,7 +350,7 @@ int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
396 AddrTable[0] = MASTER_CONTROL_ADDR; 350 AddrTable[0] = MASTER_CONTROL_ADDR;
397 ByteTable[0] |= state->config->AgcMasterByte; 351 ByteTable[0] |= state->config->AgcMasterByte;
398 352
399 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, 1); 353 mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
400 354
401 // Tuner RF frequency setting stage 1 355 // Tuner RF frequency setting stage 1
402 MXL_TuneRF(fe, RfFreqHz); 356 MXL_TuneRF(fe, RfFreqHz);
@@ -410,13 +364,13 @@ int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
410 364
411 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ; 365 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ;
412 AddrTable[TableLen] = MASTER_CONTROL_ADDR ; 366 AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
413 ByteTable[TableLen] = MasterControlByte | AgcMasterByte; 367 ByteTable[TableLen] = MasterControlByte | state->config->AgcMasterByte;
414 TableLen += 1; 368 TableLen += 1;
415 369
416 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, TableLen); 370 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
417 371
418 // Wait 30 ms. 372 // Wait 30 ms.
419 msleep(30); 373 msleep(150);
420 374
421 // Tuner RF frequency setting stage 2 375 // Tuner RF frequency setting stage 2
422 MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1) ; 376 MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1) ;
@@ -425,101 +379,21 @@ int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
425 379
426 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ; 380 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START) ;
427 AddrTable[TableLen] = MASTER_CONTROL_ADDR ; 381 AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
428 ByteTable[TableLen] = MasterControlByte | AgcMasterByte ; 382 ByteTable[TableLen] = MasterControlByte | state->config->AgcMasterByte ;
429 TableLen += 1; 383 TableLen += 1;
430 384
431 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, TableLen); 385 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
432 386
433 return 0; 387 msleep(100);
434}
435 388
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 }
448 return 0; 389 return 0;
449} 390}
391/* End: Custom code taken from the Realtek driver */
450 392
451/* Write a word to a single reg */ 393/* ----------------------------------------------------------------
452static int mxl5005s_writereg16(struct dvb_frontend *fe, u8 reg, u16 val) 394 * Begin: Reference driver code found in the Realtek driver.
453{ 395 * Copyright (c) 2008 MaxLinear
454 struct mxl5005s_state *state = fe->tuner_priv; 396 */
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
523u16 MXL5005_RegisterInit(struct dvb_frontend *fe) 397u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
524{ 398{
525 struct mxl5005s_state *state = fe->tuner_priv; 399 struct mxl5005s_state *state = fe->tuner_priv;
@@ -841,7 +715,6 @@ u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
841 return 0 ; 715 return 0 ;
842} 716}
843 717
844// DONE
845u16 MXL5005_ControlInit(struct dvb_frontend *fe) 718u16 MXL5005_ControlInit(struct dvb_frontend *fe)
846{ 719{
847 struct mxl5005s_state *state = fe->tuner_priv; 720 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1785,7 +1658,6 @@ u16 MXL5005_ControlInit(struct dvb_frontend *fe)
1785// MaxLinear source code - MXL5005_c.cpp 1658// MaxLinear source code - MXL5005_c.cpp
1786// MXL5005.cpp : Defines the initialization routines for the DLL. 1659// MXL5005.cpp : Defines the initialization routines for the DLL.
1787// 2.6.12 1660// 2.6.12
1788// DONE
1789void InitTunerControls(struct dvb_frontend *fe) 1661void InitTunerControls(struct dvb_frontend *fe)
1790{ 1662{
1791 MXL5005_RegisterInit(fe); 1663 MXL5005_RegisterInit(fe);
@@ -1828,7 +1700,6 @@ void InitTunerControls(struct dvb_frontend *fe)
1828// > 0 : Failed // 1700// > 0 : Failed //
1829// // 1701// //
1830/////////////////////////////////////////////////////////////////////////////// 1702///////////////////////////////////////////////////////////////////////////////
1831// DONE
1832u16 MXL5005_TunerConfig(struct dvb_frontend *fe, 1703u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
1833 u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */ 1704 u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */
1834 u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */ 1705 u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */
@@ -1898,7 +1769,6 @@ u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
1898// > 0 : Failed // 1769// > 0 : Failed //
1899// // 1770// //
1900/////////////////////////////////////////////////////////////////////////////// 1771///////////////////////////////////////////////////////////////////////////////
1901// DONE
1902void MXL_SynthIFLO_Calc(struct dvb_frontend *fe) 1772void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
1903{ 1773{
1904 struct mxl5005s_state *state = fe->tuner_priv; 1774 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1937,7 +1807,6 @@ void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
1937// > 0 : Failed // 1807// > 0 : Failed //
1938// // 1808// //
1939/////////////////////////////////////////////////////////////////////////////// 1809///////////////////////////////////////////////////////////////////////////////
1940// DONE
1941void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe) 1810void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
1942{ 1811{
1943 struct mxl5005s_state *state = fe->tuner_priv; 1812 struct mxl5005s_state *state = fe->tuner_priv;
@@ -1976,7 +1845,6 @@ void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
1976// > 0 : Failed // 1845// > 0 : Failed //
1977// // 1846// //
1978/////////////////////////////////////////////////////////////////////////////// 1847///////////////////////////////////////////////////////////////////////////////
1979// DONE
1980u16 MXL_OverwriteICDefault(struct dvb_frontend *fe) 1848u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
1981{ 1849{
1982 u16 status = 0; 1850 u16 status = 0;
@@ -2014,7 +1882,6 @@ u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
2014// > 0 : Failed // 1882// > 0 : Failed //
2015// // 1883// //
2016/////////////////////////////////////////////////////////////////////////////// 1884///////////////////////////////////////////////////////////////////////////////
2017// DONE
2018u16 MXL_BlockInit(struct dvb_frontend *fe) 1885u16 MXL_BlockInit(struct dvb_frontend *fe)
2019{ 1886{
2020 struct mxl5005s_state *state = fe->tuner_priv; 1887 struct mxl5005s_state *state = fe->tuner_priv;
@@ -2042,6 +1909,7 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
2042 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2); 1909 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
2043 break; 1910 break;
2044 case 6000000: 1911 case 6000000:
1912 printk("%s() doing 6MHz digital\n", __func__);
2045 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 3); 1913 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 3);
2046 break; 1914 break;
2047 } 1915 }
@@ -2072,7 +1940,6 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
2072 else /* Single AGC Mode Dig Ana */ 1940 else /* Single AGC Mode Dig Ana */
2073 status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12); 1941 status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
2074 1942
2075
2076 if (state->TOP == 55) /* TOP == 5.5 */ 1943 if (state->TOP == 55) /* TOP == 5.5 */
2077 status += MXL_ControlWrite(fe, AGC_IF, 0x0); 1944 status += MXL_ControlWrite(fe, AGC_IF, 0x0);
2078 1945
@@ -2302,6 +2169,8 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
2302 status += MXL_ControlWrite(fe, BB_IQSWAP, 0); 2169 status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
2303 else /* High IF */ 2170 else /* High IF */
2304 status += MXL_ControlWrite(fe, BB_IQSWAP, 1); 2171 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2172 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
2173
2305 } 2174 }
2306 if (state->Mod_Type == MXL_ANALOG_CABLE) { 2175 if (state->Mod_Type == MXL_ANALOG_CABLE) {
2307 /* Analog Cable Mode */ 2176 /* Analog Cable Mode */
@@ -2338,7 +2207,7 @@ u16 MXL_BlockInit(struct dvb_frontend *fe)
2338 } 2207 }
2339 2208
2340 /* RSSI disable */ 2209 /* RSSI disable */
2341 if(state->EN_RSSI==0) { 2210 if(state->EN_RSSI == 0) {
2342 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1); 2211 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2343 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1); 2212 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2344 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0); 2213 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
@@ -2547,6 +2416,7 @@ u16 MXL_IFSynthInit(struct dvb_frontend *fe)
2547 Fref = 324000000UL ; 2416 Fref = 324000000UL ;
2548 } 2417 }
2549 if (state->IF_LO == 5380000UL) { 2418 if (state->IF_LO == 5380000UL) {
2419 printk("%s() doing 5.38\n", __func__);
2550 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07) ; 2420 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07) ;
2551 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C) ; 2421 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C) ;
2552 Fref = 322800000UL ; 2422 Fref = 322800000UL ;
@@ -3229,6 +3099,7 @@ u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
3229 3099
3230 if (state->TF_Type == MXL_TF_C_H) // Tracking Filter type C-H for Hauppauge only 3100 if (state->TF_Type == MXL_TF_C_H) // Tracking Filter type C-H for Hauppauge only
3231 { 3101 {
3102 printk("%s() CH filter\n", __func__);
3232 status += MXL_ControlWrite(fe, DAC_DIN_A, 0) ; 3103 status += MXL_ControlWrite(fe, DAC_DIN_A, 0) ;
3233 3104
3234 if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) 3105 if (state->RF_IN >= 43000000 && state->RF_IN < 150000000)
@@ -3767,7 +3638,6 @@ u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
3767 return status ; 3638 return status ;
3768} 3639}
3769 3640
3770// DONE
3771u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val) 3641u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
3772{ 3642{
3773 u16 status = 0; 3643 u16 status = 0;
@@ -3834,7 +3704,6 @@ u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
3834// >0 : Value exceed maximum allowed for control number // 3704// >0 : Value exceed maximum allowed for control number //
3835// // 3705// //
3836/////////////////////////////////////////////////////////////////////////////// 3706///////////////////////////////////////////////////////////////////////////////
3837// DONE
3838u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value) 3707u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
3839{ 3708{
3840 u16 status = 0; 3709 u16 status = 0;
@@ -3875,7 +3744,6 @@ u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
3875// 2 : Control name not found // 3744// 2 : Control name not found //
3876// // 3745// //
3877/////////////////////////////////////////////////////////////////////////////// 3746///////////////////////////////////////////////////////////////////////////////
3878// DONE
3879u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, u32 value, u16 controlGroup) 3747u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, u32 value, u16 controlGroup)
3880{ 3748{
3881 struct mxl5005s_state *state = fe->tuner_priv; 3749 struct mxl5005s_state *state = fe->tuner_priv;
@@ -3982,7 +3850,6 @@ u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum, u32 value, u
3982// -1 : Invalid Register Address // 3850// -1 : Invalid Register Address //
3983// // 3851// //
3984/////////////////////////////////////////////////////////////////////////////// 3852///////////////////////////////////////////////////////////////////////////////
3985// DONE
3986u16 MXL_RegWrite(struct dvb_frontend *fe, u8 RegNum, u8 RegVal) 3853u16 MXL_RegWrite(struct dvb_frontend *fe, u8 RegNum, u8 RegVal)
3987{ 3854{
3988 struct mxl5005s_state *state = fe->tuner_priv; 3855 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4022,7 +3889,6 @@ u16 MXL_RegWrite(struct dvb_frontend *fe, u8 RegNum, u8 RegVal)
4022// -1 : Invalid Register Address // 3889// -1 : Invalid Register Address //
4023// // 3890// //
4024/////////////////////////////////////////////////////////////////////////////// 3891///////////////////////////////////////////////////////////////////////////////
4025// DONE
4026u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal) 3892u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
4027{ 3893{
4028 struct mxl5005s_state *state = fe->tuner_priv; 3894 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4059,7 +3925,6 @@ u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
4059// -1 : Invalid control name // 3925// -1 : Invalid control name //
4060// // 3926// //
4061/////////////////////////////////////////////////////////////////////////////// 3927///////////////////////////////////////////////////////////////////////////////
4062// DONE
4063u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value) 3928u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
4064{ 3929{
4065 struct mxl5005s_state *state = fe->tuner_priv; 3930 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4131,7 +3996,6 @@ u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
4131// -1 : Invalid control name // 3996// -1 : Invalid control name //
4132// // 3997// //
4133/////////////////////////////////////////////////////////////////////////////// 3998///////////////////////////////////////////////////////////////////////////////
4134// DONE
4135u16 MXL_ControlRegRead(struct dvb_frontend *fe, u16 controlNum, u8 *RegNum, int * count) 3999u16 MXL_ControlRegRead(struct dvb_frontend *fe, u16 controlNum, u8 *RegNum, int * count)
4136{ 4000{
4137 struct mxl5005s_state *state = fe->tuner_priv; 4001 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4237,7 +4101,6 @@ u16 MXL_ControlRegRead(struct dvb_frontend *fe, u16 controlNum, u8 *RegNum, int
4237// NONE // 4101// NONE //
4238// // 4102// //
4239/////////////////////////////////////////////////////////////////////////////// 4103///////////////////////////////////////////////////////////////////////////////
4240// DONE
4241void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, u8 bitVal) 4104void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, u8 bitVal)
4242{ 4105{
4243 struct mxl5005s_state *state = fe->tuner_priv; 4106 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4285,7 +4148,6 @@ void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, u8 bitVal)
4285// Computed value // 4148// Computed value //
4286// // 4149// //
4287/////////////////////////////////////////////////////////////////////////////// 4150///////////////////////////////////////////////////////////////////////////////
4288// DONE
4289u32 MXL_Ceiling(u32 value, u32 resolution) 4151u32 MXL_Ceiling(u32 value, u32 resolution)
4290{ 4152{
4291 return (value/resolution + (value % resolution > 0 ? 1 : 0)); 4153 return (value/resolution + (value % resolution > 0 ? 1 : 0));
@@ -4294,7 +4156,6 @@ u32 MXL_Ceiling(u32 value, u32 resolution)
4294// 4156//
4295// Retrieve the Initialzation Registers 4157// Retrieve the Initialzation Registers
4296// 4158//
4297// DONE
4298u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4159u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4299{ 4160{
4300 u16 status = 0; 4161 u16 status = 0;
@@ -4317,7 +4178,6 @@ u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *c
4317 return status; 4178 return status;
4318} 4179}
4319 4180
4320// DONE
4321u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4181u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4322{ 4182{
4323 u16 status = 0; 4183 u16 status = 0;
@@ -4345,7 +4205,6 @@ u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *cou
4345 return status; 4205 return status;
4346} 4206}
4347 4207
4348// DONE
4349u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4208u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4350{ 4209{
4351 u16 status = 0; 4210 u16 status = 0;
@@ -4363,7 +4222,6 @@ u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, i
4363 return status; 4222 return status;
4364} 4223}
4365 4224
4366// DONE
4367u16 MXL_GetCHRegister_LowIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count) 4225u16 MXL_GetCHRegister_LowIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, int *count)
4368{ 4226{
4369 u16 status = 0; 4227 u16 status = 0;
@@ -4381,7 +4239,6 @@ u16 MXL_GetCHRegister_LowIF(struct dvb_frontend *fe, u8 * RegNum, u8 *RegVal, in
4381 return status; 4239 return status;
4382} 4240}
4383 4241
4384// DONE
4385u16 MXL_GetMasterControl(u8 *MasterReg, int state) 4242u16 MXL_GetMasterControl(u8 *MasterReg, int state)
4386{ 4243{
4387 if (state == 1) /* Load_Start */ 4244 if (state == 1) /* Load_Start */
@@ -4526,7 +4383,6 @@ u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
4526 return status; 4383 return status;
4527} 4384}
4528 4385
4529// DONE
4530u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis) 4386u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
4531{ 4387{
4532 struct mxl5005s_state *state = fe->tuner_priv; 4388 struct mxl5005s_state *state = fe->tuner_priv;
@@ -4537,141 +4393,224 @@ u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
4537 4393
4538 return status; 4394 return status;
4539} 4395}
4540
4541#endif 4396#endif
4397/* End: Reference driver code found in the Realtek driver that
4398 * is copyright MaxLinear */
4542 4399
4543/* Linux driver related functions */ 4400/* ----------------------------------------------------------------
4544 4401 * Begin: Everything after here is new code to adapt the
4545 4402 * proprietary Realtek driver into a Linux API tuner.
4546int mxl5005s_init(struct dvb_frontend *fe) 4403 * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
4404 */
4405static int mxl5005s_reset(struct dvb_frontend *fe)
4547{ 4406{
4548 int MxlModMode; 4407 struct mxl5005s_state *state = fe->tuner_priv;
4549 int MxlIfMode; 4408 int ret = 0;
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;
4562 4409
4563 /* Set MxL5005S parameters. */ 4410 u8 buf[2] = { 0xff, 0x00 };
4564 MxlModMode = MXL_DIGITAL_MODE; 4411 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
4565 MxlIfMode = MXL_ZERO_IF; 4412 .buf = buf, .len = 2 };
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;
4586 4413
4587 MXL5005_TunerConfig( 4414 dprintk(2, "%s()\n", __func__);
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}
4605 4415
4606static int mxl5005s_set_params(struct dvb_frontend *fe, 4416 if (fe->ops.i2c_gate_ctrl)
4607 struct dvb_frontend_parameters *params) 4417 fe->ops.i2c_gate_ctrl(fe, 1);
4608{
4609 u32 freq;
4610 u32 bw;
4611 4418
4612 if (fe->ops.info.type == FE_OFDM) 4419 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
4613 bw = params->u.ofdm.bandwidth; 4420 printk(KERN_WARNING "mxl5005s I2C reset failed\n");
4614 else 4421 ret = -EREMOTEIO;
4615 bw = MXL5005S_BANDWIDTH_6MHZ; 4422 }
4616 4423
4617 freq = params->frequency; /* Hz */ 4424 if (fe->ops.i2c_gate_ctrl)
4618 dprintk(1, "%s() freq=%d bw=%d\n", __func__, freq, bw); 4425 fe->ops.i2c_gate_ctrl(fe, 0);
4619 4426
4620 return mxl5005s_SetRfFreqHz(fe, freq); 4427 return ret;
4621} 4428}
4622 4429
4623static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency) 4430/* Write a single byte to a single reg, latch the value if required by
4431 * following the transaction with the latch byte.
4432 */
4433static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
4624{ 4434{
4625 struct mxl5005s_state *state = fe->tuner_priv; 4435 struct mxl5005s_state *state = fe->tuner_priv;
4626 dprintk(1, "%s()\n", __func__); 4436 u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE };
4437 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
4438 .buf = buf, .len = 3 };
4627 4439
4628 *frequency = state->RF_IN; 4440 if (latch == 0)
4441 msg.len = 2;
4629 4442
4443 dprintk(2, "%s(reg = 0x%x val = 0x%x addr = 0x%x)\n", __func__, reg, val, msg.addr);
4444
4445 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
4446 printk(KERN_WARNING "mxl5005s I2C write failed\n");
4447 return -EREMOTEIO;
4448 }
4630 return 0; 4449 return 0;
4631} 4450}
4632 4451
4633static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 4452int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, u8 *datatable, u8 len)
4634{ 4453{
4635 struct mxl5005s_state *state = fe->tuner_priv; 4454 int ret = 0, i;
4636 dprintk(1, "%s()\n", __func__);
4637 4455
4638 *bandwidth = state->Chan_Bandwidth; 4456 if (fe->ops.i2c_gate_ctrl)
4457 fe->ops.i2c_gate_ctrl(fe, 1);
4639 4458
4640 return 0; 4459 for (i = 0 ; i < len-1; i++) {
4460 ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
4461 if (ret < 0)
4462 break;
4463 }
4464
4465 ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
4466
4467 if (fe->ops.i2c_gate_ctrl)
4468 fe->ops.i2c_gate_ctrl(fe, 0);
4469
4470 return ret;
4641} 4471}
4642 4472
4643static int mxl5005s_get_status(struct dvb_frontend *fe, u32 *status) 4473
4474int mxl5005s_init(struct dvb_frontend *fe)
4644{ 4475{
4645 dprintk(1, "%s()\n", __func__); 4476 dprintk(1, "%s()\n", __func__);
4646 4477 return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
4647 *status = 0;
4648 // *status = TUNER_STATUS_LOCKED;
4649
4650 return 0;
4651} 4478}
4652 4479
4653static int mxl5005s_init2(struct dvb_frontend *fe) 4480int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth)
4654{ 4481{
4655 struct mxl5005s_state *state = fe->tuner_priv; 4482 struct mxl5005s_state *state = fe->tuner_priv;
4483
4656 u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 4484 u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
4657 u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX]; 4485 u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
4658 int TableLen; 4486 int TableLen;
4659 4487
4660 dprintk(1, "%s()\n", __func__); 4488 dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
4661 4489
4662 /* Initialize MxL5005S tuner according to MxL5005S tuner example code. */ 4490 mxl5005s_reset(fe);
4663 4491
4664 /* Tuner initialization stage 0 */ 4492 /* Tuner initialization stage 0 */
4665 MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET); 4493 MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
4666 AddrTable[0] = MASTER_CONTROL_ADDR; 4494 AddrTable[0] = MASTER_CONTROL_ADDR;
4667 ByteTable[0] |= state->config->AgcMasterByte; 4495 ByteTable[0] |= state->config->AgcMasterByte;
4668 4496
4669 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, 1); 4497 mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
4498
4499 mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
4670 4500
4671 /* Tuner initialization stage 1 */ 4501 /* Tuner initialization stage 1 */
4672 MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen); 4502 MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
4673 4503
4674 mxl5005s_SetRegsWithTable(fe, AddrTable, ByteTable, TableLen); 4504 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
4505
4506 return 0;
4507}
4508
4509int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type, u32 bandwidth)
4510{
4511 struct mxl5005s_state *state = fe->tuner_priv;
4512 struct mxl5005s_config *c = state->config;
4513
4514 InitTunerControls(fe);
4515
4516 /* Set MxL5005S parameters. */
4517 MXL5005_TunerConfig(
4518 fe,
4519 c->mod_mode,
4520 c->if_mode,
4521 bandwidth,
4522 c->if_freq,
4523 c->xtal_freq,
4524 c->agc_mode,
4525 c->top,
4526 c->output_load,
4527 c->clock_out,
4528 c->div_out,
4529 c->cap_select,
4530 c->rssi_enable,
4531 mod_type,
4532 c->tracking_filter);
4533
4534 return 0;
4535}
4536
4537static int mxl5005s_set_params(struct dvb_frontend *fe,
4538 struct dvb_frontend_parameters *params)
4539{
4540 struct mxl5005s_state *state = fe->tuner_priv;
4541 u32 req_mode, req_bw = 0;
4542 int ret;
4543
4544 dprintk(1, "%s()\n", __func__);
4545
4546 if (fe->ops.info.type == FE_ATSC) {
4547 switch (params->u.vsb.modulation) {
4548 case VSB_8:
4549 req_mode = MXL_ATSC; break;
4550 default:
4551 case QAM_64:
4552 case QAM_256:
4553 case QAM_AUTO:
4554 req_mode = MXL_QAM; break;
4555 }
4556 }
4557 else req_mode = MXL_DVBT;
4558
4559 /* Change tuner for new modulation type if reqd */
4560 if (req_mode != state->current_mode) {
4561 switch (req_mode) {
4562 case VSB_8:
4563 case QAM_64:
4564 case QAM_256:
4565 case QAM_AUTO:
4566 req_bw = MXL5005S_BANDWIDTH_6MHZ;
4567 break;
4568 default:
4569 /* Assume DVB-T */
4570 switch (params->u.ofdm.bandwidth) {
4571 case BANDWIDTH_6_MHZ:
4572 req_bw = MXL5005S_BANDWIDTH_6MHZ;
4573 break;
4574 case BANDWIDTH_7_MHZ:
4575 req_bw = MXL5005S_BANDWIDTH_7MHZ;
4576 break;
4577 case BANDWIDTH_AUTO:
4578 case BANDWIDTH_8_MHZ:
4579 req_bw = MXL5005S_BANDWIDTH_8MHZ;
4580 break;
4581 }
4582 }
4583
4584 state->current_mode = req_mode;
4585 ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
4586
4587 } else
4588 ret = 0;
4589
4590 if (ret == 0) {
4591 dprintk(1, "%s() freq=%d\n", __func__, params->frequency);
4592 ret = mxl5005s_SetRfFreqHz(fe, params->frequency);
4593 }
4594
4595 return ret;
4596}
4597
4598static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
4599{
4600 struct mxl5005s_state *state = fe->tuner_priv;
4601 dprintk(1, "%s()\n", __func__);
4602
4603 *frequency = state->RF_IN;
4604
4605 return 0;
4606}
4607
4608static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
4609{
4610 struct mxl5005s_state *state = fe->tuner_priv;
4611 dprintk(1, "%s()\n", __func__);
4612
4613 *bandwidth = state->Chan_Bandwidth;
4675 4614
4676 return 0; 4615 return 0;
4677} 4616}
@@ -4698,7 +4637,6 @@ static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
4698 .set_params = mxl5005s_set_params, 4637 .set_params = mxl5005s_set_params,
4699 .get_frequency = mxl5005s_get_frequency, 4638 .get_frequency = mxl5005s_get_frequency,
4700 .get_bandwidth = mxl5005s_get_bandwidth, 4639 .get_bandwidth = mxl5005s_get_bandwidth,
4701 .get_status = mxl5005s_get_status
4702}; 4640};
4703 4641
4704struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, 4642struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
@@ -4715,6 +4653,7 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
4715 state->frontend = fe; 4653 state->frontend = fe;
4716 state->config = config; 4654 state->config = config;
4717 state->i2c = i2c; 4655 state->i2c = i2c;
4656 state->current_mode = MXL_QAM;
4718 4657
4719 printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", config->i2c_address); 4658 printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", config->i2c_address);
4720 4659
@@ -4726,8 +4665,5 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
4726EXPORT_SYMBOL(mxl5005s_attach); 4665EXPORT_SYMBOL(mxl5005s_attach);
4727 4666
4728MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver"); 4667MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
4729MODULE_AUTHOR("Jan Hoogenraad");
4730MODULE_AUTHOR("Barnaby Shearer");
4731MODULE_AUTHOR("Andy Hasper");
4732MODULE_AUTHOR("Steven Toth"); 4668MODULE_AUTHOR("Steven Toth");
4733MODULE_LICENSE("GPL"); 4669MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 7d0727d44536..687cf146c2a0 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -1,63 +1,118 @@
1/* 1/*
2 * For the Realtek RTL chip RTL2831U 2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
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 */
24 3
4 Copyright (C) 2008 MaxLinear
5 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
6
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 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
25 22
26#ifndef __MXL5005S_H 23#ifndef __MXL5005S_H
27#define __MXL5005S_H 24#define __MXL5005S_H
28 25
29#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
30 27
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};
42
43/* Crystal frequency */
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};
51
52struct mxl5005s_config 28struct mxl5005s_config
53{ 29{
30 /* 7 bit i2c address */
54 u8 i2c_address; 31 u8 i2c_address;
55 32
33#define IF_FREQ_4570000HZ 4570000
34#define IF_FREQ_4571429HZ 4571429
35#define IF_FREQ_5380000HZ 5380000
36#define IF_FREQ_36000000HZ 36000000
37#define IF_FREQ_36125000HZ 36125000
38#define IF_FREQ_36166667HZ 36166667
39#define IF_FREQ_44000000HZ 44000000
40 u32 if_freq;
41
42#define CRYSTAL_FREQ_4000000HZ 4000000
43#define CRYSTAL_FREQ_16000000HZ 16000000
44#define CRYSTAL_FREQ_25000000HZ 25000000
45#define CRYSTAL_FREQ_28800000HZ 28800000
46 u32 xtal_freq;
47
48#define MXL_DUAL_AGC 0
49#define MXL_SINGLE_AGC 1
50 u8 agc_mode;
51
52#define MXL_TF_DEFAULT 0
53#define MXL_TF_OFF 1
54#define MXL_TF_C 2
55#define MXL_TF_C_H 3
56#define MXL_TF_D 4
57#define MXL_TF_D_L 5
58#define MXL_TF_E 6
59#define MXL_TF_F 7
60#define MXL_TF_E_2 8
61#define MXL_TF_E_NA 9
62#define MXL_TF_G 10
63 u8 tracking_filter;
64
65#define MXL_RSSI_DISABLE 0
66#define MXL_RSSI_ENABLE 1
67 u8 rssi_enable;
68
69#define MXL_CAP_SEL_DISABLE 0
70#define MXL_CAP_SEL_ENABLE 1
71 u8 cap_select;
72
73#define MXL_DIV_OUT_1 0
74#define MXL_DIV_OUT_4 1
75 u8 div_out;
76
77#define MXL_CLOCK_OUT_DISABLE 0
78#define MXL_CLOCK_OUT_ENABLE 1
79 u8 clock_out;
80
81#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
82#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
83 u32 output_load;
84
85#define MXL5005S_TOP_5P5 55
86#define MXL5005S_TOP_7P2 72
87#define MXL5005S_TOP_9P2 92
88#define MXL5005S_TOP_11P0 110
89#define MXL5005S_TOP_12P9 129
90#define MXL5005S_TOP_14P7 147
91#define MXL5005S_TOP_16P8 168
92#define MXL5005S_TOP_19P4 194
93#define MXL5005S_TOP_21P2 212
94#define MXL5005S_TOP_23P2 232
95#define MXL5005S_TOP_25P2 252
96#define MXL5005S_TOP_27P1 271
97#define MXL5005S_TOP_29P2 292
98#define MXL5005S_TOP_31P7 317
99#define MXL5005S_TOP_34P9 349
100 u32 top;
101
102#define MXL_ANALOG_MODE 0
103#define MXL_DIGITAL_MODE 1
104 u8 mod_mode;
105
106#define MXL_ZERO_IF 0
107#define MXL_LOW_IF 1
108 u8 if_mode;
109
56 /* Stuff I don't know what to do with */ 110 /* Stuff I don't know what to do with */
57 u8 AgcMasterByte; 111 u8 AgcMasterByte;
58}; 112};
59 113
60#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || (defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE)) 114#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \
115 (defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
61extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, 116extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
62 struct i2c_adapter *i2c, 117 struct i2c_adapter *i2c,
63 struct mxl5005s_config *config); 118 struct mxl5005s_config *config);