brintos

brintos / linux-shallow public Read only

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