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