[media] drxd: provide ability to disable the i2c gate control function
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / dvb / frontends / drxd_hard.c
blobb8baafe3b54b0d10ebcd5bbdf217d53d5a46e5b9
1 /*
2 * drxd_hard.c: DVB-T Demodulator Micronas DRX3975D-A2,DRX397xD-B1
4 * Copyright (C) 2003-2007 Micronas
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/firmware.h>
30 #include <linux/i2c.h>
31 #include <linux/version.h>
32 #include <asm/div64.h>
34 #include "dvb_frontend.h"
35 #include "drxd.h"
36 #include "drxd_firm.h"
38 #define CHK_ERROR(s) if( (status = s)<0 ) break
39 #define CHUNK_SIZE 48
41 #define DRX_I2C_RMW 0x10
42 #define DRX_I2C_BROADCAST 0x20
43 #define DRX_I2C_CLEARCRC 0x80
44 #define DRX_I2C_SINGLE_MASTER 0xC0
45 #define DRX_I2C_MODEFLAGS 0xC0
46 #define DRX_I2C_FLAGS 0xF0
48 #ifndef SIZEOF_ARRAY
49 #define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
50 #endif
52 #define DEFAULT_LOCK_TIMEOUT 1100
54 #define DRX_CHANNEL_AUTO 0
55 #define DRX_CHANNEL_HIGH 1
56 #define DRX_CHANNEL_LOW 2
58 #define DRX_LOCK_MPEG 1
59 #define DRX_LOCK_FEC 2
60 #define DRX_LOCK_DEMOD 4
63 /****************************************************************************/
65 enum CSCDState {
66 CSCD_INIT = 0,
67 CSCD_SET,
68 CSCD_SAVED
71 enum CDrxdState {
72 DRXD_UNINITIALIZED = 0,
73 DRXD_STOPPED,
74 DRXD_STARTED
77 enum AGC_CTRL_MODE {
78 AGC_CTRL_AUTO = 0,
79 AGC_CTRL_USER,
80 AGC_CTRL_OFF
83 enum OperationMode {
84 OM_Default,
85 OM_DVBT_Diversity_Front,
86 OM_DVBT_Diversity_End
89 struct SCfgAgc {
90 enum AGC_CTRL_MODE ctrlMode;
91 u16 outputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
92 u16 settleLevel; /* range [0, ... , 1023], 1/n of fullscale range */
93 u16 minOutputLevel;/* range [0, ... , 1023], 1/n of fullscale range */
94 u16 maxOutputLevel;/* range [0, ... , 1023], 1/n of fullscale range */
95 u16 speed; /* range [0, ... , 1023], 1/n of fullscale range */
97 u16 R1;
98 u16 R2;
99 u16 R3;
102 struct SNoiseCal {
103 int cpOpt;
104 u16 cpNexpOfs;
105 u16 tdCal2k;
106 u16 tdCal8k;
109 enum app_env {
110 APPENV_STATIC = 0,
111 APPENV_PORTABLE = 1,
112 APPENV_MOBILE = 2
115 enum EIFFilter {
116 IFFILTER_SAW = 0,
117 IFFILTER_DISCRETE = 1
120 struct drxd_state {
121 struct dvb_frontend frontend;
122 struct dvb_frontend_ops ops;
123 struct dvb_frontend_parameters param;
125 const struct firmware *fw;
126 struct device *dev;
128 struct i2c_adapter *i2c;
129 void *priv;
130 struct drxd_config config;
132 int i2c_access;
133 int init_done;
134 struct semaphore mutex;
136 u8 chip_adr;
137 u16 hi_cfg_timing_div;
138 u16 hi_cfg_bridge_delay;
139 u16 hi_cfg_wakeup_key;
140 u16 hi_cfg_ctrl;
142 u16 intermediate_freq;
143 u16 osc_clock_freq;
145 enum CSCDState cscd_state;
146 enum CDrxdState drxd_state;
148 u16 sys_clock_freq;
149 s16 osc_clock_deviation;
150 u16 expected_sys_clock_freq;
152 u16 insert_rs_byte;
153 u16 enable_parallel;
155 int operation_mode;
157 struct SCfgAgc if_agc_cfg;
158 struct SCfgAgc rf_agc_cfg;
160 struct SNoiseCal noise_cal;
162 u32 fe_fs_add_incr;
163 u32 org_fe_fs_add_incr;
164 u16 current_fe_if_incr;
166 u16 m_FeAgRegAgPwd;
167 u16 m_FeAgRegAgAgcSio;
169 u16 m_EcOcRegOcModeLop;
170 u16 m_EcOcRegSncSncLvl;
171 u8 *m_InitAtomicRead;
172 u8 *m_HiI2cPatch;
174 u8 *m_ResetCEFR;
175 u8 *m_InitFE_1;
176 u8 *m_InitFE_2;
177 u8 *m_InitCP;
178 u8 *m_InitCE;
179 u8 *m_InitEQ;
180 u8 *m_InitSC;
181 u8 *m_InitEC;
182 u8 *m_ResetECRAM;
183 u8 *m_InitDiversityFront;
184 u8 *m_InitDiversityEnd;
185 u8 *m_DisableDiversity;
186 u8 *m_StartDiversityFront;
187 u8 *m_StartDiversityEnd;
189 u8 *m_DiversityDelay8MHZ;
190 u8 *m_DiversityDelay6MHZ;
192 u8 *microcode;
193 u32 microcode_length;
195 int type_A;
196 int PGA;
197 int diversity;
198 int tuner_mirrors;
200 enum app_env app_env_default;
201 enum app_env app_env_diversity;
206 /****************************************************************************/
207 /* I2C **********************************************************************/
208 /****************************************************************************/
210 static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
212 struct i2c_msg msg = { .addr=adr, .flags=0, .buf=data, .len=len };
214 if (i2c_transfer(adap, &msg, 1) != 1)
215 return -1;
216 return 0;
219 static int i2c_read(struct i2c_adapter *adap,
220 u8 adr, u8 *msg, int len, u8 *answ, int alen)
222 struct i2c_msg msgs[2] = { { .addr=adr, .flags=0,
223 .buf=msg, .len=len },
224 { .addr=adr, .flags=I2C_M_RD,
225 .buf=answ, .len=alen } };
226 if (i2c_transfer(adap, msgs, 2) != 2)
227 return -1;
228 return 0;
231 inline u32 MulDiv32(u32 a, u32 b, u32 c)
233 u64 tmp64;
235 tmp64=(u64)a*(u64)b;
236 do_div(tmp64, c);
238 return (u32) tmp64;
241 static int Read16(struct drxd_state *state, u32 reg, u16 *data, u8 flags)
243 u8 adr=state->config.demod_address;
244 u8 mm1[4]={reg&0xff, (reg>>16)&0xff,
245 flags|((reg>>24)&0xff), (reg>>8)&0xff};
246 u8 mm2[2];
247 if (i2c_read(state->i2c, adr, mm1, 4, mm2, 2)<0)
248 return -1;
249 if (data)
250 *data=mm2[0]|(mm2[1]<<8);
251 return mm2[0]|(mm2[1]<<8);
254 static int Read32(struct drxd_state *state, u32 reg, u32 *data, u8 flags)
256 u8 adr=state->config.demod_address;
257 u8 mm1[4]={reg&0xff, (reg>>16)&0xff,
258 flags|((reg>>24)&0xff), (reg>>8)&0xff};
259 u8 mm2[4];
261 if (i2c_read(state->i2c, adr, mm1, 4, mm2, 4)<0)
262 return -1;
263 if (data)
264 *data=mm2[0]|(mm2[1]<<8)|(mm2[2]<<16)|(mm2[3]<<24);
265 return 0;
268 static int Write16(struct drxd_state *state, u32 reg, u16 data, u8 flags)
270 u8 adr=state->config.demod_address;
271 u8 mm[6]={ reg&0xff, (reg>>16)&0xff,
272 flags|((reg>>24)&0xff), (reg>>8)&0xff,
273 data&0xff, (data>>8)&0xff };
275 if (i2c_write(state->i2c, adr, mm, 6)<0)
276 return -1;
277 return 0;
280 static int Write32(struct drxd_state *state, u32 reg, u32 data, u8 flags)
282 u8 adr=state->config.demod_address;
283 u8 mm[8]={ reg&0xff, (reg>>16)&0xff,
284 flags|((reg>>24)&0xff), (reg>>8)&0xff,
285 data&0xff, (data>>8)&0xff,
286 (data>>16)&0xff, (data>>24)&0xff };
288 if (i2c_write(state->i2c, adr, mm, 8)<0)
289 return -1;
290 return 0;
293 static int write_chunk(struct drxd_state *state,
294 u32 reg, u8 *data, u32 len, u8 flags)
296 u8 adr=state->config.demod_address;
297 u8 mm[CHUNK_SIZE+4]={ reg&0xff, (reg>>16)&0xff,
298 flags|((reg>>24)&0xff), (reg>>8)&0xff };
299 int i;
301 for (i=0; i<len; i++)
302 mm[4+i]=data[i];
303 if (i2c_write(state->i2c, adr, mm, 4+len)<0) {
304 printk("error in write_chunk\n");
305 return -1;
307 return 0;
310 static int WriteBlock(struct drxd_state *state,
311 u32 Address, u16 BlockSize, u8 *pBlock, u8 Flags)
313 while(BlockSize > 0) {
314 u16 Chunk = BlockSize > CHUNK_SIZE ? CHUNK_SIZE : BlockSize;
316 if (write_chunk(state, Address, pBlock, Chunk, Flags)<0)
317 return -1;
318 pBlock += Chunk;
319 Address += (Chunk >> 1);
320 BlockSize -= Chunk;
322 return 0;
325 static int WriteTable(struct drxd_state *state, u8 *pTable)
327 int status = 0;
329 if( pTable == NULL )
330 return 0;
332 while(!status) {
333 u16 Length;
334 u32 Address = pTable[0]|(pTable[1]<<8)|
335 (pTable[2]<<16)|(pTable[3]<<24);
337 if (Address==0xFFFFFFFF)
338 break;
339 pTable += sizeof(u32);
341 Length = pTable[0]|(pTable[1]<<8);
342 pTable += sizeof(u16);
343 if (!Length)
344 break;
345 status = WriteBlock(state, Address, Length*2, pTable, 0);
346 pTable += (Length*2);
348 return status;
352 /****************************************************************************/
353 /****************************************************************************/
354 /****************************************************************************/
356 static int ResetCEFR(struct drxd_state *state)
358 return WriteTable(state, state->m_ResetCEFR);
361 static int InitCP(struct drxd_state *state)
363 return WriteTable(state, state->m_InitCP);
366 static int InitCE(struct drxd_state *state)
368 int status;
369 enum app_env AppEnv = state->app_env_default;
371 do {
372 CHK_ERROR(WriteTable(state, state->m_InitCE));
374 if (state->operation_mode == OM_DVBT_Diversity_Front ||
375 state->operation_mode == OM_DVBT_Diversity_End ) {
376 AppEnv = state->app_env_diversity;
378 if ( AppEnv == APPENV_STATIC ) {
379 CHK_ERROR(Write16(state,CE_REG_TAPSET__A, 0x0000,0));
380 } else if( AppEnv == APPENV_PORTABLE ) {
381 CHK_ERROR(Write16(state,CE_REG_TAPSET__A, 0x0001,0));
382 } else if( AppEnv == APPENV_MOBILE && state->type_A ) {
383 CHK_ERROR(Write16(state,CE_REG_TAPSET__A, 0x0002,0));
384 } else if( AppEnv == APPENV_MOBILE && !state->type_A ) {
385 CHK_ERROR(Write16(state,CE_REG_TAPSET__A, 0x0006,0));
388 /* start ce */
389 CHK_ERROR(Write16(state,B_CE_REG_COMM_EXEC__A,0x0001,0));
390 } while(0);
391 return status;
394 static int StopOC(struct drxd_state *state)
396 int status = 0;
397 u16 ocSyncLvl = 0;
398 u16 ocModeLop = state->m_EcOcRegOcModeLop;
399 u16 dtoIncLop = 0;
400 u16 dtoIncHip = 0;
402 do {
403 /* Store output configuration */
404 CHK_ERROR(Read16(state, EC_OC_REG_SNC_ISC_LVL__A,
405 &ocSyncLvl, 0));;
406 /* CHK_ERROR(Read16(EC_OC_REG_OC_MODE_LOP__A,
407 &ocModeLop)); */
408 state->m_EcOcRegSncSncLvl = ocSyncLvl;
409 /* m_EcOcRegOcModeLop = ocModeLop; */
411 /* Flush FIFO (byte-boundary) at fixed rate */
412 CHK_ERROR(Read16(state, EC_OC_REG_RCN_MAP_LOP__A,
413 &dtoIncLop,0 ));
414 CHK_ERROR(Read16(state, EC_OC_REG_RCN_MAP_HIP__A,
415 &dtoIncHip,0 ));
416 CHK_ERROR(Write16(state, EC_OC_REG_DTO_INC_LOP__A,
417 dtoIncLop,0 ));
418 CHK_ERROR(Write16(state, EC_OC_REG_DTO_INC_HIP__A,
419 dtoIncHip,0 ));
420 ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M);
421 ocModeLop |= EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC;
422 CHK_ERROR(Write16(state, EC_OC_REG_OC_MODE_LOP__A,
423 ocModeLop,0 ));
424 CHK_ERROR(Write16(state, EC_OC_REG_COMM_EXEC__A,
425 EC_OC_REG_COMM_EXEC_CTL_HOLD,0 ));
427 msleep(1);
428 /* Output pins to '0' */
429 CHK_ERROR(Write16(state, EC_OC_REG_OCR_MPG_UOS__A,
430 EC_OC_REG_OCR_MPG_UOS__M,0 ));
432 /* Force the OC out of sync */
433 ocSyncLvl &= ~(EC_OC_REG_SNC_ISC_LVL_OSC__M);
434 CHK_ERROR(Write16(state, EC_OC_REG_SNC_ISC_LVL__A,
435 ocSyncLvl,0 ));
436 ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M);
437 ocModeLop |= EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE;
438 ocModeLop |= 0x2; /* Magically-out-of-sync */
439 CHK_ERROR(Write16(state, EC_OC_REG_OC_MODE_LOP__A,
440 ocModeLop,0 ));
441 CHK_ERROR(Write16(state, EC_OC_REG_COMM_INT_STA__A, 0x0,0 ));
442 CHK_ERROR(Write16(state, EC_OC_REG_COMM_EXEC__A,
443 EC_OC_REG_COMM_EXEC_CTL_ACTIVE,0 ));
444 } while(0);
446 return status;
449 static int StartOC(struct drxd_state *state)
451 int status=0;
453 do {
454 /* Stop OC */
455 CHK_ERROR(Write16(state, EC_OC_REG_COMM_EXEC__A,
456 EC_OC_REG_COMM_EXEC_CTL_HOLD,0 ));
458 /* Restore output configuration */
459 CHK_ERROR(Write16(state, EC_OC_REG_SNC_ISC_LVL__A,
460 state->m_EcOcRegSncSncLvl,0 ));
461 CHK_ERROR(Write16(state, EC_OC_REG_OC_MODE_LOP__A,
462 state->m_EcOcRegOcModeLop,0 ));
464 /* Output pins active again */
465 CHK_ERROR(Write16(state, EC_OC_REG_OCR_MPG_UOS__A,
466 EC_OC_REG_OCR_MPG_UOS_INIT,0 ));
468 /* Start OC */
469 CHK_ERROR(Write16(state, EC_OC_REG_COMM_EXEC__A,
470 EC_OC_REG_COMM_EXEC_CTL_ACTIVE,0 ));
471 } while(0);
472 return status;
475 static int InitEQ(struct drxd_state *state)
477 return WriteTable(state, state->m_InitEQ);
480 static int InitEC(struct drxd_state *state)
482 return WriteTable(state, state->m_InitEC);
485 static int InitSC(struct drxd_state *state)
487 return WriteTable(state, state->m_InitSC);
490 static int InitAtomicRead(struct drxd_state *state)
492 return WriteTable(state, state->m_InitAtomicRead);
495 static int CorrectSysClockDeviation(struct drxd_state *state);
497 static int DRX_GetLockStatus(struct drxd_state *state, u32 *pLockStatus)
499 u16 ScRaRamLock = 0;
500 const u16 mpeg_lock_mask = ( SC_RA_RAM_LOCK_MPEG__M |
501 SC_RA_RAM_LOCK_FEC__M |
502 SC_RA_RAM_LOCK_DEMOD__M );
503 const u16 fec_lock_mask = ( SC_RA_RAM_LOCK_FEC__M |
504 SC_RA_RAM_LOCK_DEMOD__M );
505 const u16 demod_lock_mask = SC_RA_RAM_LOCK_DEMOD__M ;
507 int status;
509 *pLockStatus=0;
511 status = Read16(state, SC_RA_RAM_LOCK__A, &ScRaRamLock, 0x0000 );
512 if(status<0) {
513 printk("Can't read SC_RA_RAM_LOCK__A status = %08x\n",
514 status);
515 return status;
518 if( state->drxd_state != DRXD_STARTED )
519 return 0;
521 if ( (ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask ) {
522 *pLockStatus|=DRX_LOCK_MPEG;
523 CorrectSysClockDeviation(state);
526 if ( (ScRaRamLock & fec_lock_mask) == fec_lock_mask )
527 *pLockStatus|=DRX_LOCK_FEC;
529 if ( (ScRaRamLock & demod_lock_mask) == demod_lock_mask )
530 *pLockStatus|=DRX_LOCK_DEMOD;
531 return 0;
534 /****************************************************************************/
536 static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
538 int status;
540 if( cfg->outputLevel > DRXD_FE_CTRL_MAX )
541 return -1;
543 if( cfg->ctrlMode == AGC_CTRL_USER ) {
544 do {
545 u16 FeAgRegPm1AgcWri;
546 u16 FeAgRegAgModeLop;
548 CHK_ERROR(Read16(state,FE_AG_REG_AG_MODE_LOP__A,
549 &FeAgRegAgModeLop,0));
550 FeAgRegAgModeLop &=
551 (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
552 FeAgRegAgModeLop |=
553 FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC;
554 CHK_ERROR(Write16(state,FE_AG_REG_AG_MODE_LOP__A,
555 FeAgRegAgModeLop,0));
557 FeAgRegPm1AgcWri = (u16)(cfg->outputLevel &
558 FE_AG_REG_PM1_AGC_WRI__M);
559 CHK_ERROR(Write16(state,FE_AG_REG_PM1_AGC_WRI__A,
560 FeAgRegPm1AgcWri,0));
562 while(0);
563 } else if( cfg->ctrlMode == AGC_CTRL_AUTO ) {
564 if ( ( (cfg->maxOutputLevel) < (cfg->minOutputLevel) ) ||
565 ( (cfg->maxOutputLevel) > DRXD_FE_CTRL_MAX ) ||
566 ( (cfg->speed) > DRXD_FE_CTRL_MAX ) ||
567 ( (cfg->settleLevel) > DRXD_FE_CTRL_MAX )
569 return (-1);
570 do {
571 u16 FeAgRegAgModeLop;
572 u16 FeAgRegEgcSetLvl;
573 u16 slope, offset;
575 /* == Mode == */
577 CHK_ERROR(Read16(state,FE_AG_REG_AG_MODE_LOP__A,
578 &FeAgRegAgModeLop,0));
579 FeAgRegAgModeLop &=
580 (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
581 FeAgRegAgModeLop |=
582 FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC;
583 CHK_ERROR(Write16(state,FE_AG_REG_AG_MODE_LOP__A,
584 FeAgRegAgModeLop,0));
586 /* == Settle level == */
588 FeAgRegEgcSetLvl = (u16)(( cfg->settleLevel >> 1 ) &
589 FE_AG_REG_EGC_SET_LVL__M );
590 CHK_ERROR(Write16(state,FE_AG_REG_EGC_SET_LVL__A,
591 FeAgRegEgcSetLvl,0));
593 /* == Min/Max == */
595 slope = (u16)(( cfg->maxOutputLevel -
596 cfg->minOutputLevel )/2);
597 offset = (u16)(( cfg->maxOutputLevel +
598 cfg->minOutputLevel )/2 - 511);
600 CHK_ERROR(Write16(state,FE_AG_REG_GC1_AGC_RIC__A,
601 slope,0));
602 CHK_ERROR(Write16(state,FE_AG_REG_GC1_AGC_OFF__A,
603 offset,0));
605 /* == Speed == */
607 const u16 maxRur = 8;
608 const u16 slowIncrDecLUT[]={ 3, 4, 4, 5, 6 };
609 const u16 fastIncrDecLUT[]={ 14, 15, 15, 16,
610 17, 18, 18, 19,
611 20, 21, 22, 23,
612 24, 26, 27, 28,
613 29, 31};
615 u16 fineSteps = (DRXD_FE_CTRL_MAX+1)/
616 (maxRur+1);
617 u16 fineSpeed = (u16)(cfg->speed -
618 ((cfg->speed/
619 fineSteps)*
620 fineSteps));
621 u16 invRurCount= (u16)(cfg->speed /
622 fineSteps);
623 u16 rurCount;
624 if ( invRurCount > maxRur )
626 rurCount = 0;
627 fineSpeed += fineSteps;
628 } else {
629 rurCount = maxRur - invRurCount;
633 fastInc = default *
634 (2^(fineSpeed/fineSteps))
635 => range[default...2*default>
636 slowInc = default *
637 (2^(fineSpeed/fineSteps))
640 u16 fastIncrDec =
641 fastIncrDecLUT[fineSpeed/
642 ((fineSteps/
643 (14+1))+1) ];
644 u16 slowIncrDec = slowIncrDecLUT[
645 fineSpeed/(fineSteps/(3+1)) ];
647 CHK_ERROR(Write16(state,
648 FE_AG_REG_EGC_RUR_CNT__A,
649 rurCount, 0));
650 CHK_ERROR(Write16(state,
651 FE_AG_REG_EGC_FAS_INC__A,
652 fastIncrDec, 0));
653 CHK_ERROR(Write16(state,
654 FE_AG_REG_EGC_FAS_DEC__A,
655 fastIncrDec, 0));
656 CHK_ERROR(Write16(state,
657 FE_AG_REG_EGC_SLO_INC__A,
658 slowIncrDec, 0));
659 CHK_ERROR(Write16(state,
660 FE_AG_REG_EGC_SLO_DEC__A,
661 slowIncrDec, 0));
664 } while(0);
666 } else {
667 /* No OFF mode for IF control */
668 return (-1);
670 return status;
674 static int SetCfgRfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
676 int status = 0;
678 if( cfg->outputLevel > DRXD_FE_CTRL_MAX )
679 return -1;
681 if( cfg->ctrlMode == AGC_CTRL_USER ) {
682 do {
683 u16 AgModeLop=0;
684 u16 level = ( cfg->outputLevel );
686 if (level == DRXD_FE_CTRL_MAX )
687 level++;
689 CHK_ERROR( Write16(state,FE_AG_REG_PM2_AGC_WRI__A,
690 level, 0x0000 ));
692 /*==== Mode ====*/
694 /* Powerdown PD2, WRI source */
695 state->m_FeAgRegAgPwd &=
696 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
697 state->m_FeAgRegAgPwd |=
698 FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
699 CHK_ERROR( Write16(state,FE_AG_REG_AG_PWD__A,
700 state->m_FeAgRegAgPwd,0x0000 ));
702 CHK_ERROR( Read16(state,FE_AG_REG_AG_MODE_LOP__A,
703 &AgModeLop,0x0000 ));
704 AgModeLop &= (~( FE_AG_REG_AG_MODE_LOP_MODE_5__M |
705 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
706 AgModeLop |= ( FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
707 FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC );
708 CHK_ERROR( Write16(state,FE_AG_REG_AG_MODE_LOP__A,
709 AgModeLop,0x0000 ));
712 /* enable AGC2 pin */
714 u16 FeAgRegAgAgcSio = 0;
715 CHK_ERROR( Read16(state,
716 FE_AG_REG_AG_AGC_SIO__A,
717 &FeAgRegAgAgcSio, 0x0000 ));
718 FeAgRegAgAgcSio &=
719 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
720 FeAgRegAgAgcSio |=
721 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
722 CHK_ERROR( Write16(state,
723 FE_AG_REG_AG_AGC_SIO__A,
724 FeAgRegAgAgcSio, 0x0000 ));
727 } while(0);
728 } else if( cfg->ctrlMode == AGC_CTRL_AUTO ) {
729 u16 AgModeLop=0;
731 do {
732 u16 level;
733 /* Automatic control */
734 /* Powerup PD2, AGC2 as output, TGC source */
735 (state->m_FeAgRegAgPwd) &=
736 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
737 (state->m_FeAgRegAgPwd) |=
738 FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
739 CHK_ERROR(Write16(state,FE_AG_REG_AG_PWD__A,
740 (state->m_FeAgRegAgPwd),0x0000 ));
742 CHK_ERROR(Read16(state,FE_AG_REG_AG_MODE_LOP__A,
743 &AgModeLop,0x0000 ));
744 AgModeLop &= (~( FE_AG_REG_AG_MODE_LOP_MODE_5__M |
745 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
746 AgModeLop |= ( FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
747 FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC );
748 CHK_ERROR(Write16(state,
749 FE_AG_REG_AG_MODE_LOP__A,
750 AgModeLop, 0x0000 ));
751 /* Settle level */
752 level = ( (( cfg->settleLevel )>>4) &
753 FE_AG_REG_TGC_SET_LVL__M );
754 CHK_ERROR(Write16(state,
755 FE_AG_REG_TGC_SET_LVL__A,
756 level,0x0000 ));
758 /* Min/max: don't care */
760 /* Speed: TODO */
762 /* enable AGC2 pin */
764 u16 FeAgRegAgAgcSio = 0;
765 CHK_ERROR( Read16(state,
766 FE_AG_REG_AG_AGC_SIO__A,
767 &FeAgRegAgAgcSio, 0x0000 ));
768 FeAgRegAgAgcSio &=
769 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
770 FeAgRegAgAgcSio |=
771 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
772 CHK_ERROR( Write16(state,
773 FE_AG_REG_AG_AGC_SIO__A,
774 FeAgRegAgAgcSio, 0x0000 ));
777 } while(0);
778 } else {
779 u16 AgModeLop=0;
781 do {
782 /* No RF AGC control */
783 /* Powerdown PD2, AGC2 as output, WRI source */
784 (state->m_FeAgRegAgPwd) &=
785 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
786 (state->m_FeAgRegAgPwd) |=
787 FE_AG_REG_AG_PWD_PWD_PD2_ENABLE;
788 CHK_ERROR(Write16(state,
789 FE_AG_REG_AG_PWD__A,
790 (state->m_FeAgRegAgPwd),0x0000 ));
792 CHK_ERROR(Read16(state,
793 FE_AG_REG_AG_MODE_LOP__A,
794 &AgModeLop,0x0000 ));
795 AgModeLop &= (~( FE_AG_REG_AG_MODE_LOP_MODE_5__M |
796 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
797 AgModeLop |= ( FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
798 FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC );
799 CHK_ERROR(Write16(state,
800 FE_AG_REG_AG_MODE_LOP__A,
801 AgModeLop,0x0000 ));
803 /* set FeAgRegAgAgcSio AGC2 (RF) as input */
805 u16 FeAgRegAgAgcSio = 0;
806 CHK_ERROR( Read16(state,
807 FE_AG_REG_AG_AGC_SIO__A,
808 &FeAgRegAgAgcSio, 0x0000 ));
809 FeAgRegAgAgcSio &=
810 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
811 FeAgRegAgAgcSio |=
812 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT;
813 CHK_ERROR( Write16(state,
814 FE_AG_REG_AG_AGC_SIO__A,
815 FeAgRegAgAgcSio, 0x0000 ));
817 } while(0);
819 return status;
822 static int ReadIFAgc(struct drxd_state *state, u32 *pValue)
824 int status = 0;
826 *pValue = 0;
827 if( state->if_agc_cfg.ctrlMode != AGC_CTRL_OFF ) {
828 u16 Value;
829 status = Read16(state, FE_AG_REG_GC1_AGC_DAT__A,&Value,0);
830 Value &= FE_AG_REG_GC1_AGC_DAT__M;
831 if(status>=0) {
832 /* 3.3V
836 Vin - R3 - * -- Vout
842 u32 R1 = state->if_agc_cfg.R1;
843 u32 R2 = state->if_agc_cfg.R2;
844 u32 R3 = state->if_agc_cfg.R3;
846 u32 Vmax = (3300 * R2) / ( R1 + R2 );
847 u32 Rpar = ( R2 * R3 ) / ( R3 + R2 );
848 u32 Vmin = (3300 * Rpar ) / ( R1 + Rpar );
849 u32 Vout = Vmin + (( Vmax - Vmin ) * Value) / 1024;
851 *pValue = Vout;
854 return status;
857 static int DownloadMicrocode(struct drxd_state *state,
858 const u8 *pMCImage, u32 Length)
860 u8 *pSrc;
861 u16 Flags;
862 u32 Address;
863 u16 nBlocks;
864 u16 BlockSize;
865 u16 BlockCRC;
866 u32 offset=0;
867 int i, status=0;
869 pSrc=(u8 *) pMCImage;
870 Flags = (pSrc[0] << 8) | pSrc[1];
871 pSrc += sizeof(u16); offset += sizeof(u16);
872 nBlocks = (pSrc[0] << 8) | pSrc[1];
873 pSrc += sizeof(u16); offset += sizeof(u16);
875 for(i=0; i<nBlocks; i++ ) {
876 Address=(pSrc[0] << 24) | (pSrc[1] << 16) |
877 (pSrc[2] << 8) | pSrc[3];
878 pSrc += sizeof(u32); offset += sizeof(u32);
880 BlockSize = ( (pSrc[0] << 8) | pSrc[1] ) * sizeof(u16);
881 pSrc += sizeof(u16); offset += sizeof(u16);
883 Flags = (pSrc[0] << 8) | pSrc[1];
884 pSrc += sizeof(u16); offset += sizeof(u16);
886 BlockCRC = (pSrc[0] << 8) | pSrc[1];
887 pSrc += sizeof(u16); offset += sizeof(u16);
889 status = WriteBlock(state,Address,BlockSize,
890 pSrc,DRX_I2C_CLEARCRC);
891 if (status<0)
892 break;
893 pSrc += BlockSize;
894 offset += BlockSize;
897 return status;
900 static int HI_Command(struct drxd_state *state, u16 cmd, u16 *pResult)
902 u32 nrRetries = 0;
903 u16 waitCmd;
904 int status;
906 if ((status=Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0))<0)
907 return status;
909 do {
910 nrRetries+=1;
911 if (nrRetries>DRXD_MAX_RETRIES) {
912 status=-1;
913 break;
915 status=Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
916 } while (waitCmd!=0);
918 if (status>=0)
919 status=Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
920 return status;
923 static int HI_CfgCommand(struct drxd_state *state)
925 int status=0;
927 down(&state->mutex);
928 Write16(state, HI_RA_RAM_SRV_CFG_KEY__A,
929 HI_RA_RAM_SRV_RST_KEY_ACT, 0);
930 Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, state->hi_cfg_timing_div, 0);
931 Write16(state, HI_RA_RAM_SRV_CFG_BDL__A,
932 state->hi_cfg_bridge_delay, 0);
933 Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, state->hi_cfg_wakeup_key, 0);
934 Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, state->hi_cfg_ctrl, 0);
936 Write16(state, HI_RA_RAM_SRV_CFG_KEY__A,
937 HI_RA_RAM_SRV_RST_KEY_ACT, 0);
939 if ((state->hi_cfg_ctrl & HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)==
940 HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)
941 status=Write16(state, HI_RA_RAM_SRV_CMD__A,
942 HI_RA_RAM_SRV_CMD_CONFIG, 0);
943 else
944 status=HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0);
945 up(&state->mutex);
946 return status;
949 static int InitHI(struct drxd_state *state)
951 state->hi_cfg_wakeup_key = (state->chip_adr);
952 /* port/bridge/power down ctrl */
953 state->hi_cfg_ctrl = HI_RA_RAM_SRV_CFG_ACT_SLV0_ON;
954 return HI_CfgCommand(state);
957 static int HI_ResetCommand(struct drxd_state *state)
959 int status;
961 down(&state->mutex);
962 status=Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
963 HI_RA_RAM_SRV_RST_KEY_ACT, 0);
964 if (status==0)
965 status=HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0);
966 up(&state->mutex);
967 msleep(1);
968 return status;
971 static int DRX_ConfigureI2CBridge(struct drxd_state *state,
972 int bEnableBridge)
974 state->hi_cfg_ctrl &= (~HI_RA_RAM_SRV_CFG_ACT_BRD__M);
975 if ( bEnableBridge )
976 state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_ON;
977 else
978 state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_OFF;
980 return HI_CfgCommand(state);
983 #define HI_TR_WRITE 0x9
984 #define HI_TR_READ 0xA
985 #define HI_TR_READ_WRITE 0xB
986 #define HI_TR_BROADCAST 0x4
988 #if 0
989 static int AtomicReadBlock(struct drxd_state *state,
990 u32 Addr, u16 DataSize, u8 *pData, u8 Flags)
992 int status;
993 int i=0;
995 /* Parameter check */
996 if ( (!pData) || ( (DataSize & 1)!=0 ) )
997 return -1;
999 down(&state->mutex);
1001 do {
1002 /* Instruct HI to read n bytes */
1003 /* TODO use proper names forthese egisters */
1004 CHK_ERROR( Write16(state,HI_RA_RAM_SRV_CFG_KEY__A,
1005 (HI_TR_FUNC_ADDR & 0xFFFF), 0));
1006 CHK_ERROR( Write16(state,HI_RA_RAM_SRV_CFG_DIV__A,
1007 (u16)(Addr >> 16), 0));
1008 CHK_ERROR( Write16(state,HI_RA_RAM_SRV_CFG_BDL__A,
1009 (u16)(Addr & 0xFFFF), 0));
1010 CHK_ERROR( Write16(state,HI_RA_RAM_SRV_CFG_WUP__A,
1011 (u16)((DataSize/2) - 1), 0));
1012 CHK_ERROR( Write16(state,HI_RA_RAM_SRV_CFG_ACT__A,
1013 HI_TR_READ, 0));
1015 CHK_ERROR( HI_Command(state, HI_RA_RAM_SRV_CMD_EXECUTE,0));
1017 } while(0);
1019 if (status>=0) {
1020 for (i = 0; i < (DataSize/2); i += 1) {
1021 u16 word;
1023 status = Read16(state, (HI_RA_RAM_USR_BEGIN__A + i),
1024 &word, 0);
1025 if( status<0)
1026 break;
1027 pData[2*i] = (u8) (word & 0xFF);
1028 pData[(2*i) + 1] = (u8) (word >> 8 );
1031 up(&state->mutex);
1032 return status;
1035 static int AtomicReadReg32(struct drxd_state *state,
1036 u32 Addr, u32 *pData, u8 Flags)
1038 u8 buf[sizeof (u32)];
1039 int status;
1041 if (!pData)
1042 return -1;
1043 status=AtomicReadBlock(state, Addr, sizeof (u32), buf, Flags);
1044 *pData = (((u32) buf[0]) << 0) +
1045 (((u32) buf[1]) << 8) +
1046 (((u32) buf[2]) << 16) +
1047 (((u32) buf[3]) << 24);
1048 return status;
1050 #endif
1052 static int StopAllProcessors(struct drxd_state *state)
1054 return Write16(state, HI_COMM_EXEC__A,
1055 SC_COMM_EXEC_CTL_STOP, DRX_I2C_BROADCAST);
1058 static int EnableAndResetMB(struct drxd_state *state)
1060 if (state->type_A) {
1061 /* disable? monitor bus observe @ EC_OC */
1062 Write16(state, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
1065 /* do inverse broadcast, followed by explicit write to HI */
1066 Write16(state, HI_COMM_MB__A, 0x0000, DRX_I2C_BROADCAST);
1067 Write16(state, HI_COMM_MB__A, 0x0000, 0x0000);
1068 return 0;
1071 static int InitCC(struct drxd_state *state)
1073 if (state->osc_clock_freq == 0 ||
1074 state->osc_clock_freq > 20000 ||
1075 (state->osc_clock_freq % 4000 ) != 0 ) {
1076 printk("invalid osc frequency %d\n", state->osc_clock_freq);
1077 return -1;
1080 Write16(state, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0);
1081 Write16(state, CC_REG_PLL_MODE__A, CC_REG_PLL_MODE_BYPASS_PLL |
1082 CC_REG_PLL_MODE_PUMP_CUR_12, 0);
1083 Write16(state, CC_REG_REF_DIVIDE__A, state->osc_clock_freq/4000, 0);
1084 Write16(state, CC_REG_PWD_MODE__A, CC_REG_PWD_MODE_DOWN_PLL, 0);
1085 Write16(state, CC_REG_UPDATE__A, CC_REG_UPDATE_KEY, 0);
1087 return 0;
1090 static int ResetECOD(struct drxd_state *state)
1092 int status = 0;
1094 if(state->type_A )
1095 status = Write16(state, EC_OD_REG_SYNC__A, 0x0664, 0);
1096 else
1097 status = Write16(state, B_EC_OD_REG_SYNC__A, 0x0664, 0);
1099 if (!(status<0))
1100 status = WriteTable(state, state->m_ResetECRAM);
1101 if (!(status<0))
1102 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0001, 0);
1103 return status;
1107 /* Configure PGA switch */
1109 static int SetCfgPga(struct drxd_state *state, int pgaSwitch)
1111 int status;
1112 u16 AgModeLop = 0;
1113 u16 AgModeHip = 0;
1114 do {
1115 if ( pgaSwitch ) {
1116 /* PGA on */
1117 /* fine gain */
1118 CHK_ERROR(Read16(state, B_FE_AG_REG_AG_MODE_LOP__A,
1119 &AgModeLop, 0x0000));
1120 AgModeLop&=(~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
1121 AgModeLop|= B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC;
1122 CHK_ERROR(Write16(state, B_FE_AG_REG_AG_MODE_LOP__A,
1123 AgModeLop, 0x0000));
1125 /* coarse gain */
1126 CHK_ERROR(Read16(state, B_FE_AG_REG_AG_MODE_HIP__A,
1127 &AgModeHip, 0x0000));
1128 AgModeHip&=(~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
1129 AgModeHip|= B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC ;
1130 CHK_ERROR(Write16(state, B_FE_AG_REG_AG_MODE_HIP__A,
1131 AgModeHip, 0x0000));
1133 /* enable fine and coarse gain, enable AAF,
1134 no ext resistor */
1135 CHK_ERROR(Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
1136 B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN,
1137 0x0000));
1138 } else {
1139 /* PGA off, bypass */
1141 /* fine gain */
1142 CHK_ERROR(Read16(state, B_FE_AG_REG_AG_MODE_LOP__A,
1143 &AgModeLop, 0x0000));
1144 AgModeLop&=(~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
1145 AgModeLop|= B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC ;
1146 CHK_ERROR(Write16(state, B_FE_AG_REG_AG_MODE_LOP__A,
1147 AgModeLop, 0x0000));
1149 /* coarse gain */
1150 CHK_ERROR(Read16(state, B_FE_AG_REG_AG_MODE_HIP__A,
1151 &AgModeHip, 0x0000));
1152 AgModeHip&=(~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
1153 AgModeHip|= B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC ;
1154 CHK_ERROR(Write16(state, B_FE_AG_REG_AG_MODE_HIP__A,
1155 AgModeHip, 0x0000));
1157 /* disable fine and coarse gain, enable AAF,
1158 no ext resistor */
1159 CHK_ERROR(Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
1160 B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
1161 0x0000));
1164 while(0);
1165 return status;
1168 static int InitFE(struct drxd_state *state)
1170 int status;
1174 CHK_ERROR( WriteTable(state, state->m_InitFE_1));
1176 if( state->type_A ) {
1177 status = Write16(state, FE_AG_REG_AG_PGA_MODE__A,
1178 FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0);
1179 } else {
1180 if (state->PGA)
1181 status = SetCfgPga(state, 0);
1182 else
1183 status =
1184 Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
1185 B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0);
1188 if (status<0) break;
1189 CHK_ERROR( Write16( state, FE_AG_REG_AG_AGC_SIO__A,
1190 state->m_FeAgRegAgAgcSio, 0x0000));
1191 CHK_ERROR( Write16( state, FE_AG_REG_AG_PWD__A,state->m_FeAgRegAgPwd,
1192 0x0000));
1194 CHK_ERROR( WriteTable(state, state->m_InitFE_2));
1197 } while(0);
1199 return status;
1202 static int InitFT(struct drxd_state *state)
1205 norm OFFSET, MB says =2 voor 8K en =3 voor 2K waarschijnlijk
1206 SC stuff
1208 return Write16(state, FT_REG_COMM_EXEC__A, 0x0001, 0x0000 );
1211 static int SC_WaitForReady(struct drxd_state *state)
1213 u16 curCmd;
1214 int i;
1216 for(i = 0; i < DRXD_MAX_RETRIES; i += 1 )
1218 int status = Read16(state, SC_RA_RAM_CMD__A,&curCmd,0);
1219 if (status==0 || curCmd == 0 )
1220 return status;
1222 return -1;
1225 static int SC_SendCommand(struct drxd_state *state, u16 cmd)
1227 int status=0;
1228 u16 errCode;
1230 Write16(state, SC_RA_RAM_CMD__A,cmd,0);
1231 SC_WaitForReady(state);
1233 Read16(state, SC_RA_RAM_CMD_ADDR__A,&errCode,0);
1235 if( errCode == 0xFFFF )
1237 printk("Command Error\n");
1238 status = -1;
1241 return status;
1244 static int SC_ProcStartCommand(struct drxd_state *state,
1245 u16 subCmd,u16 param0,u16 param1)
1247 int status=0;
1248 u16 scExec;
1250 down(&state->mutex);
1251 do {
1252 Read16(state, SC_COMM_EXEC__A, &scExec, 0);
1253 if (scExec != 1) {
1254 status=-1;
1255 break;
1257 SC_WaitForReady(state);
1258 Write16(state, SC_RA_RAM_CMD_ADDR__A,subCmd,0);
1259 Write16(state, SC_RA_RAM_PARAM1__A,param1,0);
1260 Write16(state, SC_RA_RAM_PARAM0__A,param0,0);
1262 SC_SendCommand(state, SC_RA_RAM_CMD_PROC_START);
1263 } while(0);
1264 up(&state->mutex);
1265 return status;
1269 static int SC_SetPrefParamCommand(struct drxd_state *state,
1270 u16 subCmd,u16 param0,u16 param1)
1272 int status;
1274 down(&state->mutex);
1275 do {
1276 CHK_ERROR( SC_WaitForReady(state) );
1277 CHK_ERROR( Write16(state,SC_RA_RAM_CMD_ADDR__A,subCmd,0) );
1278 CHK_ERROR( Write16(state,SC_RA_RAM_PARAM1__A,param1,0) );
1279 CHK_ERROR( Write16(state,SC_RA_RAM_PARAM0__A,param0,0) );
1281 CHK_ERROR( SC_SendCommand(state,
1282 SC_RA_RAM_CMD_SET_PREF_PARAM) );
1283 } while(0);
1284 up(&state->mutex);
1285 return status;
1288 #if 0
1289 static int SC_GetOpParamCommand(struct drxd_state *state, u16 *result)
1291 int status=0;
1293 down(&state->mutex);
1294 do {
1295 CHK_ERROR( SC_WaitForReady(state) );
1296 CHK_ERROR( SC_SendCommand(state,
1297 SC_RA_RAM_CMD_GET_OP_PARAM) );
1298 CHK_ERROR( Read16(state, SC_RA_RAM_PARAM0__A,result, 0 ) );
1299 } while(0);
1300 up(&state->mutex);
1301 return status;
1303 #endif
1305 static int ConfigureMPEGOutput(struct drxd_state *state, int bEnableOutput)
1307 int status;
1309 do {
1310 u16 EcOcRegIprInvMpg = 0;
1311 u16 EcOcRegOcModeLop = 0;
1312 u16 EcOcRegOcModeHip = 0;
1313 u16 EcOcRegOcMpgSio = 0;
1315 /*CHK_ERROR(Read16(state, EC_OC_REG_OC_MODE_LOP__A,
1316 &EcOcRegOcModeLop, 0));*/
1318 if( state->operation_mode == OM_DVBT_Diversity_Front )
1320 if ( bEnableOutput )
1322 EcOcRegOcModeHip |=
1323 B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR;
1325 else
1326 EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
1327 EcOcRegOcModeLop |=
1328 EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
1330 else
1332 EcOcRegOcModeLop = state->m_EcOcRegOcModeLop;
1334 if (bEnableOutput)
1335 EcOcRegOcMpgSio &=
1336 (~(EC_OC_REG_OC_MPG_SIO__M));
1337 else
1338 EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
1340 /* Don't Insert RS Byte */
1341 if( state->insert_rs_byte )
1343 EcOcRegOcModeLop &=
1344 (~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M));
1345 EcOcRegOcModeHip &=
1346 (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
1347 EcOcRegOcModeHip |=
1348 EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE;
1349 } else {
1350 EcOcRegOcModeLop |=
1351 EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
1352 EcOcRegOcModeHip &=
1353 (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
1354 EcOcRegOcModeHip |=
1355 EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE;
1358 /* Mode = Parallel */
1359 if( state->enable_parallel )
1360 EcOcRegOcModeLop &=
1361 (~(EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M));
1362 else
1363 EcOcRegOcModeLop |=
1364 EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL;
1366 /* Invert Data */
1367 /* EcOcRegIprInvMpg |= 0x00FF; */
1368 EcOcRegIprInvMpg &= (~(0x00FF));
1370 /* Invert Error ( we don't use the pin ) */
1371 /* EcOcRegIprInvMpg |= 0x0100; */
1372 EcOcRegIprInvMpg &= (~(0x0100));
1374 /* Invert Start ( we don't use the pin ) */
1375 /* EcOcRegIprInvMpg |= 0x0200; */
1376 EcOcRegIprInvMpg &= (~(0x0200));
1378 /* Invert Valid ( we don't use the pin ) */
1379 /* EcOcRegIprInvMpg |= 0x0400; */
1380 EcOcRegIprInvMpg &= (~(0x0400));
1382 /* Invert Clock */
1383 /* EcOcRegIprInvMpg |= 0x0800; */
1384 EcOcRegIprInvMpg &= (~(0x0800));
1386 /* EcOcRegOcModeLop =0x05; */
1387 CHK_ERROR( Write16(state, EC_OC_REG_IPR_INV_MPG__A,
1388 EcOcRegIprInvMpg, 0));
1389 CHK_ERROR( Write16(state, EC_OC_REG_OC_MODE_LOP__A,
1390 EcOcRegOcModeLop, 0) );
1391 CHK_ERROR( Write16(state, EC_OC_REG_OC_MODE_HIP__A,
1392 EcOcRegOcModeHip, 0x0000 ) );
1393 CHK_ERROR( Write16(state, EC_OC_REG_OC_MPG_SIO__A,
1394 EcOcRegOcMpgSio, 0) );
1395 } while(0);
1396 return status;
1399 static int SetDeviceTypeId(struct drxd_state *state)
1401 int status = 0;
1402 u16 deviceId = 0 ;
1404 do {
1405 CHK_ERROR(Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0));
1406 /* TODO: why twice? */
1407 CHK_ERROR(Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0));
1408 printk( "drxd: deviceId = %04x\n",deviceId);
1410 state->type_A = 0;
1411 state->PGA = 0;
1412 state->diversity = 0;
1413 if (deviceId == 0) { /* on A2 only 3975 available */
1414 state->type_A = 1;
1415 printk("DRX3975D-A2\n");
1416 } else {
1417 deviceId >>= 12;
1418 printk("DRX397%dD-B1\n",deviceId);
1419 switch(deviceId) {
1420 case 4:
1421 state->diversity = 1;
1422 case 3:
1423 case 7:
1424 state->PGA = 1;
1425 break;
1426 case 6:
1427 state->diversity = 1;
1428 case 5:
1429 case 8:
1430 break;
1431 default:
1432 status = -1;
1433 break;
1436 } while(0);
1438 if (status<0)
1439 return status;
1441 /* Init Table selection */
1442 state->m_InitAtomicRead = DRXD_InitAtomicRead;
1443 state->m_InitSC = DRXD_InitSC;
1444 state->m_ResetECRAM = DRXD_ResetECRAM;
1445 if (state->type_A) {
1446 state->m_ResetCEFR = DRXD_ResetCEFR;
1447 state->m_InitFE_1 = DRXD_InitFEA2_1;
1448 state->m_InitFE_2 = DRXD_InitFEA2_2;
1449 state->m_InitCP = DRXD_InitCPA2;
1450 state->m_InitCE = DRXD_InitCEA2;
1451 state->m_InitEQ = DRXD_InitEQA2;
1452 state->m_InitEC = DRXD_InitECA2;
1453 state->microcode = DRXD_A2_microcode;
1454 state->microcode_length = DRXD_A2_microcode_length;
1455 } else {
1456 state->m_ResetCEFR = NULL;
1457 state->m_InitFE_1 = DRXD_InitFEB1_1;
1458 state->m_InitFE_2 = DRXD_InitFEB1_2;
1459 state->m_InitCP = DRXD_InitCPB1;
1460 state->m_InitCE = DRXD_InitCEB1;
1461 state->m_InitEQ = DRXD_InitEQB1;
1462 state->m_InitEC = DRXD_InitECB1;
1463 state->microcode = DRXD_B1_microcode;
1464 state->microcode_length = DRXD_B1_microcode_length;
1466 if (state->diversity) {
1467 state->m_InitDiversityFront = DRXD_InitDiversityFront;
1468 state->m_InitDiversityEnd = DRXD_InitDiversityEnd;
1469 state->m_DisableDiversity = DRXD_DisableDiversity;
1470 state->m_StartDiversityFront = DRXD_StartDiversityFront;
1471 state->m_StartDiversityEnd = DRXD_StartDiversityEnd;
1472 state->m_DiversityDelay8MHZ = DRXD_DiversityDelay8MHZ;
1473 state->m_DiversityDelay6MHZ = DRXD_DiversityDelay6MHZ;
1474 } else {
1475 state->m_InitDiversityFront = NULL;
1476 state->m_InitDiversityEnd = NULL;
1477 state->m_DisableDiversity = NULL;
1478 state->m_StartDiversityFront = NULL;
1479 state->m_StartDiversityEnd = NULL;
1480 state->m_DiversityDelay8MHZ = NULL;
1481 state->m_DiversityDelay6MHZ = NULL;
1484 return status;
1487 static int CorrectSysClockDeviation(struct drxd_state *state)
1489 int status;
1490 s32 incr = 0;
1491 s32 nomincr = 0;
1492 u32 bandwidth=0;
1493 u32 sysClockInHz=0;
1494 u32 sysClockFreq=0; /* in kHz */
1495 s16 oscClockDeviation;
1496 s16 Diff;
1498 do {
1499 /* Retrieve bandwidth and incr, sanity check */
1501 /* These accesses should be AtomicReadReg32, but that
1502 causes trouble (at least for diversity */
1503 CHK_ERROR( Read32(state, LC_RA_RAM_IFINCR_NOM_L__A,
1504 ((u32 *)&nomincr),0 ));
1505 CHK_ERROR( Read32(state, FE_IF_REG_INCR0__A,
1506 (u32 *) &incr,0 ));
1508 if( state->type_A ) {
1509 if( (nomincr - incr < -500) ||
1510 (nomincr - incr > 500 ) )
1511 break;
1512 } else {
1513 if( (nomincr - incr < -2000 ) ||
1514 (nomincr - incr > 2000 ) )
1515 break;
1518 switch( state->param.u.ofdm.bandwidth )
1520 case BANDWIDTH_8_MHZ :
1521 bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
1522 break;
1523 case BANDWIDTH_7_MHZ :
1524 bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
1525 break;
1526 case BANDWIDTH_6_MHZ :
1527 bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
1528 break;
1529 default :
1530 return -1;
1531 break;
1534 /* Compute new sysclock value
1535 sysClockFreq = (((incr + 2^23)*bandwidth)/2^21)/1000 */
1536 incr += (1<<23);
1537 sysClockInHz = MulDiv32(incr,bandwidth,1<<21);
1538 sysClockFreq= (u32)(sysClockInHz/1000);
1539 /* rounding */
1540 if ( ( sysClockInHz%1000 ) > 500 )
1542 sysClockFreq++;
1545 /* Compute clock deviation in ppm */
1546 oscClockDeviation = (u16) (
1547 (((s32)(sysClockFreq) -
1548 (s32)(state->expected_sys_clock_freq))*
1549 1000000L)/(s32)(state->expected_sys_clock_freq) );
1551 Diff = oscClockDeviation - state->osc_clock_deviation;
1552 /*printk("sysclockdiff=%d\n", Diff);*/
1553 if( Diff >= -200 && Diff <= 200 ) {
1554 state->sys_clock_freq = (u16) sysClockFreq;
1555 if( oscClockDeviation !=
1556 state->osc_clock_deviation ) {
1557 if (state->config.osc_deviation) {
1558 state->config.osc_deviation(
1559 state->priv,
1560 oscClockDeviation, 1);
1561 state->osc_clock_deviation=
1562 oscClockDeviation;
1565 /* switch OFF SRMM scan in SC */
1566 CHK_ERROR( Write16( state,
1567 SC_RA_RAM_SAMPLE_RATE_COUNT__A,
1568 DRXD_OSCDEV_DONT_SCAN,0));
1569 /* overrule FE_IF internal value for
1570 proper re-locking */
1571 CHK_ERROR( Write16( state, SC_RA_RAM_IF_SAVE__AX,
1572 state->current_fe_if_incr, 0));
1573 state->cscd_state = CSCD_SAVED;
1575 } while(0);
1577 return (status);
1580 static int DRX_Stop(struct drxd_state *state)
1582 int status;
1584 if( state->drxd_state != DRXD_STARTED )
1585 return 0;
1587 do {
1588 if (state->cscd_state != CSCD_SAVED ) {
1589 u32 lock;
1590 CHK_ERROR( DRX_GetLockStatus(state, &lock));
1593 CHK_ERROR(StopOC(state));
1595 state->drxd_state = DRXD_STOPPED;
1597 CHK_ERROR( ConfigureMPEGOutput(state, 0) );
1599 if(state->type_A ) {
1600 /* Stop relevant processors off the device */
1601 CHK_ERROR( Write16(state, EC_OD_REG_COMM_EXEC__A,
1602 0x0000, 0x0000));
1604 CHK_ERROR( Write16(state, SC_COMM_EXEC__A,
1605 SC_COMM_EXEC_CTL_STOP, 0 ));
1606 CHK_ERROR( Write16(state, LC_COMM_EXEC__A,
1607 SC_COMM_EXEC_CTL_STOP, 0 ));
1608 } else {
1609 /* Stop all processors except HI & CC & FE */
1610 CHK_ERROR(Write16(state,
1611 B_SC_COMM_EXEC__A,
1612 SC_COMM_EXEC_CTL_STOP, 0 ));
1613 CHK_ERROR(Write16(state,
1614 B_LC_COMM_EXEC__A,
1615 SC_COMM_EXEC_CTL_STOP, 0 ));
1616 CHK_ERROR(Write16(state,
1617 B_FT_COMM_EXEC__A,
1618 SC_COMM_EXEC_CTL_STOP, 0 ));
1619 CHK_ERROR(Write16(state,
1620 B_CP_COMM_EXEC__A,
1621 SC_COMM_EXEC_CTL_STOP, 0 ));
1622 CHK_ERROR(Write16(state,
1623 B_CE_COMM_EXEC__A,
1624 SC_COMM_EXEC_CTL_STOP, 0 ));
1625 CHK_ERROR(Write16(state,
1626 B_EQ_COMM_EXEC__A,
1627 SC_COMM_EXEC_CTL_STOP, 0 ));
1628 CHK_ERROR(Write16(state,
1629 EC_OD_REG_COMM_EXEC__A,
1630 0x0000, 0 ));
1633 } while(0);
1634 return status;
1638 int SetOperationMode(struct drxd_state *state, int oMode)
1640 int status;
1642 do {
1643 if (state->drxd_state != DRXD_STOPPED) {
1644 status = -1;
1645 break;
1648 if (oMode == state->operation_mode) {
1649 status = 0;
1650 break;
1653 if (oMode != OM_Default && !state->diversity) {
1654 status = -1;
1655 break;
1658 switch(oMode)
1660 case OM_DVBT_Diversity_Front:
1661 status = WriteTable(state,
1662 state->m_InitDiversityFront);
1663 break;
1664 case OM_DVBT_Diversity_End:
1665 status = WriteTable(state,
1666 state->m_InitDiversityEnd);
1667 break;
1668 case OM_Default:
1669 /* We need to check how to
1670 get DRXD out of diversity */
1671 default:
1672 status = WriteTable(state, state->m_DisableDiversity);
1673 break;
1675 } while(0);
1677 if (!status)
1678 state->operation_mode = oMode;
1679 return status;
1684 static int StartDiversity(struct drxd_state *state)
1686 int status=0;
1687 u16 rcControl;
1689 do {
1690 if (state->operation_mode == OM_DVBT_Diversity_Front) {
1691 CHK_ERROR(WriteTable(state,
1692 state->m_StartDiversityFront));
1693 } else if( state->operation_mode == OM_DVBT_Diversity_End ) {
1694 CHK_ERROR(WriteTable(state,
1695 state->m_StartDiversityEnd));
1696 if( state->param.u.ofdm.bandwidth ==
1697 BANDWIDTH_8_MHZ ) {
1698 CHK_ERROR(
1699 WriteTable(state,
1700 state->
1701 m_DiversityDelay8MHZ));
1702 } else {
1703 CHK_ERROR(
1704 WriteTable(state,
1705 state->
1706 m_DiversityDelay6MHZ));
1709 CHK_ERROR(Read16(state,
1710 B_EQ_REG_RC_SEL_CAR__A,
1711 &rcControl,0));
1712 rcControl &= ~(B_EQ_REG_RC_SEL_CAR_FFTMODE__M);
1713 rcControl |= B_EQ_REG_RC_SEL_CAR_DIV_ON |
1714 /* combining enabled */
1715 B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
1716 B_EQ_REG_RC_SEL_CAR_PASS_A_CC |
1717 B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC;
1718 CHK_ERROR(Write16(state,
1719 B_EQ_REG_RC_SEL_CAR__A,
1720 rcControl,0));
1722 } while(0);
1723 return status;
1727 static int SetFrequencyShift(struct drxd_state *state,
1728 u32 offsetFreq, int channelMirrored)
1730 int negativeShift = (state->tuner_mirrors == channelMirrored);
1732 /* Handle all mirroring
1734 * Note: ADC mirroring (aliasing) is implictly handled by limiting
1735 * feFsRegAddInc to 28 bits below
1736 * (if the result before masking is more than 28 bits, this means
1737 * that the ADC is mirroring.
1738 * The masking is in fact the aliasing of the ADC)
1742 /* Compute register value, unsigned computation */
1743 state->fe_fs_add_incr = MulDiv32( state->intermediate_freq +
1744 offsetFreq,
1745 1<<28, state->sys_clock_freq);
1746 /* Remove integer part */
1747 state->fe_fs_add_incr &= 0x0FFFFFFFL;
1748 if (negativeShift)
1750 state->fe_fs_add_incr = ((1<<28) - state->fe_fs_add_incr);
1753 /* Save the frequency shift without tunerOffset compensation
1754 for CtrlGetChannel. */
1755 state->org_fe_fs_add_incr = MulDiv32( state->intermediate_freq,
1756 1<<28, state->sys_clock_freq);
1757 /* Remove integer part */
1758 state->org_fe_fs_add_incr &= 0x0FFFFFFFL;
1759 if (negativeShift)
1760 state->org_fe_fs_add_incr = ((1L<<28) -
1761 state->org_fe_fs_add_incr);
1763 return Write32(state, FE_FS_REG_ADD_INC_LOP__A,
1764 state->fe_fs_add_incr, 0);
1767 static int SetCfgNoiseCalibration (struct drxd_state *state,
1768 struct SNoiseCal* noiseCal )
1770 u16 beOptEna;
1771 int status=0;
1773 do {
1774 CHK_ERROR(Read16(state, SC_RA_RAM_BE_OPT_ENA__A,
1775 &beOptEna, 0));
1776 if (noiseCal->cpOpt)
1778 beOptEna |= (1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
1779 } else {
1780 beOptEna &= ~(1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
1781 CHK_ERROR(Write16(state, CP_REG_AC_NEXP_OFFS__A,
1782 noiseCal->cpNexpOfs, 0));
1784 CHK_ERROR(Write16(state, SC_RA_RAM_BE_OPT_ENA__A,
1785 beOptEna, 0));
1787 if( !state->type_A )
1789 CHK_ERROR(Write16( state,
1790 B_SC_RA_RAM_CO_TD_CAL_2K__A,
1791 noiseCal->tdCal2k,0));
1792 CHK_ERROR(Write16( state,
1793 B_SC_RA_RAM_CO_TD_CAL_8K__A,
1794 noiseCal->tdCal8k,0));
1796 } while(0);
1798 return status;
1801 static int DRX_Start(struct drxd_state *state, s32 off)
1803 struct dvb_ofdm_parameters *p = &state->param.u.ofdm;
1804 int status;
1806 u16 transmissionParams = 0;
1807 u16 operationMode = 0;
1808 u16 qpskTdTpsPwr = 0;
1809 u16 qam16TdTpsPwr = 0;
1810 u16 qam64TdTpsPwr = 0;
1811 u32 feIfIncr = 0;
1812 u32 bandwidth = 0;
1813 int mirrorFreqSpect;
1815 u16 qpskSnCeGain = 0;
1816 u16 qam16SnCeGain = 0;
1817 u16 qam64SnCeGain = 0;
1818 u16 qpskIsGainMan = 0;
1819 u16 qam16IsGainMan = 0;
1820 u16 qam64IsGainMan = 0;
1821 u16 qpskIsGainExp = 0;
1822 u16 qam16IsGainExp = 0;
1823 u16 qam64IsGainExp = 0;
1824 u16 bandwidthParam = 0;
1826 if (off<0)
1827 off=(off-500)/1000;
1828 else
1829 off=(off+500)/1000;
1831 do {
1832 if (state->drxd_state != DRXD_STOPPED)
1833 return -1;
1834 CHK_ERROR( ResetECOD(state) );
1835 if (state->type_A) {
1836 CHK_ERROR( InitSC(state) );
1837 } else {
1838 CHK_ERROR( InitFT(state) );
1839 CHK_ERROR( InitCP(state) );
1840 CHK_ERROR( InitCE(state) );
1841 CHK_ERROR( InitEQ(state) );
1842 CHK_ERROR( InitSC(state) );
1845 /* Restore current IF & RF AGC settings */
1847 CHK_ERROR(SetCfgIfAgc(state, &state->if_agc_cfg ));
1848 CHK_ERROR(SetCfgRfAgc(state, &state->rf_agc_cfg ));
1850 mirrorFreqSpect=( state->param.inversion==INVERSION_ON);
1852 switch (p->transmission_mode) {
1853 default: /* Not set, detect it automatically */
1854 operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
1855 /* fall through , try first guess DRX_FFTMODE_8K */
1856 case TRANSMISSION_MODE_8K :
1857 transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
1858 if (state->type_A) {
1859 CHK_ERROR( Write16(state,
1860 EC_SB_REG_TR_MODE__A,
1861 EC_SB_REG_TR_MODE_8K,
1862 0x0000 ));
1863 qpskSnCeGain = 99;
1864 qam16SnCeGain = 83;
1865 qam64SnCeGain = 67;
1867 break;
1868 case TRANSMISSION_MODE_2K :
1869 transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_2K;
1870 if (state->type_A) {
1871 CHK_ERROR( Write16(state,
1872 EC_SB_REG_TR_MODE__A,
1873 EC_SB_REG_TR_MODE_2K,
1874 0x0000 ));
1875 qpskSnCeGain = 97;
1876 qam16SnCeGain = 71;
1877 qam64SnCeGain = 65;
1879 break;
1882 switch( p->guard_interval )
1884 case GUARD_INTERVAL_1_4:
1885 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
1886 break;
1887 case GUARD_INTERVAL_1_8:
1888 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_8;
1889 break;
1890 case GUARD_INTERVAL_1_16:
1891 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_16;
1892 break;
1893 case GUARD_INTERVAL_1_32:
1894 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_32;
1895 break;
1896 default: /* Not set, detect it automatically */
1897 operationMode |= SC_RA_RAM_OP_AUTO_GUARD__M;
1898 /* try first guess 1/4 */
1899 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
1900 break;
1903 switch( p->hierarchy_information )
1905 case HIERARCHY_1:
1906 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1;
1907 if (state->type_A) {
1908 CHK_ERROR( Write16(state, EQ_REG_OT_ALPHA__A,
1909 0x0001, 0x0000 ) );
1910 CHK_ERROR( Write16(state, EC_SB_REG_ALPHA__A,
1911 0x0001, 0x0000 ) );
1913 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
1914 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA1;
1915 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA1;
1917 qpskIsGainMan =
1918 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
1919 qam16IsGainMan =
1920 SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
1921 qam64IsGainMan =
1922 SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
1924 qpskIsGainExp =
1925 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
1926 qam16IsGainExp =
1927 SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
1928 qam64IsGainExp =
1929 SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
1931 break;
1933 case HIERARCHY_2:
1934 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A2;
1935 if (state->type_A) {
1936 CHK_ERROR( Write16(state, EQ_REG_OT_ALPHA__A,
1937 0x0002, 0x0000 ) );
1938 CHK_ERROR( Write16(state, EC_SB_REG_ALPHA__A,
1939 0x0002, 0x0000 ) );
1941 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
1942 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA2;
1943 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA2;
1945 qpskIsGainMan =
1946 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
1947 qam16IsGainMan =
1948 SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE;
1949 qam64IsGainMan =
1950 SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE;
1952 qpskIsGainExp =
1953 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
1954 qam16IsGainExp =
1955 SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE;
1956 qam64IsGainExp =
1957 SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE;
1959 break;
1960 case HIERARCHY_4:
1961 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A4;
1962 if (state->type_A) {
1963 CHK_ERROR( Write16(state, EQ_REG_OT_ALPHA__A,
1964 0x0003, 0x0000 ));
1965 CHK_ERROR( Write16(state, EC_SB_REG_ALPHA__A,
1966 0x0003, 0x0000 ) );
1968 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
1969 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA4;
1970 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA4;
1972 qpskIsGainMan =
1973 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
1974 qam16IsGainMan =
1975 SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE;
1976 qam64IsGainMan =
1977 SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE;
1979 qpskIsGainExp =
1980 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
1981 qam16IsGainExp =
1982 SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE;
1983 qam64IsGainExp =
1984 SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE;
1986 break;
1987 case HIERARCHY_AUTO:
1988 default:
1989 /* Not set, detect it automatically, start with none */
1990 operationMode |= SC_RA_RAM_OP_AUTO_HIER__M;
1991 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_NO;
1992 if (state->type_A) {
1993 CHK_ERROR( Write16(state, EQ_REG_OT_ALPHA__A,
1994 0x0000, 0x0000 ) );
1995 CHK_ERROR( Write16(state, EC_SB_REG_ALPHA__A,
1996 0x0000, 0x0000 ) );
1998 qpskTdTpsPwr = EQ_TD_TPS_PWR_QPSK;
1999 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHAN;
2000 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHAN;
2002 qpskIsGainMan =
2003 SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE;
2004 qam16IsGainMan =
2005 SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
2006 qam64IsGainMan =
2007 SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
2009 qpskIsGainExp =
2010 SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE;
2011 qam16IsGainExp =
2012 SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
2013 qam64IsGainExp =
2014 SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
2016 break;
2018 CHK_ERROR( status );
2020 switch( p->constellation ) {
2021 default:
2022 operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
2023 /* fall through , try first guess
2024 DRX_CONSTELLATION_QAM64 */
2025 case QAM_64:
2026 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
2027 if (state->type_A) {
2028 CHK_ERROR(Write16(state, EQ_REG_OT_CONST__A,
2029 0x0002, 0x0000 ) );
2030 CHK_ERROR(Write16(state, EC_SB_REG_CONST__A,
2031 EC_SB_REG_CONST_64QAM,
2032 0x0000) );
2033 CHK_ERROR(Write16(state,
2034 EC_SB_REG_SCALE_MSB__A,
2035 0x0020, 0x0000 ) );
2036 CHK_ERROR(Write16(state,
2037 EC_SB_REG_SCALE_BIT2__A,
2038 0x0008, 0x0000 ) );
2039 CHK_ERROR(Write16(state,
2040 EC_SB_REG_SCALE_LSB__A,
2041 0x0002, 0x0000 ) );
2043 CHK_ERROR(Write16(state,
2044 EQ_REG_TD_TPS_PWR_OFS__A,
2045 qam64TdTpsPwr, 0x0000 ) );
2046 CHK_ERROR( Write16(state,EQ_REG_SN_CEGAIN__A,
2047 qam64SnCeGain, 0x0000 ));
2048 CHK_ERROR( Write16(state,EQ_REG_IS_GAIN_MAN__A,
2049 qam64IsGainMan, 0x0000 ));
2050 CHK_ERROR( Write16(state,EQ_REG_IS_GAIN_EXP__A,
2051 qam64IsGainExp, 0x0000 ));
2053 break;
2054 case QPSK :
2055 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QPSK;
2056 if (state->type_A) {
2057 CHK_ERROR(Write16(state, EQ_REG_OT_CONST__A,
2058 0x0000, 0x0000 ) );
2059 CHK_ERROR(Write16(state, EC_SB_REG_CONST__A,
2060 EC_SB_REG_CONST_QPSK,
2061 0x0000) );
2062 CHK_ERROR(Write16(state,
2063 EC_SB_REG_SCALE_MSB__A,
2064 0x0010, 0x0000 ) );
2065 CHK_ERROR(Write16(state,
2066 EC_SB_REG_SCALE_BIT2__A,
2067 0x0000, 0x0000 ) );
2068 CHK_ERROR(Write16(state,
2069 EC_SB_REG_SCALE_LSB__A,
2070 0x0000, 0x0000 ) );
2072 CHK_ERROR(Write16(state,
2073 EQ_REG_TD_TPS_PWR_OFS__A,
2074 qpskTdTpsPwr, 0x0000 ) );
2075 CHK_ERROR( Write16(state, EQ_REG_SN_CEGAIN__A,
2076 qpskSnCeGain, 0x0000 ));
2077 CHK_ERROR( Write16(state,
2078 EQ_REG_IS_GAIN_MAN__A,
2079 qpskIsGainMan, 0x0000 ));
2080 CHK_ERROR( Write16(state,
2081 EQ_REG_IS_GAIN_EXP__A,
2082 qpskIsGainExp, 0x0000 ));
2084 break;
2086 case QAM_16:
2087 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM16;
2088 if (state->type_A) {
2089 CHK_ERROR(Write16(state, EQ_REG_OT_CONST__A,
2090 0x0001, 0x0000 ) );
2091 CHK_ERROR(Write16(state, EC_SB_REG_CONST__A,
2092 EC_SB_REG_CONST_16QAM,
2093 0x0000) );
2094 CHK_ERROR(Write16(state,
2095 EC_SB_REG_SCALE_MSB__A,
2096 0x0010, 0x0000 ) );
2097 CHK_ERROR(Write16(state,
2098 EC_SB_REG_SCALE_BIT2__A,
2099 0x0004, 0x0000 ) );
2100 CHK_ERROR(Write16(state,
2101 EC_SB_REG_SCALE_LSB__A,
2102 0x0000, 0x0000 ) );
2104 CHK_ERROR(Write16(state,
2105 EQ_REG_TD_TPS_PWR_OFS__A,
2106 qam16TdTpsPwr, 0x0000 ) );
2107 CHK_ERROR( Write16(state, EQ_REG_SN_CEGAIN__A,
2108 qam16SnCeGain, 0x0000 ));
2109 CHK_ERROR( Write16(state,
2110 EQ_REG_IS_GAIN_MAN__A,
2111 qam16IsGainMan, 0x0000 ));
2112 CHK_ERROR( Write16(state,
2113 EQ_REG_IS_GAIN_EXP__A,
2114 qam16IsGainExp, 0x0000 ));
2116 break;
2119 CHK_ERROR( status );
2121 switch (DRX_CHANNEL_HIGH) {
2122 default:
2123 case DRX_CHANNEL_AUTO:
2124 case DRX_CHANNEL_LOW:
2125 transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO;
2126 CHK_ERROR( Write16(state, EC_SB_REG_PRIOR__A,
2127 EC_SB_REG_PRIOR_LO, 0x0000 ));
2128 break;
2129 case DRX_CHANNEL_HIGH:
2130 transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI;
2131 CHK_ERROR( Write16(state, EC_SB_REG_PRIOR__A,
2132 EC_SB_REG_PRIOR_HI, 0x0000 ));
2133 break;
2137 switch( p->code_rate_HP )
2139 case FEC_1_2:
2140 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2;
2141 if (state->type_A) {
2142 CHK_ERROR( Write16(state,
2143 EC_VD_REG_SET_CODERATE__A,
2144 EC_VD_REG_SET_CODERATE_C1_2,
2145 0x0000 ) );
2147 break;
2148 default:
2149 operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
2150 case FEC_2_3 :
2151 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
2152 if (state->type_A) {
2153 CHK_ERROR( Write16(state,
2154 EC_VD_REG_SET_CODERATE__A,
2155 EC_VD_REG_SET_CODERATE_C2_3,
2156 0x0000 ) );
2158 break;
2159 case FEC_3_4 :
2160 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4;
2161 if (state->type_A) {
2162 CHK_ERROR( Write16(state,
2163 EC_VD_REG_SET_CODERATE__A,
2164 EC_VD_REG_SET_CODERATE_C3_4,
2165 0x0000 ) );
2167 break;
2168 case FEC_5_6 :
2169 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6;
2170 if (state->type_A) {
2171 CHK_ERROR( Write16(state,
2172 EC_VD_REG_SET_CODERATE__A,
2173 EC_VD_REG_SET_CODERATE_C5_6,
2174 0x0000 ) );
2176 break;
2177 case FEC_7_8 :
2178 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8;
2179 if (state->type_A) {
2180 CHK_ERROR( Write16(state,
2181 EC_VD_REG_SET_CODERATE__A,
2182 EC_VD_REG_SET_CODERATE_C7_8,
2183 0x0000 ) );
2185 break;
2187 CHK_ERROR( status );
2189 /* First determine real bandwidth (Hz) */
2190 /* Also set delay for impulse noise cruncher (only A2) */
2191 /* Also set parameters for EC_OC fix, note
2192 EC_OC_REG_TMD_HIL_MAR is changed
2193 by SC for fix for some 8K,1/8 guard but is restored by
2194 InitEC and ResetEC
2195 functions */
2196 switch( p->bandwidth )
2198 case BANDWIDTH_AUTO:
2199 case BANDWIDTH_8_MHZ:
2200 /* (64/7)*(8/8)*1000000 */
2201 bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
2203 bandwidthParam = 0;
2204 status = Write16(state,
2205 FE_AG_REG_IND_DEL__A , 50 , 0x0000 );
2206 break;
2207 case BANDWIDTH_7_MHZ:
2208 /* (64/7)*(7/8)*1000000 */
2209 bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
2210 bandwidthParam =0x4807; /*binary:0100 1000 0000 0111 */
2211 status = Write16(state,
2212 FE_AG_REG_IND_DEL__A , 59 , 0x0000 );
2213 break;
2214 case BANDWIDTH_6_MHZ:
2215 /* (64/7)*(6/8)*1000000 */
2216 bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
2217 bandwidthParam =0x0F07; /*binary: 0000 1111 0000 0111*/
2218 status = Write16(state,
2219 FE_AG_REG_IND_DEL__A , 71 , 0x0000 );
2220 break;
2222 CHK_ERROR( status );
2224 CHK_ERROR( Write16(state,
2225 SC_RA_RAM_BAND__A, bandwidthParam, 0x0000));
2228 u16 sc_config;
2229 CHK_ERROR(Read16(state,
2230 SC_RA_RAM_CONFIG__A, &sc_config, 0));
2232 /* enable SLAVE mode in 2k 1/32 to
2233 prevent timing change glitches */
2234 if ( (p->transmission_mode==TRANSMISSION_MODE_2K) &&
2235 (p->guard_interval==GUARD_INTERVAL_1_32) ) {
2236 /* enable slave */
2237 sc_config |= SC_RA_RAM_CONFIG_SLAVE__M;
2238 } else {
2239 /* disable slave */
2240 sc_config &= ~SC_RA_RAM_CONFIG_SLAVE__M;
2242 CHK_ERROR( Write16(state,
2243 SC_RA_RAM_CONFIG__A, sc_config,0 ));
2246 CHK_ERROR( SetCfgNoiseCalibration(state, &state->noise_cal));
2248 if (state->cscd_state == CSCD_INIT )
2250 /* switch on SRMM scan in SC */
2251 CHK_ERROR( Write16(state,
2252 SC_RA_RAM_SAMPLE_RATE_COUNT__A,
2253 DRXD_OSCDEV_DO_SCAN, 0x0000 ));
2254 /* CHK_ERROR( Write16( SC_RA_RAM_SAMPLE_RATE_STEP__A,
2255 DRXD_OSCDEV_STEP , 0x0000 ));*/
2256 state->cscd_state = CSCD_SET;
2260 /* Now compute FE_IF_REG_INCR */
2261 /*((( SysFreq/BandWidth)/2)/2) -1) * 2^23) =>
2262 ((SysFreq / BandWidth) * (2^21) ) - (2^23)*/
2263 feIfIncr = MulDiv32(state->sys_clock_freq*1000,
2264 ( 1ULL<< 21 ), bandwidth) - (1<<23) ;
2265 CHK_ERROR( Write16(state,
2266 FE_IF_REG_INCR0__A,
2267 (u16)(feIfIncr & FE_IF_REG_INCR0__M ),
2268 0x0000) );
2269 CHK_ERROR( Write16(state,
2270 FE_IF_REG_INCR1__A,
2271 (u16)((feIfIncr >> FE_IF_REG_INCR0__W) &
2272 FE_IF_REG_INCR1__M ), 0x0000) );
2273 /* Bandwidth setting done */
2275 /* Mirror & frequency offset */
2276 SetFrequencyShift(state, off, mirrorFreqSpect);
2278 /* Start SC, write channel settings to SC */
2280 /* Enable SC after setting all other parameters */
2281 CHK_ERROR( Write16(state, SC_COMM_STATE__A, 0, 0x0000));
2282 CHK_ERROR( Write16(state, SC_COMM_EXEC__A, 1, 0x0000));
2284 /* Write SC parameter registers, operation mode */
2285 #if 1
2286 operationMode =( SC_RA_RAM_OP_AUTO_MODE__M |
2287 SC_RA_RAM_OP_AUTO_GUARD__M |
2288 SC_RA_RAM_OP_AUTO_CONST__M |
2289 SC_RA_RAM_OP_AUTO_HIER__M |
2290 SC_RA_RAM_OP_AUTO_RATE__M );
2291 #endif
2292 CHK_ERROR( SC_SetPrefParamCommand(state, 0x0000,
2293 transmissionParams,
2294 operationMode) );
2296 /* Start correct processes to get in lock */
2297 CHK_ERROR( SC_ProcStartCommand(state, SC_RA_RAM_PROC_LOCKTRACK,
2298 SC_RA_RAM_SW_EVENT_RUN_NMASK__M,
2299 SC_RA_RAM_LOCKTRACK_MIN) );
2301 CHK_ERROR( StartOC(state) );
2303 if( state->operation_mode != OM_Default ) {
2304 CHK_ERROR(StartDiversity(state));
2307 state->drxd_state = DRXD_STARTED;
2308 } while(0);
2310 return status;
2313 static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
2315 u32 ulRfAgcOutputLevel = 0xffffffff;
2316 u32 ulRfAgcSettleLevel = 528; /* Optimum value for MT2060 */
2317 u32 ulRfAgcMinLevel = 0; /* Currently unused */
2318 u32 ulRfAgcMaxLevel = DRXD_FE_CTRL_MAX; /* Currently unused */
2319 u32 ulRfAgcSpeed = 0; /* Currently unused */
2320 u32 ulRfAgcMode = 0;/*2; Off */
2321 u32 ulRfAgcR1 = 820;
2322 u32 ulRfAgcR2 = 2200;
2323 u32 ulRfAgcR3 = 150;
2324 u32 ulIfAgcMode = 0; /* Auto */
2325 u32 ulIfAgcOutputLevel = 0xffffffff;
2326 u32 ulIfAgcSettleLevel = 0xffffffff;
2327 u32 ulIfAgcMinLevel = 0xffffffff;
2328 u32 ulIfAgcMaxLevel = 0xffffffff;
2329 u32 ulIfAgcSpeed = 0xffffffff;
2330 u32 ulIfAgcR1 = 820;
2331 u32 ulIfAgcR2 = 2200;
2332 u32 ulIfAgcR3 = 150;
2333 u32 ulClock = state->config.clock;
2334 u32 ulSerialMode = 0;
2335 u32 ulEcOcRegOcModeLop = 4; /* Dynamic DTO source */
2336 u32 ulHiI2cDelay = HI_I2C_DELAY;
2337 u32 ulHiI2cBridgeDelay = HI_I2C_BRIDGE_DELAY;
2338 u32 ulHiI2cPatch = 0;
2339 u32 ulEnvironment = APPENV_PORTABLE;
2340 u32 ulEnvironmentDiversity = APPENV_MOBILE;
2341 u32 ulIFFilter = IFFILTER_SAW;
2343 state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2344 state->if_agc_cfg.outputLevel = 0;
2345 state->if_agc_cfg.settleLevel = 140;
2346 state->if_agc_cfg.minOutputLevel = 0;
2347 state->if_agc_cfg.maxOutputLevel = 1023;
2348 state->if_agc_cfg.speed = 904;
2350 if( ulIfAgcMode == 1 && ulIfAgcOutputLevel <= DRXD_FE_CTRL_MAX )
2352 state->if_agc_cfg.ctrlMode = AGC_CTRL_USER;
2353 state->if_agc_cfg.outputLevel = (u16)(ulIfAgcOutputLevel);
2356 if( ulIfAgcMode == 0 &&
2357 ulIfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
2358 ulIfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
2359 ulIfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
2360 ulIfAgcSpeed <= DRXD_FE_CTRL_MAX
2363 state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2364 state->if_agc_cfg.settleLevel = (u16)(ulIfAgcSettleLevel);
2365 state->if_agc_cfg.minOutputLevel = (u16)(ulIfAgcMinLevel);
2366 state->if_agc_cfg.maxOutputLevel = (u16)(ulIfAgcMaxLevel);
2367 state->if_agc_cfg.speed = (u16)(ulIfAgcSpeed);
2370 state->if_agc_cfg.R1 = (u16)(ulIfAgcR1);
2371 state->if_agc_cfg.R2 = (u16)(ulIfAgcR2);
2372 state->if_agc_cfg.R3 = (u16)(ulIfAgcR3);
2374 state->rf_agc_cfg.R1 = (u16)(ulRfAgcR1);
2375 state->rf_agc_cfg.R2 = (u16)(ulRfAgcR2);
2376 state->rf_agc_cfg.R3 = (u16)(ulRfAgcR3);
2378 state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2379 /* rest of the RFAgcCfg structure currently unused */
2380 if (ulRfAgcMode==1 && ulRfAgcOutputLevel<=DRXD_FE_CTRL_MAX) {
2381 state->rf_agc_cfg.ctrlMode = AGC_CTRL_USER;
2382 state->rf_agc_cfg.outputLevel = (u16)(ulRfAgcOutputLevel);
2385 if( ulRfAgcMode == 0 &&
2386 ulRfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
2387 ulRfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
2388 ulRfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
2389 ulRfAgcSpeed <= DRXD_FE_CTRL_MAX
2392 state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2393 state->rf_agc_cfg.settleLevel = (u16)(ulRfAgcSettleLevel);
2394 state->rf_agc_cfg.minOutputLevel = (u16)(ulRfAgcMinLevel);
2395 state->rf_agc_cfg.maxOutputLevel = (u16)(ulRfAgcMaxLevel);
2396 state->rf_agc_cfg.speed = (u16)(ulRfAgcSpeed);
2399 if( ulRfAgcMode == 2 )
2401 state->rf_agc_cfg.ctrlMode = AGC_CTRL_OFF;
2404 if (ulEnvironment <= 2)
2405 state->app_env_default = (enum app_env)
2406 (ulEnvironment);
2407 if (ulEnvironmentDiversity <= 2)
2408 state->app_env_diversity = (enum app_env)
2409 (ulEnvironmentDiversity);
2411 if( ulIFFilter == IFFILTER_DISCRETE )
2413 /* discrete filter */
2414 state->noise_cal.cpOpt = 0;
2415 state->noise_cal.cpNexpOfs = 40;
2416 state->noise_cal.tdCal2k = -40;
2417 state->noise_cal.tdCal8k = -24;
2418 } else {
2419 /* SAW filter */
2420 state->noise_cal.cpOpt = 1;
2421 state->noise_cal.cpNexpOfs = 0;
2422 state->noise_cal.tdCal2k = -21;
2423 state->noise_cal.tdCal8k = -24;
2425 state->m_EcOcRegOcModeLop = (u16)(ulEcOcRegOcModeLop);
2427 state->chip_adr = (state->config.demod_address<<1)|1;
2428 switch( ulHiI2cPatch )
2430 case 1 : state->m_HiI2cPatch = DRXD_HiI2cPatch_1; break;
2431 case 3 : state->m_HiI2cPatch = DRXD_HiI2cPatch_3; break;
2432 default:
2433 state->m_HiI2cPatch = NULL;
2436 /* modify tuner and clock attributes */
2437 state->intermediate_freq = (u16)(IntermediateFrequency/1000);
2438 /* expected system clock frequency in kHz */
2439 state->expected_sys_clock_freq = 48000;
2440 /* real system clock frequency in kHz */
2441 state->sys_clock_freq = 48000;
2442 state->osc_clock_freq = (u16) ulClock;
2443 state->osc_clock_deviation = 0;
2444 state->cscd_state = CSCD_INIT;
2445 state->drxd_state = DRXD_UNINITIALIZED;
2447 state->PGA=0;
2448 state->type_A=0;
2449 state->tuner_mirrors=0;
2451 /* modify MPEG output attributes */
2452 state->insert_rs_byte = state->config.insert_rs_byte;
2453 state->enable_parallel = (ulSerialMode != 1);
2455 /* Timing div, 250ns/Psys */
2456 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2458 state->hi_cfg_timing_div = (u16)((state->sys_clock_freq/1000)*
2459 ulHiI2cDelay)/1000 ;
2460 /* Bridge delay, uses oscilator clock */
2461 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2462 state->hi_cfg_bridge_delay = (u16)((state->osc_clock_freq/1000) *
2463 ulHiI2cBridgeDelay)/1000 ;
2465 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
2466 /* state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO; */
2467 state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
2468 return 0;
2471 int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
2473 int status=0;
2474 u32 driverVersion;
2476 if (state->init_done)
2477 return 0;
2479 CDRXD(state, state->config.IF ? state->config.IF : 36000000);
2481 do {
2482 state->operation_mode = OM_Default;
2484 CHK_ERROR( SetDeviceTypeId(state) );
2486 /* Apply I2c address patch to B1 */
2487 if( !state->type_A && state->m_HiI2cPatch != NULL )
2488 CHK_ERROR(WriteTable(state, state->m_HiI2cPatch));
2490 if (state->type_A) {
2491 /* HI firmware patch for UIO readout,
2492 avoid clearing of result register */
2493 CHK_ERROR(Write16(state, 0x43012D, 0x047f, 0));
2496 CHK_ERROR( HI_ResetCommand(state));
2498 CHK_ERROR(StopAllProcessors(state));
2499 CHK_ERROR(InitCC(state));
2501 state->osc_clock_deviation = 0;
2503 if (state->config.osc_deviation)
2504 state->osc_clock_deviation =
2505 state->config.osc_deviation(state->priv,
2506 0, 0);
2508 /* Handle clock deviation */
2509 s32 devB;
2510 s32 devA = (s32)(state->osc_clock_deviation) *
2511 (s32)(state->expected_sys_clock_freq);
2512 /* deviation in kHz */
2513 s32 deviation = ( devA /(1000000L));
2514 /* rounding, signed */
2515 if ( devA > 0 )
2516 devB=(2);
2517 else
2518 devB=(-2);
2519 if ( (devB*(devA%1000000L)>1000000L ) )
2521 /* add +1 or -1 */
2522 deviation += (devB/2);
2525 state->sys_clock_freq=(u16)((state->
2526 expected_sys_clock_freq)+
2527 deviation);
2529 CHK_ERROR(InitHI(state));
2530 CHK_ERROR(InitAtomicRead(state));
2532 CHK_ERROR(EnableAndResetMB(state));
2533 if (state->type_A)
2534 CHK_ERROR(ResetCEFR(state));
2536 if (fw) {
2537 CHK_ERROR(DownloadMicrocode(state, fw, fw_size));
2538 } else {
2539 CHK_ERROR(DownloadMicrocode(state, state->microcode,
2540 state->microcode_length));
2543 if (state->PGA) {
2544 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO;
2545 SetCfgPga(state, 0); /* PGA = 0 dB */
2546 } else {
2547 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
2550 state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
2552 CHK_ERROR(InitFE(state));
2553 CHK_ERROR(InitFT(state));
2554 CHK_ERROR(InitCP(state));
2555 CHK_ERROR(InitCE(state));
2556 CHK_ERROR(InitEQ(state));
2557 CHK_ERROR(InitEC(state));
2558 CHK_ERROR(InitSC(state));
2560 CHK_ERROR(SetCfgIfAgc(state, &state->if_agc_cfg));
2561 CHK_ERROR(SetCfgRfAgc(state, &state->rf_agc_cfg));
2563 state->cscd_state = CSCD_INIT;
2564 CHK_ERROR(Write16(state, SC_COMM_EXEC__A,
2565 SC_COMM_EXEC_CTL_STOP, 0));
2566 CHK_ERROR(Write16(state, LC_COMM_EXEC__A,
2567 SC_COMM_EXEC_CTL_STOP, 0 ));
2570 driverVersion = (((VERSION_MAJOR/10) << 4) +
2571 (VERSION_MAJOR%10)) << 24;
2572 driverVersion += (((VERSION_MINOR/10) << 4) +
2573 (VERSION_MINOR%10)) << 16;
2574 driverVersion += ((VERSION_PATCH/1000)<<12) +
2575 ((VERSION_PATCH/100)<<8) +
2576 ((VERSION_PATCH/10 )<< 4) +
2577 (VERSION_PATCH%10 );
2579 CHK_ERROR(Write32(state, SC_RA_RAM_DRIVER_VERSION__AX,
2580 driverVersion,0 ));
2582 CHK_ERROR( StopOC(state) );
2584 state->drxd_state = DRXD_STOPPED;
2585 state->init_done=1;
2586 status=0;
2587 } while (0);
2588 return status;
2591 int DRXD_status(struct drxd_state *state, u32 *pLockStatus)
2593 DRX_GetLockStatus(state, pLockStatus);
2595 /*if (*pLockStatus&DRX_LOCK_MPEG)*/
2596 if (*pLockStatus&DRX_LOCK_FEC) {
2597 ConfigureMPEGOutput(state, 1);
2598 /* Get status again, in case we have MPEG lock now */
2599 /*DRX_GetLockStatus(state, pLockStatus);*/
2602 return 0;
2605 /****************************************************************************/
2606 /****************************************************************************/
2607 /****************************************************************************/
2609 static int drxd_read_signal_strength(struct dvb_frontend *fe,
2610 u16 *strength)
2612 struct drxd_state *state = fe->demodulator_priv;
2613 u32 value;
2614 int res;
2616 res=ReadIFAgc(state, &value);
2617 if (res<0)
2618 *strength=0;
2619 else
2620 *strength=0xffff-(value<<4);
2621 return 0;
2625 static int drxd_read_status(struct dvb_frontend *fe, fe_status_t *status)
2627 struct drxd_state *state = fe->demodulator_priv;
2628 u32 lock;
2630 DRXD_status(state, &lock);
2631 *status=0;
2632 /* No MPEG lock in V255 firmware, bug ? */
2633 #if 1
2634 if (lock&DRX_LOCK_MPEG)
2635 *status|=FE_HAS_LOCK;
2636 #else
2637 if (lock&DRX_LOCK_FEC)
2638 *status|=FE_HAS_LOCK;
2639 #endif
2640 if (lock&DRX_LOCK_FEC)
2641 *status|=FE_HAS_VITERBI|FE_HAS_SYNC;
2642 if (lock&DRX_LOCK_DEMOD)
2643 *status|=FE_HAS_CARRIER|FE_HAS_SIGNAL;
2645 return 0;
2648 static int drxd_init(struct dvb_frontend *fe)
2650 struct drxd_state *state=fe->demodulator_priv;
2651 int err=0;
2653 /* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
2654 return DRXD_init(state, 0, 0);
2656 err=DRXD_init(state, state->fw->data, state->fw->size);
2657 release_firmware(state->fw);
2658 return err;
2661 int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
2663 struct drxd_state *state=fe->demodulator_priv;
2665 if (state->config.disable_i2c_gate_ctrl == 1)
2666 return 0;
2668 return DRX_ConfigureI2CBridge(state, onoff);
2671 static int drxd_get_tune_settings(struct dvb_frontend *fe,
2672 struct dvb_frontend_tune_settings *sets)
2674 sets->min_delay_ms=10000;
2675 sets->max_drift=0;
2676 sets->step_size=0;
2677 return 0;
2680 static int drxd_read_ber(struct dvb_frontend *fe, u32 *ber)
2682 *ber = 0;
2683 return 0;
2686 static int drxd_read_snr(struct dvb_frontend *fe, u16 *snr)
2688 *snr=0;
2689 return 0;
2692 static int drxd_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
2694 *ucblocks=0;
2695 return 0;
2698 static int drxd_sleep(struct dvb_frontend* fe)
2700 struct drxd_state *state=fe->demodulator_priv;
2702 ConfigureMPEGOutput(state, 0);
2703 return 0;
2706 static int drxd_get_frontend(struct dvb_frontend *fe,
2707 struct dvb_frontend_parameters *param)
2709 return 0;
2712 static int drxd_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
2714 return drxd_config_i2c(fe, enable);
2717 static int drxd_set_frontend(struct dvb_frontend *fe,
2718 struct dvb_frontend_parameters *param)
2720 struct drxd_state *state=fe->demodulator_priv;
2721 s32 off=0;
2723 state->param=*param;
2724 DRX_Stop(state);
2726 if (fe->ops.tuner_ops.set_params) {
2727 fe->ops.tuner_ops.set_params(fe, param);
2728 if (fe->ops.i2c_gate_ctrl)
2729 fe->ops.i2c_gate_ctrl(fe, 0);
2732 /* FIXME: move PLL drivers */
2733 if (state->config.pll_set &&
2734 state->config.pll_set(state->priv, param,
2735 state->config.pll_address,
2736 state->config.demoda_address,
2737 &off)<0) {
2738 printk("Error in pll_set\n");
2739 return -1;
2742 msleep(200);
2744 return DRX_Start(state, off);
2748 static void drxd_release(struct dvb_frontend *fe)
2750 struct drxd_state *state = fe->demodulator_priv;
2752 kfree(state);
2755 static struct dvb_frontend_ops drxd_ops = {
2757 .info = {
2758 .name = "Micronas DRXD DVB-T",
2759 .type = FE_OFDM,
2760 .frequency_min = 47125000,
2761 .frequency_max = 855250000,
2762 .frequency_stepsize = 166667,
2763 .frequency_tolerance = 0,
2764 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2765 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2766 FE_CAN_FEC_AUTO |
2767 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2768 FE_CAN_QAM_AUTO |
2769 FE_CAN_TRANSMISSION_MODE_AUTO |
2770 FE_CAN_GUARD_INTERVAL_AUTO |
2771 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
2772 FE_CAN_MUTE_TS
2775 .release = drxd_release,
2776 .init = drxd_init,
2777 .sleep = drxd_sleep,
2778 .i2c_gate_ctrl = drxd_i2c_gate_ctrl,
2780 .set_frontend = drxd_set_frontend,
2781 .get_frontend = drxd_get_frontend,
2782 .get_tune_settings = drxd_get_tune_settings,
2784 .read_status = drxd_read_status,
2785 .read_ber = drxd_read_ber,
2786 .read_signal_strength = drxd_read_signal_strength,
2787 .read_snr = drxd_read_snr,
2788 .read_ucblocks = drxd_read_ucblocks,
2791 struct dvb_frontend *drxd_attach(const struct drxd_config *config,
2792 void *priv, struct i2c_adapter *i2c,
2793 struct device *dev)
2795 struct drxd_state *state = NULL;
2797 state=kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
2798 if (!state)
2799 return NULL;
2800 memset(state, 0, sizeof(*state));
2802 memcpy(&state->ops, &drxd_ops, sizeof(struct dvb_frontend_ops));
2803 state->dev=dev;
2804 state->config=*config;
2805 state->i2c=i2c;
2806 state->priv=priv;
2808 sema_init(&state->mutex, 1);
2810 if (Read16(state, 0, 0, 0)<0)
2811 goto error;
2813 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
2814 state->frontend.ops=&state->ops;
2815 #else
2816 memcpy(&state->frontend.ops, &drxd_ops,
2817 sizeof(struct dvb_frontend_ops));
2818 #endif
2819 state->frontend.demodulator_priv=state;
2820 ConfigureMPEGOutput(state, 0);
2821 return &state->frontend;
2823 error:
2824 printk("drxd: not found\n");
2825 kfree(state);
2826 return NULL;
2829 MODULE_DESCRIPTION("DRXD driver");
2830 MODULE_AUTHOR("Micronas");
2831 MODULE_LICENSE("GPL");
2833 EXPORT_SYMBOL(drxd_attach);
2834 EXPORT_SYMBOL(drxd_config_i2c);